mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-02 22:28:45 +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_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 {
|
||||||
|
|
|
@ -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 {
|
|
||||||
for (u32 i = 0; i < Liverpool::NumViewports; i++) {
|
scsr.top_left_y = CombinedScissorValueTL(
|
||||||
const auto& scsrs = regs.viewport_scissors[i];
|
regs.screen_scissor.top_left_y, s16(regs.window_scissor.top_left_y.Value()),
|
||||||
scissors.push_back({
|
s16(regs.generic_scissor.top_left_y.Value()),
|
||||||
.offset = {scsrs.top_left_x, scsrs.top_left_y},
|
enable_offset ? regs.window_offset.window_y_offset : 0);
|
||||||
.extent = {scsrs.GetWidth(), scsrs.GetHeight()},
|
|
||||||
});
|
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();
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue