[GPU] Clamp scissor to surface_pitch
This commit is contained in:
parent
56d802c323
commit
e7cd2ffffa
|
@ -121,9 +121,9 @@ bool IsRasterizationPotentiallyDone(const RegisterFile& regs,
|
||||||
edram_mode != xenos::ModeControl::kDepth) {
|
edram_mode != xenos::ModeControl::kDepth) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto sq_program_cntl = regs.Get<reg::SQ_PROGRAM_CNTL>();
|
if (regs.Get<reg::SQ_PROGRAM_CNTL>().vs_export_mode ==
|
||||||
if (sq_program_cntl.vs_export_mode ==
|
xenos::VertexShaderExportMode::kMultipass ||
|
||||||
xenos::VertexShaderExportMode::kMultipass) {
|
!regs.Get<reg::RB_SURFACE_INFO>().surface_pitch) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (primitive_polygonal) {
|
if (primitive_polygonal) {
|
||||||
|
@ -390,6 +390,20 @@ void GetScissor(const RegisterFile& regs, Scissor& scissor_out) {
|
||||||
br_y = uint32_t(std::max(
|
br_y = uint32_t(std::max(
|
||||||
int32_t(br_y) + pa_sc_window_offset.window_y_offset, int32_t(0)));
|
int32_t(br_y) + pa_sc_window_offset.window_y_offset, int32_t(0)));
|
||||||
}
|
}
|
||||||
|
// Clamp the horizontal scissor to surface_pitch for safety, in case that's
|
||||||
|
// not done by the guest for some reason (it's not when doing draws completely
|
||||||
|
// without a viewport, for instance), to prevent overflow - this is important
|
||||||
|
// for host implementations, both based on target-indepedent rasterization
|
||||||
|
// without render target width at all (pixel shader interlocks-based custom RB
|
||||||
|
// implementations) and using conventional render targets, but padded to EDRAM
|
||||||
|
// tiles.
|
||||||
|
uint32_t surface_pitch = regs.Get<reg::RB_SURFACE_INFO>().surface_pitch;
|
||||||
|
tl_x = std::min(tl_x, surface_pitch);
|
||||||
|
br_x = std::min(br_x, surface_pitch);
|
||||||
|
// Ensure the rectangle is non-negative, by collapsing it into a 0-sized one
|
||||||
|
// (not by reordering the bounds preserving the width / height, which would
|
||||||
|
// reveal samples not meant to be covered, unless TL > BR does that on a real
|
||||||
|
// console, but no evidence of such has ever been seen).
|
||||||
br_x = std::max(br_x, tl_x);
|
br_x = std::max(br_x, tl_x);
|
||||||
br_y = std::max(br_y, tl_y);
|
br_y = std::max(br_y, tl_y);
|
||||||
scissor_out.left = tl_x;
|
scissor_out.left = tl_x;
|
||||||
|
|
|
@ -37,7 +37,10 @@ int32_t FloatToD3D11Fixed16p8(float f32);
|
||||||
// Whether with the current state, any samples to rasterize (for any reason, not
|
// Whether with the current state, any samples to rasterize (for any reason, not
|
||||||
// only to write something to a render target, but also to do sample counting or
|
// only to write something to a render target, but also to do sample counting or
|
||||||
// pixel shader memexport) can be generated. Finally dropping draw calls can
|
// pixel shader memexport) can be generated. Finally dropping draw calls can
|
||||||
// only be done if the vertex shader doesn't memexport.
|
// only be done if the vertex shader doesn't memexport. Checks mostly special
|
||||||
|
// cases (for both the guest and usual host implementations), not everything
|
||||||
|
// like whether viewport / scissor are empty (until this truly matters in any
|
||||||
|
// game, of course).
|
||||||
bool IsRasterizationPotentiallyDone(const RegisterFile& regs,
|
bool IsRasterizationPotentiallyDone(const RegisterFile& regs,
|
||||||
bool primitive_polygonal);
|
bool primitive_polygonal);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue