[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) {
|
||||
return false;
|
||||
}
|
||||
auto sq_program_cntl = regs.Get<reg::SQ_PROGRAM_CNTL>();
|
||||
if (sq_program_cntl.vs_export_mode ==
|
||||
xenos::VertexShaderExportMode::kMultipass) {
|
||||
if (regs.Get<reg::SQ_PROGRAM_CNTL>().vs_export_mode ==
|
||||
xenos::VertexShaderExportMode::kMultipass ||
|
||||
!regs.Get<reg::RB_SURFACE_INFO>().surface_pitch) {
|
||||
return false;
|
||||
}
|
||||
if (primitive_polygonal) {
|
||||
|
@ -390,6 +390,20 @@ void GetScissor(const RegisterFile& regs, Scissor& scissor_out) {
|
|||
br_y = uint32_t(std::max(
|
||||
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_y = std::max(br_y, tl_y);
|
||||
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
|
||||
// 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
|
||||
// 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 primitive_polygonal);
|
||||
|
||||
|
|
Loading…
Reference in New Issue