genX/pipeline: Break emit_vertex_input out into common code
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 26 Jan 2016 18:52:56 +0000 (10:52 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 26 Jan 2016 22:56:37 +0000 (14:56 -0800)
It's mostly the same and contains some non-trivial logic, so it really
should be shared.  Also, we're about to make some modifications here that
we would really like to share.

src/vulkan/gen7_pipeline.c
src/vulkan/gen8_pipeline.c
src/vulkan/genX_pipeline_util.h

index 9b90c6e..679510a 100644 (file)
 #include "genX_pipeline_util.h"
 
 static void
-emit_vertex_input(struct anv_pipeline *pipeline,
-                  const VkPipelineVertexInputStateCreateInfo *info,
-                  const struct anv_graphics_pipeline_create_info *extra)
-{
-   uint32_t elements;
-   if (extra && extra->disable_vs) {
-      /* If the VS is disabled, just assume the user knows what they're
-       * doing and apply the layout blindly.  This can only come from
-       * meta, so this *should* be safe.
-       */
-      elements = 0;
-      for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++)
-         elements |= (1 << info->pVertexAttributeDescriptions[i].location);
-   } else {
-      /* Pull inputs_read out of the VS prog data */
-      uint64_t inputs_read = pipeline->vs_prog_data.inputs_read;
-      assert((inputs_read & ((1 << VERT_ATTRIB_GENERIC0) - 1)) == 0);
-      elements = inputs_read >> VERT_ATTRIB_GENERIC0;
-   }
-
-   uint32_t vb_count = __builtin_popcount(elements);
-
-   if (pipeline->vs_prog_data.uses_vertexid ||
-       pipeline->vs_prog_data.uses_instanceid)
-      vb_count++;
-
-   if (vb_count == 0)
-      return;
-
-   const uint32_t num_dwords = 1 + vb_count * 2;
-
-   uint32_t *p = anv_batch_emitn(&pipeline->batch, num_dwords,
-                                 GEN7_3DSTATE_VERTEX_ELEMENTS);
-   memset(p + 1, 0, (num_dwords - 1) * 4);
-
-   for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) {
-      const VkVertexInputAttributeDescription *desc =
-         &info->pVertexAttributeDescriptions[i];
-      enum isl_format format = anv_get_isl_format(desc->format,
-                                                  VK_IMAGE_ASPECT_COLOR_BIT,
-                                                  VK_IMAGE_TILING_LINEAR);
-
-      assert(desc->binding < 32);
-
-      if ((elements & (1 << desc->location)) == 0)
-         continue; /* Binding unused */
-
-      uint32_t slot = __builtin_popcount(elements & ((1 << desc->location) - 1));
-
-      struct GEN7_VERTEX_ELEMENT_STATE element = {
-         .VertexBufferIndex = desc->binding,
-         .Valid = true,
-         .SourceElementFormat = format,
-         .EdgeFlagEnable = false,
-         .SourceElementOffset = desc->offset,
-         .Component0Control = vertex_element_comp_control(format, 0),
-         .Component1Control = vertex_element_comp_control(format, 1),
-         .Component2Control = vertex_element_comp_control(format, 2),
-         .Component3Control = vertex_element_comp_control(format, 3),
-      };
-      GEN7_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + slot * 2], &element);
-   }
-
-   if (pipeline->vs_prog_data.uses_vertexid ||
-       pipeline->vs_prog_data.uses_instanceid) {
-      struct GEN7_VERTEX_ELEMENT_STATE element = {
-         .Valid = true,
-         /* FIXME: Do we need to provide the base vertex as component 0 here
-          * to support the correct base vertex ID? */
-         .Component0Control = VFCOMP_STORE_0,
-         .Component1Control = VFCOMP_STORE_0,
-         .Component2Control = VFCOMP_STORE_VID,
-         .Component3Control = VFCOMP_STORE_IID
-      };
-      GEN7_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + (vb_count - 1) * 2], &element);
-   }
-}
-
-static void
 gen7_emit_rs_state(struct anv_pipeline *pipeline,
                    const VkPipelineRasterizationStateCreateInfo *info,
                    const struct anv_graphics_pipeline_create_info *extra)
index 314a958..2615639 100644 (file)
 #include "genX_pipeline_util.h"
 
 static void
