zink: move primitive-topology stuff into program
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Wed, 19 Jun 2019 10:29:49 +0000 (12:29 +0200)
committerErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 28 Oct 2019 08:51:44 +0000 (08:51 +0000)
The primitive topology is a bit of an odd-ball, as it's the only
truly draw-call specific state that needs to be passed to the program to
get a pipeline.

So let's make this a bit more explict, by passing it separately. This
makes the flow of data a bit easier to wrap your head around.

Acked-by: Jordan Justen <jordan.l.justen@intel.com>
src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_pipeline.c
src/gallium/drivers/zink/zink_pipeline.h
src/gallium/drivers/zink/zink_program.c
src/gallium/drivers/zink/zink_program.h

index 9e6b434..6a9430c 100644 (file)
@@ -721,33 +721,6 @@ allocate_descriptor_set(struct zink_context *ctx, VkDescriptorSetLayout dsl)
    return desc_set;
 }
 
-static VkPrimitiveTopology
-zink_primitive_topology(enum pipe_prim_type mode)
-{
-   switch (mode) {
-   case PIPE_PRIM_POINTS:
-      return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
-
-   case PIPE_PRIM_LINES:
-      return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
-
-   case PIPE_PRIM_LINE_STRIP:
-      return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
-
-   case PIPE_PRIM_TRIANGLES:
-      return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
-
-   case PIPE_PRIM_TRIANGLE_STRIP:
-      return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
-
-   case PIPE_PRIM_TRIANGLE_FAN:
-      return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
-
-   default:
-      unreachable("unexpected enum pipe_prim_type");
-   }
-}
-
 static void
 zink_bind_vertex_buffers(struct zink_cmdbuf *cmdbuf, struct zink_context *ctx)
 {
@@ -847,10 +820,9 @@ zink_draw_vbo(struct pipe_context *pctx,
    if (!gfx_program)
       return;
 
-   ctx->gfx_pipeline_state.primitive_topology = zink_primitive_topology(dinfo->mode);
-
    VkPipeline pipeline = zink_get_gfx_pipeline(screen->dev, gfx_program,
-                                               &ctx->gfx_pipeline_state);
+                                               &ctx->gfx_pipeline_state,
+                                               dinfo->mode);
 
    bool depth_bias = false;
    switch (u_reduced_prim(dinfo->mode)) {
index b06f02a..0dd8918 100644 (file)
@@ -35,7 +35,8 @@
 
 VkPipeline
 zink_create_gfx_pipeline(VkDevice dev, struct zink_gfx_program *prog,
-                         struct zink_gfx_pipeline_state *state)
+                         struct zink_gfx_pipeline_state *state,
+                         VkPrimitiveTopology primitive_topology)
 {
    VkPipelineVertexInputStateCreateInfo vertex_input_state = {};
    vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
@@ -46,7 +47,7 @@ zink_create_gfx_pipeline(VkDevice dev, struct zink_gfx_program *prog,
 
    VkPipelineInputAssemblyStateCreateInfo primitive_state = {};
    primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
-   primitive_state.topology = state->primitive_topology;
+   primitive_state.topology = primitive_topology;
    primitive_state.primitiveRestartEnable = VK_FALSE;
 
    VkPipelineColorBlendStateCreateInfo blend_state = {};
index 9990c50..a2a627d 100644 (file)
@@ -36,7 +36,6 @@ struct zink_render_pass;
 struct zink_vertex_elements_state;
 
 struct zink_gfx_pipeline_state {
-   VkPrimitiveTopology primitive_topology;
    struct zink_render_pass *render_pass;
 
    struct zink_vertex_elements_state *element_state;
@@ -54,6 +53,7 @@ struct zink_gfx_pipeline_state {
 
 VkPipeline
 zink_create_gfx_pipeline(VkDevice dev, struct zink_gfx_program *prog,
-                         struct zink_gfx_pipeline_state *state);
+                         struct zink_gfx_pipeline_state *state,
+                         VkPrimitiveTopology primitive_topology);
 
 #endif
index ed890b9..9398fa2 100644 (file)
@@ -111,10 +111,13 @@ zink_create_gfx_program(VkDevice dev,
    if (!prog)
       goto fail;
 
-   prog->pipelines = _mesa_hash_table_create(NULL, hash_gfx_pipeline_state,
-                                             equals_gfx_pipeline_state);
-   if (!prog->pipelines)
-      goto fail;
+   for (int i = 0; i < ARRAY_SIZE(prog->pipelines); ++i) {
+      prog->pipelines[i] = _mesa_hash_table_create(NULL,
+                                                   hash_gfx_pipeline_state,
+                                                   equals_gfx_pipeline_state);
+      if (!prog->pipelines[i])
+         goto fail;
+   }
 
    for (int i = 0; i < PIPE_SHADER_TYPES - 1; ++i)
       prog->stages[i] = stages[i];
@@ -152,15 +155,46 @@ struct pipeline_cache_entry {
    VkPipeline pipeline;
 };
 
+static VkPrimitiveTopology
+primitive_topology(enum pipe_prim_type mode)
+{
+   switch (mode) {
+   case PIPE_PRIM_POINTS:
+      return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
+
+   case PIPE_PRIM_LINES:
+      return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
+
+   case PIPE_PRIM_LINE_STRIP:
+      return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
+
+   case PIPE_PRIM_TRIANGLES:
+      return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+   case PIPE_PRIM_TRIANGLE_FAN:
+      return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
+
+   default:
+      unreachable("unexpected enum pipe_prim_type");
+   }
+}
+
 VkPipeline
 zink_get_gfx_pipeline(VkDevice dev, struct zink_gfx_program *prog,
-                      struct zink_gfx_pipeline_state *state)
+                      struct zink_gfx_pipeline_state *state,
+                      enum pipe_prim_type mode)
 {
+   assert(mode <= ARRAY_SIZE(prog->pipelines));
+
    /* TODO: use pre-hashed versions to save some time (can re-hash only when
       state changes) */
-   struct hash_entry *entry = _mesa_hash_table_search(prog->pipelines, state);
+   struct hash_entry *entry = _mesa_hash_table_search(prog->pipelines[mode], state);
    if (!entry) {
-      VkPipeline pipeline = zink_create_gfx_pipeline(dev, prog, state);
+      VkPrimitiveTopology vkmode = primitive_topology(mode);
+      VkPipeline pipeline = zink_create_gfx_pipeline(dev, prog, state, vkmode);
       if (pipeline == VK_NULL_HANDLE)
          return VK_NULL_HANDLE;
 
@@ -171,7 +205,7 @@ zink_get_gfx_pipeline(VkDevice dev, struct zink_gfx_program *prog,
       memcpy(&pc_entry->state, state, sizeof(*state));
       pc_entry->pipeline = pipeline;
 
-      entry = _mesa_hash_table_insert(prog->pipelines, &pc_entry->state, pc_entry);
+      entry = _mesa_hash_table_insert(prog->pipelines[mode], &pc_entry->state, pc_entry);
       assert(entry);
    }
 
index 275cafa..d4357fc 100644 (file)
@@ -36,7 +36,7 @@ struct zink_gfx_program {
    struct zink_shader *stages[PIPE_SHADER_TYPES - 1]; // compute stage doesn't belong here
    VkDescriptorSetLayout dsl;
    VkPipelineLayout layout;
-   struct hash_table *pipelines;
+   struct hash_table *pipelines[PIPE_PRIM_TRIANGLE_FAN + 1];
 };
 
 struct zink_gfx_program *
@@ -48,6 +48,7 @@ zink_destroy_gfx_program(VkDevice dev, struct zink_gfx_program *);
 
 VkPipeline
 zink_get_gfx_pipeline(VkDevice dev, struct zink_gfx_program *prog,
-                      struct zink_gfx_pipeline_state *state);
+                      struct zink_gfx_pipeline_state *state,
+                      enum pipe_prim_type mode);
 
 #endif