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>tags/19.3-branchpoint
@@ -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)) { |
@@ -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 = {}; |
@@ -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 |
@@ -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); | |||
} | |||
@@ -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 |