Proper combination of scissors

This commit is contained in:
Vladislav Mikhalin 2024-09-29 13:12:15 +03:00
commit fab50dcb00
2 changed files with 60 additions and 23 deletions

View file

@ -566,17 +566,22 @@ struct Liverpool {
s16 top_left_x; s16 top_left_x;
s16 top_left_y; s16 top_left_y;
}; };
union { struct {
BitField<0, 15, u32> bottom_right_x; s16 bottom_right_x;
BitField<16, 15, u32> bottom_right_y; s16 bottom_right_y;
}; };
// From AMD spec: 'Negative numbers clamped to 0'
static s16 Clamp(s16 value) {
return std::max(s16(0), value);
}
u32 GetWidth() const { u32 GetWidth() const {
return static_cast<u32>(bottom_right_x - top_left_x); return static_cast<u32>(Clamp(bottom_right_x) - Clamp(top_left_x));
} }
u32 GetHeight() const { u32 GetHeight() const {
return static_cast<u32>(bottom_right_y - top_left_y); return static_cast<u32>(Clamp(bottom_right_y) - Clamp(top_left_y));
} }
}; };
@ -588,12 +593,12 @@ struct Liverpool {
struct ViewportScissor { struct ViewportScissor {
union { union {
BitField<0, 15, s32> top_left_x; BitField<0, 15, s32> top_left_x;
BitField<15, 15, s32> top_left_y; BitField<16, 15, s32> top_left_y;
BitField<30, 1, s32> window_offset_disable; BitField<31, 1, s32> window_offset_disable;
}; };
union { struct {
BitField<0, 15, s32> bottom_right_x; s16 bottom_right_x;
BitField<15, 15, s32> bottom_right_y; s16 bottom_right_y;
}; };
u32 GetWidth() const { u32 GetWidth() const {

View file

@ -342,6 +342,14 @@ void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) {
} }
} }
static s16 CombinedScissorValueTL(s16 scr, s16 win, s16 gen, s16 win_offset) {
return std::max({scr, s16(win + win_offset), s16(gen + win_offset)});
}
static s16 CombinedScissorValueBR(s16 scr, s16 win, s16 gen, s16 win_offset) {
return std::min({scr, s16(win + win_offset), s16(gen + win_offset)});
}
void Rasterizer::UpdateViewportScissorState() { void Rasterizer::UpdateViewportScissorState() {
auto& regs = liverpool->regs; auto& regs = liverpool->regs;
@ -369,20 +377,44 @@ void Rasterizer::UpdateViewportScissorState() {
}); });
} }
if (!regs.mode_control.vport_scissor_enable) { const bool enable_offset = !regs.window_scissor.window_offset_disable.Value();
const auto& sc = regs.screen_scissor; Liverpool::Scissor scsr;
scissors.push_back({ scsr.top_left_x = CombinedScissorValueTL(
.offset = {sc.top_left_x, sc.top_left_y}, regs.screen_scissor.top_left_x, s16(regs.window_scissor.top_left_x.Value()),
.extent = {sc.GetWidth(), sc.GetHeight()}, s16(regs.generic_scissor.top_left_x.Value()),
}); enable_offset ? regs.window_offset.window_x_offset : 0);
} else {
scsr.top_left_y = CombinedScissorValueTL(
regs.screen_scissor.top_left_y, s16(regs.window_scissor.top_left_y.Value()),
s16(regs.generic_scissor.top_left_y.Value()),
enable_offset ? regs.window_offset.window_y_offset : 0);
scsr.bottom_right_x = CombinedScissorValueBR(
regs.screen_scissor.bottom_right_x, regs.window_scissor.bottom_right_x,
regs.generic_scissor.bottom_right_x,
enable_offset ? regs.window_offset.window_x_offset : 0);
scsr.bottom_right_y = CombinedScissorValueBR(
regs.screen_scissor.bottom_right_y, regs.window_scissor.bottom_right_y,
regs.generic_scissor.bottom_right_y,
enable_offset ? regs.window_offset.window_y_offset : 0);
for (u32 i = 0; i < Liverpool::NumViewports; i++) { for (u32 i = 0; i < Liverpool::NumViewports; i++) {
const auto& scsrs = regs.viewport_scissors[i]; auto vp_scsr = scsr;
scissors.push_back({ if (regs.mode_control.vport_scissor_enable) {
.offset = {scsrs.top_left_x, scsrs.top_left_y}, vp_scsr.top_left_x =
.extent = {scsrs.GetWidth(), scsrs.GetHeight()}, std::max(vp_scsr.top_left_x, s16(regs.viewport_scissors[i].top_left_x.Value()));
}); vp_scsr.top_left_y =
std::max(vp_scsr.top_left_y, s16(regs.viewport_scissors[i].top_left_y.Value()));
vp_scsr.bottom_right_x =
std::min(vp_scsr.bottom_right_x, regs.viewport_scissors[i].bottom_right_x);
vp_scsr.bottom_right_y =
std::min(vp_scsr.bottom_right_y, regs.viewport_scissors[i].bottom_right_y);
} }
scissors.push_back({
.offset = {vp_scsr.top_left_x, vp_scsr.top_left_y},
.extent = {vp_scsr.GetWidth(), vp_scsr.GetHeight()},
});
} }
const auto cmdbuf = scheduler.CommandBuffer(); const auto cmdbuf = scheduler.CommandBuffer();