vk: Move generic pipeline init to anv_pipeline.c
authorKristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
Fri, 21 Aug 2015 05:53:54 +0000 (22:53 -0700)
committerKristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
Mon, 24 Aug 2015 20:45:41 +0000 (13:45 -0700)
This logic will be shared between multiple gens.

Signed-off-by: Kristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
src/vulkan/anv_pipeline.c
src/vulkan/anv_private.h
src/vulkan/gen8_pipeline.c

index 9a96387795d6d3d3c1588b58f361de8e3e16ec03..02343e489d174429eed9b75656eccdfa7d7ea2cf 100644 (file)
@@ -170,6 +170,111 @@ VkResult anv_DestroyPipeline(
    return VK_SUCCESS;
 }
 
+static const uint32_t vk_to_gen_primitive_type[] = {
+   [VK_PRIMITIVE_TOPOLOGY_POINT_LIST]           = _3DPRIM_POINTLIST,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_LIST]            = _3DPRIM_LINELIST,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP]           = _3DPRIM_LINESTRIP,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST]        = _3DPRIM_TRILIST,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP]       = _3DPRIM_TRISTRIP,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN]         = _3DPRIM_TRIFAN,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ]        = _3DPRIM_LINELIST_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ]       = _3DPRIM_LINESTRIP_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_ADJ]    = _3DPRIM_TRILIST_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_ADJ]   = _3DPRIM_TRISTRIP_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_PATCH]                = _3DPRIM_PATCHLIST_1
+};
+
+VkResult
+anv_pipeline_init(struct anv_pipeline *pipeline, struct anv_device *device,
+                  const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                  const struct anv_graphics_pipeline_create_info *extra)
+{
+   pipeline->device = device;
+   pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
+   memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
+   VkResult result;
+
+   result = anv_reloc_list_init(&pipeline->batch_relocs, device);
+   if (result != VK_SUCCESS) {
+      anv_device_free(device, pipeline);
+      return result;
+   }
+   pipeline->batch.next = pipeline->batch.start = pipeline->batch_data;
+   pipeline->batch.end = pipeline->batch.start + sizeof(pipeline->batch_data);
+   pipeline->batch.relocs = &pipeline->batch_relocs;
+
+   anv_state_stream_init(&pipeline->program_stream,
+                         &device->instruction_block_pool);
+
+   for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
+      pipeline->shaders[pCreateInfo->pStages[i].stage] =
+         anv_shader_from_handle(pCreateInfo->pStages[i].shader);
+   }
+
+   if (pCreateInfo->pTessellationState)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
+   if (pCreateInfo->pViewportState)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO");
+   if (pCreateInfo->pMultisampleState)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
+
+   pipeline->use_repclear = extra && extra->use_repclear;
+
+   anv_compiler_run(device->compiler, pipeline);
+
+   const struct brw_wm_prog_data *wm_prog_data = &pipeline->wm_prog_data;
+
+   pipeline->ps_ksp2 = 0;
+   pipeline->ps_grf_start2 = 0;
+   if (pipeline->ps_simd8 != NO_KERNEL) {
+      pipeline->ps_ksp0 = pipeline->ps_simd8;
+      pipeline->ps_grf_start0 = wm_prog_data->base.dispatch_grf_start_reg;
+      if (pipeline->ps_simd16 != NO_KERNEL) {
+         pipeline->ps_ksp2 = pipeline->ps_simd16;
+         pipeline->ps_grf_start2 = wm_prog_data->dispatch_grf_start_reg_16;
+      }
+   } else if (pipeline->ps_simd16 != NO_KERNEL) {
+      pipeline->ps_ksp0 = pipeline->ps_simd16;
+      pipeline->ps_grf_start0 = wm_prog_data->dispatch_grf_start_reg_16;
+   } else {
+      unreachable("no ps shader");
+   }
+
+   const VkPipelineVertexInputStateCreateInfo *vi_info =
+      pCreateInfo->pVertexInputState;
+   pipeline->vb_used = 0;
+   for (uint32_t i = 0; i < vi_info->bindingCount; i++) {
+      const VkVertexInputBindingDescription *desc =
+         &vi_info->pVertexBindingDescriptions[i];
+
+      pipeline->vb_used |= 1 << desc->binding;
+      pipeline->binding_stride[desc->binding] = desc->strideInBytes;
+
+      /* Step rate is programmed per vertex element (attribute), not
+       * binding. Set up a map of which bindings step per instance, for
+       * reference by vertex element setup. */
+      switch (desc->stepRate) {
+      default:
+      case VK_VERTEX_INPUT_STEP_RATE_VERTEX:
+         pipeline->instancing_enable[desc->binding] = false;
+         break;
+      case VK_VERTEX_INPUT_STEP_RATE_INSTANCE:
+         pipeline->instancing_enable[desc->binding] = true;
+         break;
+      }
+   }
+
+   const VkPipelineInputAssemblyStateCreateInfo *ia_info =
+      pCreateInfo->pInputAssemblyState;
+   pipeline->primitive_restart = ia_info->primitiveRestartEnable;
+   pipeline->topology = vk_to_gen_primitive_type[ia_info->topology];
+
+   if (extra && extra->use_rectlist)
+      pipeline->topology = _3DPRIM_RECTLIST;
+
+   return VK_SUCCESS;
+}
+
 VkResult
 anv_graphics_pipeline_create(
    VkDevice _device,
index 4d30bcb68ff3033a6555c0c422ac6070fd327806..2da4c414b4115bc5c66d60177fe202fe4a30d710 100644 (file)
@@ -858,12 +858,19 @@ struct anv_pipeline {
    uint32_t                                     vs_simd8;
    uint32_t                                     ps_simd8;
    uint32_t                                     ps_simd16;
+   uint32_t                                     ps_ksp0;
+   uint32_t                                     ps_ksp2;
+   uint32_t                                     ps_grf_start0;
+   uint32_t                                     ps_grf_start2;
    uint32_t                                     gs_vec4;
    uint32_t                                     gs_vertex_count;
    uint32_t                                     cs_simd;
 
    uint32_t                                     vb_used;
    uint32_t                                     binding_stride[MAX_VBS];
+   bool                                         instancing_enable[MAX_VBS];
+   bool                                         primitive_restart;
+   uint32_t                                     topology;
 
    uint32_t                                     cs_thread_width_max;
    uint32_t                                     cs_right_mask;
@@ -884,12 +891,23 @@ struct anv_graphics_pipeline_create_info {
    bool                                         use_rectlist;
 };
 
+VkResult
+anv_pipeline_init(struct anv_pipeline *pipeline, struct anv_device *device,
+                  const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                  const struct anv_graphics_pipeline_create_info *extra);
+
 VkResult
 anv_graphics_pipeline_create(VkDevice device,
                              const VkGraphicsPipelineCreateInfo *pCreateInfo,
                              const struct anv_graphics_pipeline_create_info *extra,
                              VkPipeline *pPipeline);
 
+VkResult
+gen7_graphics_pipeline_create(VkDevice _device,
+                              const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                              const struct anv_graphics_pipeline_create_info *extra,
+                              VkPipeline *pPipeline);
+
 VkResult
 gen8_graphics_pipeline_create(VkDevice _device,
                               const VkGraphicsPipelineCreateInfo *pCreateInfo,
index a993552cfd3feb653bbd69466ed85255b7eda582..9060b3c744a9dfc61dab259885c798e9a3e5f204 100644 (file)
@@ -35,29 +35,6 @@ emit_vertex_input(struct anv_pipeline *pipeline,
 {
    const uint32_t num_dwords = 1 + info->attributeCount * 2;
    uint32_t *p;
-   bool instancing_enable[32];
-
-   pipeline->vb_used = 0;
-   for (uint32_t i = 0; i < info->bindingCount; i++) {
-      const VkVertexInputBindingDescription *desc =
-         &info->pVertexBindingDescriptions[i];
-
-      pipeline->vb_used |= 1 << desc->binding;
-      pipeline->binding_stride[desc->binding] = desc->strideInBytes;
-
-      /* Step rate is programmed per vertex element (attribute), not
-       * binding. Set up a map of which bindings step per instance, for
-       * reference by vertex element setup. */
-      switch (desc->stepRate) {
-      default:
-      case VK_VERTEX_INPUT_STEP_RATE_VERTEX:
-         instancing_enable[desc->binding] = false;
-         break;
-      case VK_VERTEX_INPUT_STEP_RATE_INSTANCE:
-         instancing_enable[desc->binding] = true;
-         break;
-      }
-   }
 
    p = anv_batch_emitn(&pipeline->batch, num_dwords,
                        GEN8_3DSTATE_VERTEX_ELEMENTS);
@@ -81,7 +58,7 @@ emit_vertex_input(struct anv_pipeline *pipeline,
       GEN8_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + i * 2], &element);
 
       anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_INSTANCING,
-                     .InstancingEnable = instancing_enable[desc->binding],
+                     .InstancingEnable = pipeline->instancing_enable[desc->binding],
                      .VertexElementIndex = i,
                      /* Vulkan so far doesn't have an instance divisor, so
                       * this is always 1 (ignored if not instancing). */
@@ -102,32 +79,14 @@ emit_ia_state(struct anv_pipeline *pipeline,
               const VkPipelineInputAssemblyStateCreateInfo *info,
               const struct anv_graphics_pipeline_create_info *extra)
 {
-   static const uint32_t vk_to_gen_primitive_type[] = {
-      [VK_PRIMITIVE_TOPOLOGY_POINT_LIST]        = _3DPRIM_POINTLIST,
-      [VK_PRIMITIVE_TOPOLOGY_LINE_LIST]         = _3DPRIM_LINELIST,
-      [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP]        = _3DPRIM_LINESTRIP,
-      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST]     = _3DPRIM_TRILIST,
-      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP]    = _3DPRIM_TRISTRIP,
-      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN]      = _3DPRIM_TRIFAN,
-      [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ]     = _3DPRIM_LINELIST_ADJ,
-      [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ]    = _3DPRIM_LINESTRIP_ADJ,
-      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_ADJ] = _3DPRIM_TRILIST_ADJ,
-      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_ADJ] = _3DPRIM_TRISTRIP_ADJ,
-      [VK_PRIMITIVE_TOPOLOGY_PATCH]             = _3DPRIM_PATCHLIST_1
-   };
-   uint32_t topology = vk_to_gen_primitive_type[info->topology];
-
-   if (extra && extra->use_rectlist)
-      topology = _3DPRIM_RECTLIST;
-
    struct GEN8_3DSTATE_VF vf = {
       GEN8_3DSTATE_VF_header,
-      .IndexedDrawCutIndexEnable = info->primitiveRestartEnable,
+      .IndexedDrawCutIndexEnable = pipeline->primitive_restart
    };
    GEN8_3DSTATE_VF_pack(NULL, pipeline->gen8.vf, &vf);
 
    anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_TOPOLOGY,
