mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-22 04:24:44 +00:00
Proper combination of scissors
This commit is contained in:
parent
24a03edfb7
commit
fab50dcb00
2 changed files with 60 additions and 23 deletions
|
@ -566,17 +566,22 @@ struct Liverpool {
|
|||
s16 top_left_x;
|
||||
s16 top_left_y;
|
||||
};
|
||||
union {
|
||||
BitField<0, 15, u32> bottom_right_x;
|
||||
BitField<16, 15, u32> bottom_right_y;
|
||||
struct {
|
||||
s16 bottom_right_x;
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
union {
|
||||
BitField<0, 15, s32> top_left_x;
|
||||
BitField<15, 15, s32> top_left_y;
|
||||
BitField<30, 1, s32> window_offset_disable;
|
||||
BitField<16, 15, s32> top_left_y;
|
||||
BitField<31, 1, s32> window_offset_disable;
|
||||
};
|
||||
union {
|
||||
BitField<0, 15, s32> bottom_right_x;
|
||||
BitField<15, 15, s32> bottom_right_y;
|
||||
struct {
|
||||
s16 bottom_right_x;
|
||||
s16 bottom_right_y;
|
||||
};
|
||||
|
||||
u32 GetWidth() const {
|
||||
|
|
|
@ -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() {
|
||||
auto& regs = liverpool->regs;
|
||||
|
||||
|
@ -369,20 +377,44 @@ void Rasterizer::UpdateViewportScissorState() {
|
|||
});
|
||||
}
|
||||
|
||||
if (!regs.mode_control.vport_scissor_enable) {
|
||||
const auto& sc = regs.screen_scissor;
|
||||
scissors.push_back({
|
||||
.offset = {sc.top_left_x, sc.top_left_y},
|
||||
.extent = {sc.GetWidth(), sc.GetHeight()},
|
||||
});
|
||||
} else {
|
||||
for (u32 i = 0; i < Liverpool::NumViewports; i++) {
|
||||
const auto& scsrs = regs.viewport_scissors[i];
|
||||
scissors.push_back({
|
||||
.offset = {scsrs.top_left_x, scsrs.top_left_y},
|
||||
.extent = {scsrs.GetWidth(), scsrs.GetHeight()},
|
||||
});
|
||||
const bool enable_offset = !regs.window_scissor.window_offset_disable.Value();
|
||||
Liverpool::Scissor scsr;
|
||||
scsr.top_left_x = CombinedScissorValueTL(
|
||||
regs.screen_scissor.top_left_x, s16(regs.window_scissor.top_left_x.Value()),
|
||||
s16(regs.generic_scissor.top_left_x.Value()),
|
||||
enable_offset ? regs.window_offset.window_x_offset : 0);
|
||||
|
||||
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++) {
|
||||
auto vp_scsr = scsr;
|
||||
if (regs.mode_control.vport_scissor_enable) {
|
||||
vp_scsr.top_left_x =
|
||||
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();
|
||||
|
|
Loading…
Add table
Reference in a new issue