v3dv/pipeline: start to track dynamic state
authorAlejandro Piñeiro <apinheiro@igalia.com>
Sat, 28 Dec 2019 11:11:48 +0000 (12:11 +0100)
committerMarge Bot <eric+marge@anholt.net>
Tue, 13 Oct 2020 21:21:26 +0000 (21:21 +0000)
Starting with Viewport/Scissor data from VkGraphicsPipelineCreateInfo.

Note that initially this can be somewhat counter-intuitive. What we
are really doing it is filling up the structs with the dynamic stuff
from the pipeline, when such is not defined as dynamic. This is what
anv/radv does, and basically means that we treat both in the same way,
so easier after that.

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

src/broadcom/vulkan/v3dv_cmd_buffer.c
src/broadcom/vulkan/v3dv_pipeline.c
src/broadcom/vulkan/v3dv_private.h

index c44d355..cc3022e 100644 (file)
 #include "broadcom/cle/v3dx_pack.h"
 #include "util/u_pack_color.h"
 
+const struct v3dv_dynamic_state default_dynamic_state = {
+   .viewport = {
+      .count = 0,
+   },
+   .scissor = {
+      .count = 0,
+   },
+};
+
 void
 v3dv_cmd_buffer_add_bo(struct v3dv_cmd_buffer *cmd_buffer, struct v3dv_bo *bo)
 {
index 190c298..a5643c5 100644 (file)
@@ -677,6 +677,76 @@ pipeline_compile_graphics(struct v3dv_pipeline *pipeline,
    return VK_SUCCESS;
 }
 
+static unsigned
+v3dv_dynamic_state_mask(VkDynamicState state)
+{
+   switch(state) {
+   case VK_DYNAMIC_STATE_VIEWPORT:
+      return V3DV_DYNAMIC_VIEWPORT;
+   case VK_DYNAMIC_STATE_SCISSOR:
+      return V3DV_DYNAMIC_SCISSOR;
+   default:
+      unreachable("Unhandled dynamic state");
+   }
+}
+
+static uint32_t
+pipeline_needed_dynamic_state(const VkGraphicsPipelineCreateInfo *pCreateInfo)
+{
+   uint32_t states = V3DV_DYNAMIC_ALL;
+
+   /* FIXME: stub. Based on other values at pCreateInfo, we would need to
+    * remove flags from states
+    */
+
+   return states;
+}
+
+static void
+pipeline_init_dynamic_state(struct v3dv_pipeline *pipeline,
+                            const VkGraphicsPipelineCreateInfo *pCreateInfo)
+{
+   uint32_t needed_states = pipeline_needed_dynamic_state(pCreateInfo);
+   uint32_t states = needed_states;
+
+   pipeline->dynamic_state = default_dynamic_state;
+
+   if (pCreateInfo->pDynamicState) {
+      uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount;
+
+      for (uint32_t s = 0; s < count; s++) {
+         /* Remove all of the states that are marked as dynamic */
+         states &= ~v3dv_dynamic_state_mask(pCreateInfo->pDynamicState->pDynamicStates[s]);
+      }
+   }
+
+   struct v3dv_dynamic_state *dynamic = &pipeline->dynamic_state;
+   /* Note, as this can be counter-intuitive: although we are checking against
+    * _DYNAMIC flags, here we are copying the data from the pipeline that was
+    * not defined as dynamic.
+    */
+   if (needed_states & V3DV_DYNAMIC_VIEWPORT) {
+      assert(pCreateInfo->pViewportState);
+
+      dynamic->viewport.count = pCreateInfo->pViewportState->viewportCount;
+      if (states & V3DV_DYNAMIC_VIEWPORT) {
+         typed_memcpy(dynamic->viewport.viewports,
+                      pCreateInfo->pViewportState->pViewports,
+                      pCreateInfo->pViewportState->viewportCount);
+      }
+   }
+
+   if (needed_states & V3DV_DYNAMIC_SCISSOR) {
+      dynamic->scissor.count = pCreateInfo->pViewportState->scissorCount;
+      if (states & V3DV_DYNAMIC_SCISSOR) {
+         typed_memcpy(dynamic->scissor.scissors,
+                      pCreateInfo->pViewportState->pScissors,
+                      pCreateInfo->pViewportState->scissorCount);
+      }
+   }
+
+   pipeline->dynamic_state.mask = states;
+}
 
 static VkResult
 pipeline_init(struct v3dv_pipeline *pipeline,
@@ -692,6 +762,8 @@ pipeline_init(struct v3dv_pipeline *pipeline,
    assert(pCreateInfo->subpass < render_pass->subpass_count);
    pipeline->subpass = &render_pass->subpasses[pCreateInfo->subpass];
 
+   pipeline_init_dynamic_state(pipeline, pCreateInfo);
+
    result = pipeline_compile_graphics(pipeline, pCreateInfo, alloc);
 
    if (result != VK_SUCCESS) {
index 789eafd..0062965 100644 (file)
@@ -94,6 +94,11 @@ pack_emit_reloc(void *cl, const void *reloc) {}
 #define v3dv_assert(x)
 #endif
 
+#define typed_memcpy(dest, src, count) ({                              \
+                       STATIC_ASSERT(sizeof(*src) == sizeof(*dest)); \
+                       memcpy((dest), (src), (count) * sizeof(*(src))); \
+               })
+
 /* From vulkan spec "If the multiple viewports feature is not enabled,
  * scissorCount must be 1", ditto for viewportCount. For now we don't support
  * that feature.
@@ -428,6 +433,8 @@ struct v3dv_dynamic_state {
    struct v3dv_scissor_state scissor;
 };
 
+extern const struct v3dv_dynamic_state default_dynamic_state;
+
 struct v3dv_cmd_buffer_state {
    const struct v3dv_render_pass *pass;
    const struct v3dv_framebuffer *framebuffer;
@@ -553,6 +560,8 @@ struct v3dv_pipeline {
    struct v3dv_pipeline_stage *vs;
    struct v3dv_pipeline_stage *vs_bin;
    struct v3dv_pipeline_stage *fs;
+
+   struct v3dv_dynamic_state dynamic_state;
 };
 
 uint32_t v3dv_physical_device_api_version(struct v3dv_physical_device *dev);