[GPU] Scissor in draw_util

This commit is contained in:
Triang3l 2020-11-15 16:34:14 +03:00
parent 171c97c929
commit 56a07c1773
3 changed files with 50 additions and 27 deletions

View File

@ -21,6 +21,7 @@
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
#include "xenia/gpu/d3d12/d3d12_graphics_system.h"
#include "xenia/gpu/d3d12/d3d12_shader.h"
#include "xenia/gpu/draw_util.h"
#include "xenia/gpu/gpu_flags.h"
#include "xenia/gpu/xenos.h"
#include "xenia/ui/d3d12/d3d12_util.h"
@ -2846,34 +2847,20 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(bool primitive_two_faced) {
}
// Scissor.
auto pa_sc_window_scissor_tl = regs.Get<reg::PA_SC_WINDOW_SCISSOR_TL>();
auto pa_sc_window_scissor_br = regs.Get<reg::PA_SC_WINDOW_SCISSOR_BR>();
D3D12_RECT scissor;
scissor.left = pa_sc_window_scissor_tl.tl_x;
scissor.top = pa_sc_window_scissor_tl.tl_y;
scissor.right = pa_sc_window_scissor_br.br_x;
scissor.bottom = pa_sc_window_scissor_br.br_y;
if (!pa_sc_window_scissor_tl.window_offset_disable) {
scissor.left = std::max(
LONG(scissor.left + pa_sc_window_offset.window_x_offset), LONG(0));
scissor.top = std::max(
LONG(scissor.top + pa_sc_window_offset.window_y_offset), LONG(0));
scissor.right = std::max(
LONG(scissor.right + pa_sc_window_offset.window_x_offset), LONG(0));
scissor.bottom = std::max(
LONG(scissor.bottom + pa_sc_window_offset.window_y_offset), LONG(0));
}
scissor.left *= pixel_size_x;
scissor.top *= pixel_size_y;
scissor.right *= pixel_size_x;
scissor.bottom *= pixel_size_y;
ff_scissor_update_needed_ |= ff_scissor_.left != scissor.left;
ff_scissor_update_needed_ |= ff_scissor_.top != scissor.top;
ff_scissor_update_needed_ |= ff_scissor_.right != scissor.right;
ff_scissor_update_needed_ |= ff_scissor_.bottom != scissor.bottom;
draw_util::Scissor scissor;
draw_util::GetScissor(regs, scissor);
D3D12_RECT scissor_rect;
scissor_rect.left = LONG(scissor.left * pixel_size_x);
scissor_rect.top = LONG(scissor.top * pixel_size_y);
scissor_rect.right = LONG((scissor.left + scissor.width) * pixel_size_x);
scissor_rect.bottom = LONG((scissor.top + scissor.height) * pixel_size_y);
ff_scissor_update_needed_ |= ff_scissor_.left != scissor_rect.left;
ff_scissor_update_needed_ |= ff_scissor_.top != scissor_rect.top;
ff_scissor_update_needed_ |= ff_scissor_.right != scissor_rect.right;
ff_scissor_update_needed_ |= ff_scissor_.bottom != scissor_rect.bottom;
if (ff_scissor_update_needed_) {
ff_scissor_ = scissor;
deferred_command_list_.RSSetScissorRect(scissor);
ff_scissor_ = scissor_rect;
deferred_command_list_.RSSetScissorRect(scissor_rect);
ff_scissor_update_needed_ = false;
}

View File

@ -111,6 +111,34 @@ int32_t FloatToD3D11Fixed16p8(float f32) {
return result.s;
}
void GetScissor(const RegisterFile& regs, Scissor& scissor_out) {
// FIXME(Triang3l): Screen scissor isn't applied here, but it seems to be
// unused on Xbox 360 Direct3D 9.
auto pa_sc_window_scissor_tl = regs.Get<reg::PA_SC_WINDOW_SCISSOR_TL>();
auto pa_sc_window_scissor_br = regs.Get<reg::PA_SC_WINDOW_SCISSOR_BR>();
uint32_t tl_x = pa_sc_window_scissor_tl.tl_x;
uint32_t tl_y = pa_sc_window_scissor_tl.tl_y;
uint32_t br_x = pa_sc_window_scissor_br.br_x;
uint32_t br_y = pa_sc_window_scissor_br.br_y;
if (!pa_sc_window_scissor_tl.window_offset_disable) {
auto pa_sc_window_offset = regs.Get<reg::PA_SC_WINDOW_OFFSET>();
tl_x = uint32_t(std::max(
int32_t(tl_x) + pa_sc_window_offset.window_x_offset, int32_t(0)));
tl_y = uint32_t(std::max(
int32_t(tl_y) + pa_sc_window_offset.window_y_offset, int32_t(0)));
br_x = uint32_t(std::max(
int32_t(br_x) + pa_sc_window_offset.window_x_offset, int32_t(0)));
br_y = uint32_t(std::max(
int32_t(br_y) + pa_sc_window_offset.window_y_offset, int32_t(0)));
}
br_x = std::max(br_x, tl_x);
br_y = std::max(br_y, tl_y);
scissor_out.left = tl_x;
scissor_out.top = tl_y;
scissor_out.width = br_x - tl_x;
scissor_out.height = br_y - tl_y;
}
xenos::CopySampleSelect SanitizeCopySampleSelect(
xenos::CopySampleSelect copy_sample_select, xenos::MsaaSamples msaa_samples,
bool is_depth) {

View File

@ -33,6 +33,14 @@ namespace draw_util {
// for use with the top-left rasterization rule later.
int32_t FloatToD3D11Fixed16p8(float f32);
struct Scissor {
uint32_t left;
uint32_t top;
uint32_t width;
uint32_t height;
};
void GetScissor(const RegisterFile& regs, Scissor& scissor_out);
// To avoid passing values that the shader won't understand (even though
// Direct3D 9 shouldn't pass them anyway).
xenos::CopySampleSelect SanitizeCopySampleSelect(