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 <jordan.l.justen@intel.com>
This commit is contained in:
@@ -721,33 +721,6 @@ allocate_descriptor_set(struct zink_context *ctx, VkDescriptorSetLayout dsl)
|
|||||||
return desc_set;
|
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
|
static void
|
||||||
zink_bind_vertex_buffers(struct zink_cmdbuf *cmdbuf, struct zink_context *ctx)
|
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)
|
if (!gfx_program)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctx->gfx_pipeline_state.primitive_topology = zink_primitive_topology(dinfo->mode);
|
|
||||||
|
|
||||||
VkPipeline pipeline = zink_get_gfx_pipeline(screen->dev, gfx_program,
|
VkPipeline pipeline = zink_get_gfx_pipeline(screen->dev, gfx_program,
|
||||||
&ctx->gfx_pipeline_state);
|
&ctx->gfx_pipeline_state,
|
||||||
|
dinfo->mode);
|
||||||
|
|
||||||
bool depth_bias = false;
|
bool depth_bias = false;
|
||||||
switch (u_reduced_prim(dinfo->mode)) {
|
switch (u_reduced_prim(dinfo->mode)) {
|
||||||
|
@@ -35,7 +35,8 @@
|
|||||||
|
|
||||||
VkPipeline
|
VkPipeline
|
||||||
zink_create_gfx_pipeline(VkDevice dev, struct zink_gfx_program *prog,
|
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 = {};
|
VkPipelineVertexInputStateCreateInfo vertex_input_state = {};
|
||||||
vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
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 = {};
|
VkPipelineInputAssemblyStateCreateInfo primitive_state = {};
|
||||||
primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
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;
|
primitive_state.primitiveRestartEnable = VK_FALSE;
|
||||||
|
|
||||||
VkPipelineColorBlendStateCreateInfo blend_state = {};
|
VkPipelineColorBlendStateCreateInfo blend_state = {};
|
||||||
|
@@ -36,7 +36,6 @@ struct zink_render_pass;
|
|||||||
struct zink_vertex_elements_state;
|
struct zink_vertex_elements_state;
|
||||||
|
|
||||||
struct zink_gfx_pipeline_state {
|
struct zink_gfx_pipeline_state {
|
||||||
VkPrimitiveTopology primitive_topology;
|
|
||||||
struct zink_render_pass *render_pass;
|
struct zink_render_pass *render_pass;
|
||||||
|
|
||||||
struct zink_vertex_elements_state *element_state;
|
struct zink_vertex_elements_state *element_state;
|
||||||
@@ -54,6 +53,7 @@ struct zink_gfx_pipeline_state {
|
|||||||
|
|
||||||
VkPipeline
|
VkPipeline
|
||||||
zink_create_gfx_pipeline(VkDevice dev, struct zink_gfx_program *prog,
|
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
|
#endif
|
||||||
|
@@ -111,10 +111,13 @@ zink_create_gfx_program(VkDevice dev,
|
|||||||
if (!prog)
|
if (!prog)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
prog->pipelines = _mesa_hash_table_create(NULL, hash_gfx_pipeline_state,
|
for (int i = 0; i < ARRAY_SIZE(prog->pipelines); ++i) {
|
||||||
equals_gfx_pipeline_state);
|
prog->pipelines[i] = _mesa_hash_table_create(NULL,
|
||||||
if (!prog->pipelines)
|
hash_gfx_pipeline_state,
|
||||||
goto fail;
|
equals_gfx_pipeline_state);
|
||||||
|
if (!prog->pipelines[i])
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < PIPE_SHADER_TYPES - 1; ++i)
|
for (int i = 0; i < PIPE_SHADER_TYPES - 1; ++i)
|
||||||
prog->stages[i] = stages[i];
|
prog->stages[i] = stages[i];
|
||||||
@@ -152,15 +155,46 @@ struct pipeline_cache_entry {
|
|||||||
VkPipeline pipeline;
|
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
|
VkPipeline
|
||||||
zink_get_gfx_pipeline(VkDevice dev, struct zink_gfx_program *prog,
|
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
|
/* TODO: use pre-hashed versions to save some time (can re-hash only when
|
||||||
state changes) */
|
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) {
|
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)
|
if (pipeline == VK_NULL_HANDLE)
|
||||||
return 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));
|
memcpy(&pc_entry->state, state, sizeof(*state));
|
||||||
pc_entry->pipeline = pipeline;
|
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);
|
assert(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ struct zink_gfx_program {
|
|||||||
struct zink_shader *stages[PIPE_SHADER_TYPES - 1]; // compute stage doesn't belong here
|
struct zink_shader *stages[PIPE_SHADER_TYPES - 1]; // compute stage doesn't belong here
|
||||||
VkDescriptorSetLayout dsl;
|
VkDescriptorSetLayout dsl;
|
||||||
VkPipelineLayout layout;
|
VkPipelineLayout layout;
|
||||||
struct hash_table *pipelines;
|
struct hash_table *pipelines[PIPE_PRIM_TRIANGLE_FAN + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zink_gfx_program *
|
struct zink_gfx_program *
|
||||||
@@ -48,6 +48,7 @@ zink_destroy_gfx_program(VkDevice dev, struct zink_gfx_program *);
|
|||||||
|
|
||||||
VkPipeline
|
VkPipeline
|
||||||
zink_get_gfx_pipeline(VkDevice dev, struct zink_gfx_program *prog,
|
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
|
#endif
|
||||||
|
Reference in New Issue
Block a user