-                  .PrimitiveTopologyType = topology);
+                  .PrimitiveTopologyType = pipeline->topology);
 }
 
 static void
@@ -356,6 +315,10 @@ gen8_graphics_pipeline_create(
    if (pipeline == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   result = anv_pipeline_init(pipeline, device, pCreateInfo, extra);
+   if (result != VK_SUCCESS)
+      return result;
+
    pipeline->device = device;
    pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
    memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
@@ -564,26 +527,9 @@ gen8_graphics_pipeline_create(
                      .UserClipDistanceCullTestEnableBitmask = 0);
 
    const struct brw_wm_prog_data *wm_prog_data = &pipeline->wm_prog_data;
-   uint32_t ksp0, ksp2, grf_start0, grf_start2;
-
-   ksp2 = 0;
-   grf_start2 = 0;
-   if (pipeline->ps_simd8 != NO_KERNEL) {
-      ksp0 = pipeline->ps_simd8;
-      grf_start0 = wm_prog_data->base.dispatch_grf_start_reg;
-      if (pipeline->ps_simd16 != NO_KERNEL) {
-         ksp2 = pipeline->ps_simd16;
-         grf_start2 = wm_prog_data->dispatch_grf_start_reg_16;
-      }
-   } else if (pipeline->ps_simd16 != NO_KERNEL) {
-      ksp0 = pipeline->ps_simd16;
-      grf_start0 = wm_prog_data->dispatch_grf_start_reg_16;
-   } else {
-      unreachable("no ps shader");
-   }
 
    anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PS,
-                  .KernelStartPointer0 = ksp0,
+                  .KernelStartPointer0 = pipeline->ps_ksp0,
 
                   .SingleProgramFlow = false,
                   .VectorMaskEnable = true,
@@ -600,12 +546,12 @@ gen8_graphics_pipeline_create(
                   ._16PixelDispatchEnable = pipeline->ps_simd16 != NO_KERNEL,
                   ._32PixelDispatchEnable = false,
 
-                  .DispatchGRFStartRegisterForConstantSetupData0 = grf_start0,
+                  .DispatchGRFStartRegisterForConstantSetupData0 = pipeline->ps_grf_start0,
                   .DispatchGRFStartRegisterForConstantSetupData1 = 0,
-                  .DispatchGRFStartRegisterForConstantSetupData2 = grf_start2,
+                  .DispatchGRFStartRegisterForConstantSetupData2 = pipeline->ps_grf_start2,
 
                   .KernelStartPointer1 = 0,
-                  .KernelStartPointer2 = ksp2);
+                  .KernelStartPointer2 = pipeline->ps_ksp2);
 
    bool per_sample_ps = false;
    anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PS_EXTRA,