From db4b914bd5ca2fcb656bc6ff585abc070344a6eb Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 9 May 2025 16:58:02 +0200 Subject: [PATCH] radv: fix emitting dynamic viewports/scissors when the count is static In a scenario where the viewports/scissors are a dynamic state but the count is static (ie. updated when a graphics pipeline is bound), the driver wasn't considering that and it was re-emitting the previous number of viewports/scissors. This fixes rendering issue with Blender. Cc: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13127 Signed-off-by: Samuel Pitoiset Part-of: (cherry picked from commit 9a07ccbc89711274e6c8b74eee6f3420b796d80d) --- .pick_status.json | 2 +- src/amd/vulkan/radv_cmd_buffer.c | 38 +++++++++++++++---------- src/amd/vulkan/radv_cmd_buffer.h | 4 ++- src/amd/vulkan/radv_pipeline_graphics.c | 33 ++++++++++++--------- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index c3e2c27e049..b1d73beae3f 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -174,7 +174,7 @@ "description": "radv: fix emitting dynamic viewports/scissors when the count is static", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 528256c3b2d..5a94b15f24d 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -71,11 +71,6 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy dest->sample_location.count = src->sample_location.count; if (copy_mask & RADV_DYNAMIC_VIEWPORT) { - if (dest->vk.vp.viewport_count != src->vk.vp.viewport_count) { - dest->vk.vp.viewport_count = src->vk.vp.viewport_count; - dest_mask |= RADV_DYNAMIC_VIEWPORT; - } - if (memcmp(&dest->vk.vp.viewports, &src->vk.vp.viewports, src->vk.vp.viewport_count * sizeof(VkViewport))) { typed_memcpy(dest->vk.vp.viewports, src->vk.vp.viewports, src->vk.vp.viewport_count); typed_memcpy(dest->hw_vp.xform, src->hw_vp.xform, src->vk.vp.viewport_count); @@ -83,18 +78,27 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy } } - if (copy_mask & RADV_DYNAMIC_SCISSOR) { - if (dest->vk.vp.scissor_count != src->vk.vp.scissor_count) { - dest->vk.vp.scissor_count = src->vk.vp.scissor_count; - dest_mask |= RADV_DYNAMIC_SCISSOR; + if (copy_mask & RADV_DYNAMIC_VIEWPORT_WITH_COUNT) { + if (dest->vk.vp.viewport_count != src->vk.vp.viewport_count) { + dest->vk.vp.viewport_count = src->vk.vp.viewport_count; + dest_mask |= RADV_DYNAMIC_VIEWPORT; } + } + if (copy_mask & RADV_DYNAMIC_SCISSOR) { if (memcmp(&dest->vk.vp.scissors, &src->vk.vp.scissors, src->vk.vp.scissor_count * sizeof(VkRect2D))) { typed_memcpy(dest->vk.vp.scissors, src->vk.vp.scissors, src->vk.vp.scissor_count); dest_mask |= RADV_DYNAMIC_SCISSOR; } } + if (copy_mask & RADV_DYNAMIC_SCISSOR_WITH_COUNT) { + if (dest->vk.vp.scissor_count != src->vk.vp.scissor_count) { + dest->vk.vp.scissor_count = src->vk.vp.scissor_count; + dest_mask |= RADV_DYNAMIC_SCISSOR; + } + } + if (copy_mask & RADV_DYNAMIC_BLEND_CONSTANTS) { if (memcmp(&dest->vk.cb.blend_constants, &src->vk.cb.blend_constants, sizeof(src->vk.cb.blend_constants))) { typed_memcpy(dest->vk.cb.blend_constants, src->vk.cb.blend_constants, 4); @@ -8034,9 +8038,6 @@ radv_CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint3 assert(firstViewport < MAX_VIEWPORTS); assert(total_count >= 1 && total_count <= MAX_VIEWPORTS); - if (state->dynamic.vk.vp.viewport_count < total_count) - state->dynamic.vk.vp.viewport_count = total_count; - memcpy(state->dynamic.vk.vp.viewports + firstViewport, pViewports, viewportCount * sizeof(*pViewports)); for (unsigned i = 0; i < viewportCount; i++) { radv_get_viewport_xform(&pViewports[i], state->dynamic.hw_vp.xform[i + firstViewport].scale, @@ -8058,9 +8059,6 @@ radv_CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_ assert(firstScissor < MAX_SCISSORS); assert(total_count >= 1 && total_count <= MAX_SCISSORS); - if (state->dynamic.vk.vp.scissor_count < total_count) - state->dynamic.vk.vp.scissor_count = total_count; - memcpy(state->dynamic.vk.vp.scissors + firstScissor, pScissors, scissorCount * sizeof(*pScissors)); state->dirty_dynamic |= RADV_DYNAMIC_SCISSOR; @@ -8233,12 +8231,22 @@ radv_CmdSetPrimitiveTopology(VkCommandBuffer commandBuffer, VkPrimitiveTopology VKAPI_ATTR void VKAPI_CALL radv_CmdSetViewportWithCount(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport *pViewports) { + VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + struct radv_cmd_state *state = &cmd_buffer->state; + + state->dynamic.vk.vp.viewport_count = viewportCount; + radv_CmdSetViewport(commandBuffer, 0, viewportCount, pViewports); } VKAPI_ATTR void VKAPI_CALL radv_CmdSetScissorWithCount(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D *pScissors) { + VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + struct radv_cmd_state *state = &cmd_buffer->state; + + state->dynamic.vk.vp.scissor_count = scissorCount; + radv_CmdSetScissor(commandBuffer, 0, scissorCount, pScissors); } diff --git a/src/amd/vulkan/radv_cmd_buffer.h b/src/amd/vulkan/radv_cmd_buffer.h index 28c6d0bdb55..adc4ca2cb47 100644 --- a/src/amd/vulkan/radv_cmd_buffer.h +++ b/src/amd/vulkan/radv_cmd_buffer.h @@ -77,7 +77,9 @@ enum radv_dynamic_state_bits { RADV_DYNAMIC_COLOR_ATTACHMENT_MAP = 1ull << 51, RADV_DYNAMIC_INPUT_ATTACHMENT_MAP = 1ull << 52, RADV_DYNAMIC_DEPTH_CLAMP_RANGE = 1ull << 53, - RADV_DYNAMIC_ALL = (1ull << 54) - 1, + RADV_DYNAMIC_VIEWPORT_WITH_COUNT = 1ull << 54, + RADV_DYNAMIC_SCISSOR_WITH_COUNT = 1ull << 55, + RADV_DYNAMIC_ALL = (1ull << 56) - 1, }; enum radv_cmd_dirty_bits { diff --git a/src/amd/vulkan/radv_pipeline_graphics.c b/src/amd/vulkan/radv_pipeline_graphics.c index 0d39afba3ce..3fdb9aa4525 100644 --- a/src/amd/vulkan/radv_pipeline_graphics.c +++ b/src/amd/vulkan/radv_pipeline_graphics.c @@ -272,10 +272,8 @@ radv_dynamic_state_mask(VkDynamicState state) { switch (state) { case VK_DYNAMIC_STATE_VIEWPORT: - case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT: return RADV_DYNAMIC_VIEWPORT; case VK_DYNAMIC_STATE_SCISSOR: - case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT: return RADV_DYNAMIC_SCISSOR; case VK_DYNAMIC_STATE_LINE_WIDTH: return RADV_DYNAMIC_LINE_WIDTH; @@ -377,6 +375,10 @@ radv_dynamic_state_mask(VkDynamicState state) return RADV_DYNAMIC_ALPHA_TO_ONE_ENABLE; case VK_DYNAMIC_STATE_DEPTH_CLAMP_RANGE_EXT: return RADV_DYNAMIC_DEPTH_CLAMP_RANGE; + case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT: + return RADV_DYNAMIC_VIEWPORT | RADV_DYNAMIC_VIEWPORT_WITH_COUNT; + case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT: + return RADV_DYNAMIC_SCISSOR | RADV_DYNAMIC_SCISSOR_WITH_COUNT; default: unreachable("Unhandled dynamic state"); } @@ -732,21 +734,24 @@ radv_pipeline_init_dynamic_state(const struct radv_device *device, struct radv_g } /* Viewport. */ - if (needed_states & RADV_DYNAMIC_VIEWPORT) { - dynamic->vk.vp.viewport_count = state->vp->viewport_count; - if (states & RADV_DYNAMIC_VIEWPORT) { - typed_memcpy(dynamic->vk.vp.viewports, state->vp->viewports, state->vp->viewport_count); - for (unsigned i = 0; i < dynamic->vk.vp.viewport_count; i++) - radv_get_viewport_xform(&dynamic->vk.vp.viewports[i], dynamic->hw_vp.xform[i].scale, - dynamic->hw_vp.xform[i].translate); - } + if (states & RADV_DYNAMIC_VIEWPORT) { + typed_memcpy(dynamic->vk.vp.viewports, state->vp->viewports, state->vp->viewport_count); + for (unsigned i = 0; i < state->vp->viewport_count; i++) + radv_get_viewport_xform(&dynamic->vk.vp.viewports[i], dynamic->hw_vp.xform[i].scale, + dynamic->hw_vp.xform[i].translate); } - if (needed_states & RADV_DYNAMIC_SCISSOR) { + if (states & RADV_DYNAMIC_VIEWPORT_WITH_COUNT) { + dynamic->vk.vp.viewport_count = state->vp->viewport_count; + } + + /* Scissor. */ + if (states & RADV_DYNAMIC_SCISSOR) { + typed_memcpy(dynamic->vk.vp.scissors, state->vp->scissors, state->vp->scissor_count); + } + + if (states & RADV_DYNAMIC_SCISSOR_WITH_COUNT) { dynamic->vk.vp.scissor_count = state->vp->scissor_count; - if (states & RADV_DYNAMIC_SCISSOR) { - typed_memcpy(dynamic->vk.vp.scissors, state->vp->scissors, state->vp->scissor_count); - } } if (states & RADV_DYNAMIC_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE) {