vulkan: Allow scissors or viewports to be set without counts
authorFaith Ekstrand <faith.ekstrand@collabora.com>
Tue, 31 Jan 2023 02:11:53 +0000 (20:11 -0600)
committerMarge Bot <emma+marge@anholt.net>
Fri, 4 Aug 2023 21:31:57 +0000 (21:31 +0000)
This is unlikely but can happen if you have the following sequence:

 1. vkCmdSetScissors()
 2. No pipeline bind
 3. vkCmdClearImage() which causes a meta save
 4. Meta restore with vk_cmd_set_dynamic_graphics_state()

In that case, we don't have scissor counts but need to restore the
scissors set with `vkCmdSetScissors()` before the meta save.  We can
safely copy all of them, it's just more memory traffic than maybe we'd
like.  Fortunately, this can only happen at the start of a command
buffer and only with a fairly silly sequence of commands.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>

src/vulkan/runtime/vk_graphics_state.c

index 04114fe..1074fce 100644 (file)
@@ -1882,14 +1882,18 @@ vk_dynamic_graphics_state_copy(struct vk_dynamic_graphics_state *dst,
 
    COPY_IF_SET(VP_VIEWPORT_COUNT, vp.viewport_count);
    if (IS_SET_IN_SRC(VP_VIEWPORTS)) {
-      assert(IS_SET_IN_SRC(VP_VIEWPORT_COUNT));
-      COPY_ARRAY(VP_VIEWPORTS, vp.viewports, src->vp.viewport_count);
+      if (likely(IS_SET_IN_SRC(VP_VIEWPORT_COUNT)))
+         COPY_ARRAY(VP_VIEWPORTS, vp.viewports, src->vp.viewport_count);
+      else
+         COPY_ARRAY(VP_VIEWPORTS, vp.viewports, MESA_VK_MAX_VIEWPORTS);
    }
 
    COPY_IF_SET(VP_SCISSOR_COUNT, vp.scissor_count);
    if (IS_SET_IN_SRC(VP_SCISSORS)) {
-      assert(IS_SET_IN_SRC(VP_SCISSOR_COUNT));
-      COPY_ARRAY(VP_SCISSORS, vp.scissors, src->vp.scissor_count);
+      if (likely(IS_SET_IN_SRC(VP_SCISSOR_COUNT)))
+         COPY_ARRAY(VP_SCISSORS, vp.scissors, src->vp.scissor_count);
+      else
+         COPY_ARRAY(VP_SCISSORS, vp.scissors, MESA_VK_MAX_SCISSORS);
    }
 
    COPY_IF_SET(VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE,