From 8f6449f29686cd9ea199ab00536b890b1d9e8e93 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Wed, 19 Jun 2019 12:29:49 +0200 Subject: [PATCH] zink: move primitive-topology stuff into program 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 --- src/gallium/drivers/zink/zink_context.c | 32 ++------------------ src/gallium/drivers/zink/zink_pipeline.c | 5 ++-- src/gallium/drivers/zink/zink_pipeline.h | 4 +-- src/gallium/drivers/zink/zink_program.c | 50 +++++++++++++++++++++++++++----- src/gallium/drivers/zink/zink_program.h | 5 ++-- 5 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 9e6b434..6a9430c 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -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)) { diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c index b06f02a..0dd8918 100644 --- a/src/gallium/drivers/zink/zink_pipeline.c +++ b/src/gallium/drivers/zink/zink_pipeline.c @@ -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 = {}; diff --git a/src/gallium/drivers/zink/zink_pipeline.h b/src/gallium/drivers/zink/zink_pipeline.h index 9990c50..a2a627d 100644 --- a/src/gallium/drivers/zink/zink_pipeline.h +++ b/src/gallium/drivers/zink/zink_pipeline.h @@ -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 diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index ed890b9..9398fa2 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -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); } diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index 275cafa..d4357fc 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -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 -- 2.7.4