Skip to content

Commit 7d96c9d

Browse files
authored
Use correct scissor rects (shadps4-emu#1146)
* WIP * Proper combination of scissors * convert static functions to lambdas
1 parent 3dea1a9 commit 7d96c9d

File tree

2 files changed

+89
-18
lines changed

2 files changed

+89
-18
lines changed

src/video_core/amdgpu/liverpool.h

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,13 @@ struct Liverpool {
253253
}
254254
};
255255

256+
struct ModeControl {
257+
s32 msaa_enable : 1;
258+
s32 vport_scissor_enable : 1;
259+
s32 line_stripple_enable : 1;
260+
s32 send_unlit_stiles_to_pkr : 1;
261+
};
262+
256263
enum class ZOrder : u32 {
257264
LateZ = 0,
258265
EarlyZLateZ = 1,
@@ -559,29 +566,39 @@ struct Liverpool {
559566
s16 top_left_x;
560567
s16 top_left_y;
561568
};
562-
union {
563-
BitField<0, 15, u32> bottom_right_x;
564-
BitField<16, 15, u32> bottom_right_y;
569+
struct {
570+
s16 bottom_right_x;
571+
s16 bottom_right_y;
565572
};
566573

574+
// From AMD spec: 'Negative numbers clamped to 0'
575+
static s16 Clamp(s16 value) {
576+
return std::max(s16(0), value);
577+
}
578+
567579
u32 GetWidth() const {
568-
return static_cast<u32>(bottom_right_x - top_left_x);
580+
return static_cast<u32>(Clamp(bottom_right_x) - Clamp(top_left_x));
569581
}
570582

571583
u32 GetHeight() const {
572-
return static_cast<u32>(bottom_right_y - top_left_y);
584+
return static_cast<u32>(Clamp(bottom_right_y) - Clamp(top_left_y));
573585
}
574586
};
575587

588+
struct WindowOffset {
589+
s32 window_x_offset : 16;
590+
s32 window_y_offset : 16;
591+
};
592+
576593
struct ViewportScissor {
577594
union {
578595
BitField<0, 15, s32> top_left_x;
579-
BitField<15, 15, s32> top_left_y;
580-
BitField<30, 1, s32> window_offset_disable;
596+
BitField<16, 15, s32> top_left_y;
597+
BitField<31, 1, s32> window_offset_disable;
581598
};
582-
union {
583-
BitField<0, 15, s32> bottom_right_x;
584-
BitField<15, 15, s32> bottom_right_y;
599+
struct {
600+
s16 bottom_right_x;
601+
s16 bottom_right_y;
585602
};
586603

587604
u32 GetWidth() const {
@@ -953,10 +970,14 @@ struct Liverpool {
953970
Scissor screen_scissor;
954971
INSERT_PADDING_WORDS(0xA010 - 0xA00C - 2);
955972
DepthBuffer depth_buffer;
956-
INSERT_PADDING_WORDS(0xA08E - 0xA018);
973+
INSERT_PADDING_WORDS(0xA080 - 0xA018);
974+
WindowOffset window_offset;
975+
ViewportScissor window_scissor;
976+
INSERT_PADDING_WORDS(0xA08E - 0xA081 - 2);
957977
ColorBufferMask color_target_mask;
958978
ColorBufferMask color_shader_mask;
959-
INSERT_PADDING_WORDS(0xA094 - 0xA08E - 2);
979+
ViewportScissor generic_scissor;
980+
INSERT_PADDING_WORDS(2);
960981
std::array<ViewportScissor, NumViewports> viewport_scissors;
961982
std::array<ViewportDepth, NumViewports> viewport_depths;
962983
INSERT_PADDING_WORDS(0xA103 - 0xA0D4);
@@ -994,7 +1015,9 @@ struct Liverpool {
9941015
PolygonControl polygon_control;
9951016
ViewportControl viewport_control;
9961017
VsOutputControl vs_output_control;
997-
INSERT_PADDING_WORDS(0xA29E - 0xA207 - 2);
1018+
INSERT_PADDING_WORDS(0xA292 - 0xA207 - 1);
1019+
ModeControl mode_control;
1020+
INSERT_PADDING_WORDS(0xA29D - 0xA292 - 1);
9981021
u32 index_size;
9991022
u32 max_index_size;
10001023
IndexBufferType index_buffer_type;
@@ -1206,8 +1229,11 @@ static_assert(GFX6_3D_REG_INDEX(depth_htile_data_base) == 0xA005);
12061229
static_assert(GFX6_3D_REG_INDEX(screen_scissor) == 0xA00C);
12071230
static_assert(GFX6_3D_REG_INDEX(depth_buffer.z_info) == 0xA010);
12081231
static_assert(GFX6_3D_REG_INDEX(depth_buffer.depth_slice) == 0xA017);
1232+
static_assert(GFX6_3D_REG_INDEX(window_offset) == 0xA080);
1233+
static_assert(GFX6_3D_REG_INDEX(window_scissor) == 0xA081);
12091234
static_assert(GFX6_3D_REG_INDEX(color_target_mask) == 0xA08E);
12101235
static_assert(GFX6_3D_REG_INDEX(color_shader_mask) == 0xA08F);
1236+
static_assert(GFX6_3D_REG_INDEX(generic_scissor) == 0xA090);
12111237
static_assert(GFX6_3D_REG_INDEX(viewport_scissors) == 0xA094);
12121238
static_assert(GFX6_3D_REG_INDEX(primitive_restart_index) == 0xA103);
12131239
static_assert(GFX6_3D_REG_INDEX(stencil_control) == 0xA10B);
@@ -1227,6 +1253,7 @@ static_assert(GFX6_3D_REG_INDEX(color_control) == 0xA202);
12271253
static_assert(GFX6_3D_REG_INDEX(clipper_control) == 0xA204);
12281254
static_assert(GFX6_3D_REG_INDEX(viewport_control) == 0xA206);
12291255
static_assert(GFX6_3D_REG_INDEX(vs_output_control) == 0xA207);
1256+
static_assert(GFX6_3D_REG_INDEX(mode_control) == 0xA292);
12301257
static_assert(GFX6_3D_REG_INDEX(index_size) == 0xA29D);
12311258
static_assert(GFX6_3D_REG_INDEX(index_buffer_type) == 0xA29F);
12321259
static_assert(GFX6_3D_REG_INDEX(enable_primitive_id) == 0xA2A1);

src/video_core/renderer_vulkan/vk_rasterizer.cpp

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,55 @@ void Rasterizer::UpdateViewportScissorState() {
368368
.maxDepth = vp.zscale + vp.zoffset,
369369
});
370370
}
371-
const auto& sc = regs.screen_scissor;
372-
scissors.push_back({
373-
.offset = {sc.top_left_x, sc.top_left_y},
374-
.extent = {sc.GetWidth(), sc.GetHeight()},
375-
});
371+
372+
const bool enable_offset = !regs.window_scissor.window_offset_disable.Value();
373+
Liverpool::Scissor scsr{};
374+
const auto combined_scissor_value_tl = [](s16 scr, s16 win, s16 gen, s16 win_offset) {
375+
return std::max({scr, s16(win + win_offset), s16(gen + win_offset)});
376+
};
377+
378+
scsr.top_left_x = combined_scissor_value_tl(
379+
regs.screen_scissor.top_left_x, s16(regs.window_scissor.top_left_x.Value()),
380+
s16(regs.generic_scissor.top_left_x.Value()),
381+
enable_offset ? regs.window_offset.window_x_offset : 0);
382+
383+
scsr.top_left_y = combined_scissor_value_tl(
384+
regs.screen_scissor.top_left_y, s16(regs.window_scissor.top_left_y.Value()),
385+
s16(regs.generic_scissor.top_left_y.Value()),
386+
enable_offset ? regs.window_offset.window_y_offset : 0);
387+
388+
const auto combined_scissor_value_br = [](s16 scr, s16 win, s16 gen, s16 win_offset) {
389+
return std::min({scr, s16(win + win_offset), s16(gen + win_offset)});
390+
};
391+
392+
scsr.bottom_right_x = combined_scissor_value_br(
393+
regs.screen_scissor.bottom_right_x, regs.window_scissor.bottom_right_x,
394+
regs.generic_scissor.bottom_right_x,
395+
enable_offset ? regs.window_offset.window_x_offset : 0);
396+
397+
scsr.bottom_right_y = combined_scissor_value_br(
398+
regs.screen_scissor.bottom_right_y, regs.window_scissor.bottom_right_y,
399+
regs.generic_scissor.bottom_right_y,
400+
enable_offset ? regs.window_offset.window_y_offset : 0);
401+
402+
for (u32 idx = 0; idx < Liverpool::NumViewports; idx++) {
403+
auto vp_scsr = scsr;
404+
if (regs.mode_control.vport_scissor_enable) {
405+
vp_scsr.top_left_x =
406+
std::max(vp_scsr.top_left_x, s16(regs.viewport_scissors[idx].top_left_x.Value()));
407+
vp_scsr.top_left_y =
408+
std::max(vp_scsr.top_left_y, s16(regs.viewport_scissors[idx].top_left_y.Value()));
409+
vp_scsr.bottom_right_x =
410+
std::min(vp_scsr.bottom_right_x, regs.viewport_scissors[idx].bottom_right_x);
411+
vp_scsr.bottom_right_y =
412+
std::min(vp_scsr.bottom_right_y, regs.viewport_scissors[idx].bottom_right_y);
413+
}
414+
scissors.push_back({
415+
.offset = {vp_scsr.top_left_x, vp_scsr.top_left_y},
416+
.extent = {vp_scsr.GetWidth(), vp_scsr.GetHeight()},
417+
});
418+
}
419+
376420
const auto cmdbuf = scheduler.CommandBuffer();
377421
cmdbuf.setViewport(0, viewports);
378422
cmdbuf.setScissor(0, scissors);

0 commit comments

Comments
 (0)