-emit_vertex_input(struct anv_pipeline *pipeline,
-                  const VkPipelineVertexInputStateCreateInfo *info,
-                  const struct anv_graphics_pipeline_create_info *extra)
-{
-   static_assert(ANV_GEN >= 8, "should be compiling this for gen < 8");
-
-   uint32_t elements;
-   if (extra && extra->disable_vs) {
-      /* If the VS is disabled, just assume the user knows what they're
-       * doing and apply the layout blindly.  This can only come from
-       * meta, so this *should* be safe.
-       */
-      elements = 0;
-      for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++)
-         elements |= (1 << info->pVertexAttributeDescriptions[i].location);
-   } else {
-      /* Pull inputs_read out of the VS prog data */
-      uint64_t inputs_read = pipeline->vs_prog_data.inputs_read;
-      assert((inputs_read & ((1 << VERT_ATTRIB_GENERIC0) - 1)) == 0);
-      elements = inputs_read >> VERT_ATTRIB_GENERIC0;
-   }
-
-   const uint32_t num_dwords = 1 + __builtin_popcount(elements) * 2;
-
-   uint32_t *p;
-   if (elements != 0) {
-      p = anv_batch_emitn(&pipeline->batch, num_dwords,
-                          GENX(3DSTATE_VERTEX_ELEMENTS));
-      memset(p + 1, 0, (num_dwords - 1) * 4);
-   }
-
-   for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) {
-      const VkVertexInputAttributeDescription *desc =
-         &info->pVertexAttributeDescriptions[i];
-      enum isl_format format = anv_get_isl_format(desc->format,
-                                                  VK_IMAGE_ASPECT_COLOR_BIT,
-                                                  VK_IMAGE_TILING_LINEAR);
-
-      assert(desc->binding < 32);
-
-      if ((elements & (1 << desc->location)) == 0)
-         continue; /* Binding unused */
-
-      uint32_t slot = __builtin_popcount(elements & ((1 << desc->location) - 1));
-
-      struct GENX(VERTEX_ELEMENT_STATE) element = {
-         .VertexBufferIndex = desc->binding,
-         .Valid = true,
-         .SourceElementFormat = format,
-         .EdgeFlagEnable = false,
-         .SourceElementOffset = desc->offset,
-         .Component0Control = vertex_element_comp_control(format, 0),
-         .Component1Control = vertex_element_comp_control(format, 1),
-         .Component2Control = vertex_element_comp_control(format, 2),
-         .Component3Control = vertex_element_comp_control(format, 3),
-      };
-      GENX(VERTEX_ELEMENT_STATE_pack)(NULL, &p[1 + slot * 2], &element);
-
-      anv_batch_emit(&pipeline->batch, GENX(3DSTATE_VF_INSTANCING),
-                     .InstancingEnable = pipeline->instancing_enable[desc->binding],
-                     .VertexElementIndex = slot,
-                     /* Vulkan so far doesn't have an instance divisor, so
-                      * this is always 1 (ignored if not instancing). */
-                     .InstanceDataStepRate = 1);
-   }
-
-   const uint32_t id_slot = __builtin_popcount(elements);
-   anv_batch_emit(&pipeline->batch, GENX(3DSTATE_VF_SGVS),
-                  .VertexIDEnable = pipeline->vs_prog_data.uses_vertexid,
-                  .VertexIDComponentNumber = 2,
-                  .VertexIDElementOffset = id_slot,
-                  .InstanceIDEnable = pipeline->vs_prog_data.uses_instanceid,
-                  .InstanceIDComponentNumber = 3,
-                  .InstanceIDElementOffset = id_slot);
-}
-
-static void
 emit_ia_state(struct anv_pipeline *pipeline,
               const VkPipelineInputAssemblyStateCreateInfo *info,
               const struct anv_graphics_pipeline_create_info *extra)
index 08fe6aa..050c335 100644 (file)
@@ -47,6 +47,113 @@ vertex_element_comp_control(enum isl_format format, unsigned comp)
    }
 }
 
