diff options
-rw-r--r-- | src/amd/vulkan/radv_cmd_buffer.c | 6 | ||||
-rw-r--r-- | src/amd/vulkan/radv_private.h | 3 | ||||
-rw-r--r-- | src/amd/vulkan/si_cmd_buffer.c | 94 |
3 files changed, 90 insertions, 13 deletions
diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 09ba7cf4e18..e50245251fb 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -750,7 +750,9 @@ radv_emit_scissor(struct radv_cmd_buffer *cmd_buffer) { uint32_t count = cmd_buffer->state.dynamic.scissor.count; si_write_scissors(cmd_buffer->cs, 0, count, - cmd_buffer->state.dynamic.scissor.scissors); + cmd_buffer->state.dynamic.scissor.scissors, + cmd_buffer->state.dynamic.viewport.viewports, + cmd_buffer->state.emitted_pipeline->graphics.can_use_guardband); radeon_set_context_reg(cmd_buffer->cs, R_028A48_PA_SC_MODE_CNTL_0, cmd_buffer->state.pipeline->graphics.ms.pa_sc_mode_cntl_0 | S_028A48_VPORT_SCISSOR_ENABLE(count ? 1 : 0)); } @@ -1281,7 +1283,7 @@ radv_cmd_buffer_flush_state(struct radv_cmd_buffer *cmd_buffer, if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_DYNAMIC_VIEWPORT)) radv_emit_viewport(cmd_buffer); - if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_DYNAMIC_SCISSOR)) + if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_DYNAMIC_SCISSOR | RADV_CMD_DIRTY_DYNAMIC_VIEWPORT)) radv_emit_scissor(cmd_buffer); ia_multi_vgt_param = si_get_ia_multi_vgt_param(cmd_buffer, instanced_draw, indirect_draw, draw_vertex_count); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 410e63ba413..e8f14dcfe02 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -758,7 +758,8 @@ void cik_create_gfx_config(struct radv_device *device); void si_write_viewport(struct radeon_winsys_cs *cs, int first_vp, int count, const VkViewport *viewports); void si_write_scissors(struct radeon_winsys_cs *cs, int first, - int count, const VkRect2D *scissors); + int count, const VkRect2D *scissors, + const VkViewport *viewports, bool can_use_guardband); uint32_t si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_draw, bool indirect_draw, uint32_t draw_vertex_count); diff --git a/src/amd/vulkan/si_cmd_buffer.c b/src/amd/vulkan/si_cmd_buffer.c index 357b5172cbe..dbcd8e87a7c 100644 --- a/src/amd/vulkan/si_cmd_buffer.c +++ b/src/amd/vulkan/si_cmd_buffer.c @@ -361,11 +361,6 @@ si_emit_config(struct radv_physical_device *physical_device, radeon_set_context_reg(cs, R_028234_PA_SU_HARDWARE_SCREEN_OFFSET, 0); radeon_set_context_reg(cs, R_028820_PA_CL_NANINF_CNTL, 0); - radeon_set_context_reg(cs, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, fui(1.0)); - radeon_set_context_reg(cs, R_028BEC_PA_CL_GB_VERT_DISC_ADJ, fui(1.0)); - radeon_set_context_reg(cs, R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ, fui(1.0)); - radeon_set_context_reg(cs, R_028BF4_PA_CL_GB_HORZ_DISC_ADJ, fui(1.0)); - radeon_set_context_reg(cs, R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0x0); radeon_set_context_reg(cs, R_028AC4_DB_SRESULTS_COMPARE_STATE1, 0x0); radeon_set_context_reg(cs, R_028AC8_DB_PRELOAD_CONTROL, 0x0); @@ -500,6 +495,22 @@ get_viewport_xform(const VkViewport *viewport, translate[2] = n; } +static void +get_viewport_xform_scissor(const VkRect2D *scissor, + float scale[2], float translate[2]) +{ + float x = scissor->offset.x; + float y = scissor->offset.y; + float half_width = 0.5f * scissor->extent.width; + float half_height = 0.5f * scissor->extent.height; + + scale[0] = half_width; + translate[0] = half_width + x; + scale[1] = half_height; + translate[1] = half_height + y; + +} + void si_write_viewport(struct radeon_winsys_cs *cs, int first_vp, int count, const VkViewport *viewports) @@ -533,21 +544,84 @@ si_write_viewport(struct radeon_winsys_cs *cs, int first_vp, } } +static VkRect2D si_scissor_from_viewport(const VkViewport *viewport) +{ + float scale[3], translate[3]; + VkRect2D rect; + + get_viewport_xform(viewport, scale, translate); + + rect.offset.x = translate[0] - abs(scale[0]); + rect.offset.y = translate[1] - abs(scale[1]); + rect.extent.width = ceilf(translate[0] + abs(scale[0])) - rect.offset.x; + rect.extent.height = ceilf(translate[1] + abs(scale[1])) - rect.offset.y; + + return rect; +} + +static VkRect2D si_intersect_scissor(const VkRect2D *a, const VkRect2D *b) { + VkRect2D ret; + ret.offset.x = MAX2(a->offset.x, b->offset.x); + ret.offset.y = MAX2(a->offset.y, b->offset.y); + ret.extent.width = MIN2(a->offset.x + a->extent.width, + b->offset.x + b->extent.width) - ret.offset.x; + ret.extent.height = MIN2(a->offset.y + a->extent.height, + b->offset.y + b->extent.height) - ret.offset.y; + return ret; +} + +static VkRect2D si_union_scissor(const VkRect2D *a, const VkRect2D *b) { + VkRect2D ret; + ret.offset.x = MIN2(a->offset.x, b->offset.x); + ret.offset.y = MIN2(a->offset.y, b->offset.y); + ret.extent.width = MAX2(a->offset.x + a->extent.width, + b->offset.x + b->extent.width) - ret.offset.x; + ret.extent.height = MAX2(a->offset.y + a->extent.height, + b->offset.y + b->extent.height) - ret.offset.y; + return ret; +} + + void si_write_scissors(struct radeon_winsys_cs *cs, int first, - int count, const VkRect2D *scissors) + int count, const VkRect2D *scissors, + const VkViewport *viewports, bool can_use_guardband) { int i; + VkRect2D merged; + float scale[2], translate[2], guardband_x = 1.0, guardband_y = 1.0; + const float max_range = 32767.0f; assert(count); radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL + first * 4 * 2, count * 2); for (i = 0; i < count; i++) { - radeon_emit(cs, S_028250_TL_X(scissors[i].offset.x) | - S_028250_TL_Y(scissors[i].offset.y) | + VkRect2D viewport_scissor = si_scissor_from_viewport(viewports + i); + VkRect2D scissor = si_intersect_scissor(&scissors[i], &viewport_scissor); + + if (i) + merged = si_union_scissor(&merged, &scissor); + else + merged = scissor; + + radeon_emit(cs, S_028250_TL_X(scissor.offset.x) | + S_028250_TL_Y(scissor.offset.y) | S_028250_WINDOW_OFFSET_DISABLE(1)); - radeon_emit(cs, S_028254_BR_X(scissors[i].offset.x + scissors[i].extent.width) | - S_028254_BR_Y(scissors[i].offset.y + scissors[i].extent.height)); + radeon_emit(cs, S_028254_BR_X(scissor.offset.x + scissor.extent.width) | + S_028254_BR_Y(scissor.offset.y + scissor.extent.height)); } + + get_viewport_xform_scissor(&merged, scale, translate); + + if (can_use_guardband) { + guardband_x = (max_range - abs(translate[0])) / scale[0]; + guardband_y = (max_range - abs(translate[1])) / scale[1]; + } + + radeon_set_context_reg_seq(cs, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 4); + radeon_emit(cs, fui(guardband_x)); + radeon_emit(cs, fui(1.0)); + radeon_emit(cs, fui(guardband_y)); + radeon_emit(cs, fui(1.0)); } static inline unsigned |