mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-28 18:46:06 +00:00
Use correct scissor rects (#1146)
* WIP * Proper combination of scissors * convert static functions to lambdas
This commit is contained in:
parent
3dea1a9f81
commit
7d96c9d634
|
@ -253,6 +253,13 @@ struct Liverpool {
|
|||
}
|
||||
};
|
||||
|
||||
struct ModeControl {
|
||||
s32 msaa_enable : 1;
|
||||
s32 vport_scissor_enable : 1;
|
||||
s32 line_stripple_enable : 1;
|
||||
s32 send_unlit_stiles_to_pkr : 1;
|
||||
};
|
||||
|
||||
enum class ZOrder : u32 {
|
||||
LateZ = 0,
|
||||
EarlyZLateZ = 1,
|
||||
|
@ -559,29 +566,39 @@ 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));
|
||||
}
|
||||
};
|
||||
|
||||
struct WindowOffset {
|
||||
s32 window_x_offset : 16;
|
||||
s32 window_y_offset : 16;
|
||||
};
|
||||
|
||||
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 {
|
||||
|
@ -953,10 +970,14 @@ struct Liverpool {
|
|||
Scissor screen_scissor;
|
||||
INSERT_PADDING_WORDS(0xA010 - 0xA00C - 2);
|
||||
DepthBuffer depth_buffer;
|
||||
INSERT_PADDING_WORDS(0xA08E - 0xA018);
|
||||
INSERT_PADDING_WORDS(0xA080 - 0xA018);
|
||||
WindowOffset window_offset;
|
||||
ViewportScissor window_scissor;
|
||||
INSERT_PADDING_WORDS(0xA08E - 0xA081 - 2);
|
||||
ColorBufferMask color_target_mask;
|
||||
ColorBufferMask color_shader_mask;
|
||||
INSERT_PADDING_WORDS(0xA094 - 0xA08E - 2);
|
||||
ViewportScissor generic_scissor;
|
||||
INSERT_PADDING_WORDS(2);
|
||||
std::array<ViewportScissor, NumViewports> viewport_scissors;
|
||||
std::array<ViewportDepth, NumViewports> viewport_depths;
|
||||
INSERT_PADDING_WORDS(0xA103 - 0xA0D4);
|
||||
|
@ -994,7 +1015,9 @@ struct Liverpool {
|
|||
PolygonControl polygon_control;
|
||||
ViewportControl viewport_control;
|
||||
VsOutputControl vs_output_control;
|
||||
INSERT_PADDING_WORDS(0xA29E - 0xA207 - 2);
|
||||
INSERT_PADDING_WORDS(0xA292 - 0xA207 - 1);
|
||||
ModeControl mode_control;
|
||||
INSERT_PADDING_WORDS(0xA29D - 0xA292 - 1);
|
||||
u32 index_size;
|
||||
u32 max_index_size;
|
||||
IndexBufferType index_buffer_type;
|
||||
|
@ -1206,8 +1229,11 @@ static_assert(GFX6_3D_REG_INDEX(depth_htile_data_base) == 0xA005);
|
|||
static_assert(GFX6_3D_REG_INDEX(screen_scissor) == 0xA00C);
|
||||
static_assert(GFX6_3D_REG_INDEX(depth_buffer.z_info) == 0xA010);
|
||||
static_assert(GFX6_3D_REG_INDEX(depth_buffer.depth_slice) == 0xA017);
|
||||
static_assert(GFX6_3D_REG_INDEX(window_offset) == 0xA080);
|
||||
static_assert(GFX6_3D_REG_INDEX(window_scissor) == 0xA081);
|
||||
static_assert(GFX6_3D_REG_INDEX(color_target_mask) == 0xA08E);
|
||||
static_assert(GFX6_3D_REG_INDEX(color_shader_mask) == 0xA08F);
|
||||
static_assert(GFX6_3D_REG_INDEX(generic_scissor) == 0xA090);
|
||||
static_assert(GFX6_3D_REG_INDEX(viewport_scissors) == 0xA094);
|
||||
static_assert(GFX6_3D_REG_INDEX(primitive_restart_index) == 0xA103);
|
||||
static_assert(GFX6_3D_REG_INDEX(stencil_control) == 0xA10B);
|
||||
|
@ -1227,6 +1253,7 @@ static_assert(GFX6_3D_REG_INDEX(color_control) == 0xA202);
|
|||
static_assert(GFX6_3D_REG_INDEX(clipper_control) == 0xA204);
|
||||
static_assert(GFX6_3D_REG_INDEX(viewport_control) == 0xA206);
|
||||
static_assert(GFX6_3D_REG_INDEX(vs_output_control) == 0xA207);
|
||||
static_assert(GFX6_3D_REG_INDEX(mode_control) == 0xA292);
|
||||
static_assert(GFX6_3D_REG_INDEX(index_size) == 0xA29D);
|
||||
static_assert(GFX6_3D_REG_INDEX(index_buffer_type) == 0xA29F);
|
||||
static_assert(GFX6_3D_REG_INDEX(enable_primitive_id) == 0xA2A1);
|
||||
|
|
|
@ -368,11 +368,55 @@ void Rasterizer::UpdateViewportScissorState() {
|
|||
.maxDepth = vp.zscale + vp.zoffset,
|
||||
});
|
||||
}
|
||||
const auto& sc = regs.screen_scissor;
|
||||
scissors.push_back({
|
||||
.offset = {sc.top_left_x, sc.top_left_y},
|
||||
.extent = {sc.GetWidth(), sc.GetHeight()},
|
||||
});
|
||||
|
||||
const bool enable_offset = !regs.window_scissor.window_offset_disable.Value();
|
||||
Liverpool::Scissor scsr{};
|
||||
const auto combined_scissor_value_tl = [](s16 scr, s16 win, s16 gen, s16 win_offset) {
|
||||
return std::max({scr, s16(win + win_offset), s16(gen + win_offset)});
|
||||
};
|
||||
|
||||
scsr.top_left_x = combined_scissor_value_tl(
|
||||
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 = combined_scissor_value_tl(
|
||||
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);
|
||||
|
||||
const auto combined_scissor_value_br = [](s16 scr, s16 win, s16 gen, s16 win_offset) {
|
||||
return std::min({scr, s16(win + win_offset), s16(gen + win_offset)});
|
||||
};
|
||||
|
||||
scsr.bottom_right_x = combined_scissor_value_br(
|
||||
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 = combined_scissor_value_br(
|
||||
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 idx = 0; idx < Liverpool::NumViewports; idx++) {
|
||||
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[idx].top_left_x.Value()));
|
||||
vp_scsr.top_left_y =
|
||||
std::max(vp_scsr.top_left_y, s16(regs.viewport_scissors[idx].top_left_y.Value()));
|
||||
vp_scsr.bottom_right_x =
|
||||
std::min(vp_scsr.bottom_right_x, regs.viewport_scissors[idx].bottom_right_x);
|
||||
vp_scsr.bottom_right_y =
|
||||
std::min(vp_scsr.bottom_right_y, regs.viewport_scissors[idx].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();
|
||||
cmdbuf.setViewport(0, viewports);
|
||||
cmdbuf.setScissor(0, scissors);
|
||||
|
|
Loading…
Reference in a new issue