+static void
+emit_vertex_input(struct anv_pipeline *pipeline,
+                  const VkPipelineVertexInputStateCreateInfo *info,
+                  const struct anv_graphics_pipeline_create_info *extra)
+{
+   uint32_t elements;
+   if (extra && extra->disable_vs) {
+      /* If the VS is disabled, just assume the user knows what they're
+       * doing and apply the layout blindly.  This can only come from
+       * meta, so this *should* be safe.
+       */
+      elements = 0;
+      for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++)
+         elements |= (1 << info->pVertexAttributeDescriptions[i].location);
+   } else {
+      /* Pull inputs_read out of the VS prog data */
+      uint64_t inputs_read = pipeline->vs_prog_data.inputs_read;
+      assert((inputs_read & ((1 << VERT_ATTRIB_GENERIC0) - 1)) == 0);
+      elements = inputs_read >> VERT_ATTRIB_GENERIC0;
+   }
+
+   uint32_t elem_count = __builtin_popcount(elements);
+
+#if ANV_GEN <= 7
+   /* On Haswell and prior, vertex and instance id are created by using the
+    * ComponentControl fields, so we need an element for any of them.
+    */
+   if (pipeline->vs_prog_data.uses_vertexid ||
+       pipeline->vs_prog_data.uses_instanceid)
+      elem_count++;
+#endif
+
+   uint32_t *p;
+   if (elem_count > 0) {
+      const uint32_t num_dwords = 1 + elem_count * 2;
+      p = anv_batch_emitn(&pipeline->batch, num_dwords,
+                          GENX(3DSTATE_VERTEX_ELEMENTS));
+      memset(p + 1, 0, (num_dwords - 1) * 4);
+   }
+
+   for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) {
+      const VkVertexInputAttributeDescription *desc =
+         &info->pVertexAttributeDescriptions[i];
+      enum isl_format format = anv_get_isl_format(desc->format,
+                                                  VK_IMAGE_ASPECT_COLOR_BIT,
+                                                  VK_IMAGE_TILING_LINEAR);
+
+      assert(desc->binding < 32);
+
+      if ((elements & (1 << desc->location)) == 0)
+         continue; /* Binding unused */
+
+      uint32_t slot = __builtin_popcount(elements & ((1 << desc->location) - 1));
+
+      struct GENX(VERTEX_ELEMENT_STATE) element = {
+         .VertexBufferIndex = desc->binding,
+         .Valid = true,
+         .SourceElementFormat = format,
+         .EdgeFlagEnable = false,
+         .SourceElementOffset = desc->offset,
+         .Component0Control = vertex_element_comp_control(format, 0),
+         .Component1Control = vertex_element_comp_control(format, 1),
+         .Component2Control = vertex_element_comp_control(format, 2),
+         .Component3Control = vertex_element_comp_control(format, 3),
+      };
+      GENX(VERTEX_ELEMENT_STATE_pack)(NULL, &p[1 + slot * 2], &element);
+
+#if ANV_GEN >= 8
+      /* On Broadwell and later, we have a separate VF_INSTANCING packet
+       * that controls instancing.  On Haswell and prior, that's part of
+       * VERTEX_BUFFER_STATE which we emit later.
+       */
+      anv_batch_emit(&pipeline->batch, GENX(3DSTATE_VF_INSTANCING),
+                     .InstancingEnable = pipeline->instancing_enable[desc->binding],
+                     .VertexElementIndex = slot,
+                     /* Vulkan so far doesn't have an instance divisor, so
+                      * this is always 1 (ignored if not instancing). */
+                     .InstanceDataStepRate = 1);
+#endif
+   }
+
+   const uint32_t id_slot = __builtin_popcount(elements);
+#if ANV_GEN >= 8
+   anv_batch_emit(&pipeline->batch, GENX(3DSTATE_VF_SGVS),
+                  .VertexIDEnable = pipeline->vs_prog_data.uses_vertexid,
+                  .VertexIDComponentNumber = 2,
+                  .VertexIDElementOffset = id_slot,
+                  .InstanceIDEnable = pipeline->vs_prog_data.uses_instanceid,
+                  .InstanceIDComponentNumber = 3,
+                  .InstanceIDElementOffset = id_slot);
+#else
+   if (pipeline->vs_prog_data.uses_vertexid ||
+       pipeline->vs_prog_data.uses_instanceid) {
+      struct GEN7_VERTEX_ELEMENT_STATE element = {
+         .Valid = true,
+         /* FIXME: Do we need to provide the base vertex as component 0 here
+          * to support the correct base vertex ID? */
+         .Component0Control = VFCOMP_STORE_0,
+         .Component1Control = VFCOMP_STORE_0,
+         .Component2Control = VFCOMP_STORE_VID,
+         .Component3Control = VFCOMP_STORE_IID
+      };
+      GEN7_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + id_slot * 2], &element);
+   }
+#endif
+}
+
 static const uint32_t vk_to_gen_cullmode[] = {
    [VK_CULL_MODE_NONE]                       = CULLMODE_NONE,
    [VK_CULL_MODE_FRONT_BIT]                  = CULLMODE_FRONT,