struct _PipelineCacheKey
{
- const /* interned */ char *shader_name;
+ const GskVulkanOpClass *op_class;
const /* interned */ char *clip_type;
VkFormat format;
};
{
const PipelineCacheKey *key = data;
- return GPOINTER_TO_UINT (key->shader_name) ^
+ return GPOINTER_TO_UINT (key->op_class) ^
GPOINTER_TO_UINT (key->clip_type) ^
key->format;
}
const PipelineCacheKey *keya = a;
const PipelineCacheKey *keyb = b;
- return keya->shader_name == keyb->shader_name &&
+ return keya->op_class == keyb->op_class &&
keya->clip_type == keyb->clip_type &&
keya->format == keyb->format;
}
}
VkPipeline
-gsk_vulkan_render_create_pipeline (GskVulkanRender *self,
- const char *shader_name,
- const char *clip_type,
- const VkPipelineVertexInputStateCreateInfo *vertex_input_state,
- VkFormat format,
- VkRenderPass render_pass)
+gsk_vulkan_render_create_pipeline (GskVulkanRender *self,
+ const GskVulkanOpClass *op_class,
+ const char *clip_type,
+ VkFormat format,
+ VkRenderPass render_pass)
{
PipelineCacheKey cache_key;
VkPipeline pipeline;
char *vertex_shader_name, *fragment_shader_name;
cache_key = (PipelineCacheKey) {
- .shader_name = g_intern_string (shader_name),
- .clip_type = g_intern_string (clip_type),
+ .op_class = op_class,
+ .clip_type = clip_type,
.format = format,
};
pipeline = g_hash_table_lookup (self->pipeline_cache, &cache_key);
return pipeline;
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self->vulkan));
- vertex_shader_name = g_strconcat ("/org/gtk/libgsk/vulkan/", shader_name, clip_type, ".vert.spv", NULL);
- fragment_shader_name = g_strconcat ("/org/gtk/libgsk/vulkan/", shader_name, clip_type, ".frag.spv", NULL);
+ vertex_shader_name = g_strconcat ("/org/gtk/libgsk/vulkan/", op_class->shader_name, clip_type, ".vert.spv", NULL);
+ fragment_shader_name = g_strconcat ("/org/gtk/libgsk/vulkan/", op_class->shader_name, clip_type, ".frag.spv", NULL);
GSK_VK_CHECK (vkCreateGraphicsPipelines, gdk_vulkan_context_get_device (self->vulkan),
gdk_vulkan_context_get_pipeline_cache (self->vulkan),
.pName = "main",
},
},
- .pVertexInputState = vertex_input_state,
+ .pVertexInputState = op_class->vertex_input_state,
.pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
VkCommandBuffer command_buffer)
{
VkPipeline current_pipeline = VK_NULL_HANDLE;
- VkPipeline op_pipeline;
- GskVulkanOp *op;
+ const GskVulkanOpClass *current_pipeline_class = NULL;
+ const char *current_pipeline_clip_type = NULL;
GskVulkanBuffer *vertex_buffer;
+ GskVulkanOp *op;
vertex_buffer = gsk_vulkan_render_pass_get_vertex_data (self, render);
for (op = gsk_vulkan_render_pass_get_first_op (self); op; op = op->next)
{
- if (op->op_class->shader_name)
+ if (op->op_class->shader_name &&
+ (op->op_class != current_pipeline_class ||
+ current_pipeline_clip_type != op->clip_type))
{
- op_pipeline = gsk_vulkan_render_create_pipeline (render,
- op->op_class->shader_name,
- op->clip_type,
- op->op_class->vertex_input_state,
- gsk_vulkan_image_get_vk_format (self->target),
- self->render_pass);
-
- if (op_pipeline != current_pipeline)
- {
- current_pipeline = op_pipeline;
- vkCmdBindPipeline (command_buffer,
- VK_PIPELINE_BIND_POINT_GRAPHICS,
- current_pipeline);
- }
+ current_pipeline = gsk_vulkan_render_create_pipeline (render,
+ op->op_class,
+ op->clip_type,
+ gsk_vulkan_image_get_vk_format (self->target),
+ self->render_pass);
+ vkCmdBindPipeline (command_buffer,
+ VK_PIPELINE_BIND_POINT_GRAPHICS,
+ current_pipeline);
+ current_pipeline_class = op->op_class;
+ current_pipeline_clip_type = op->clip_type;
}
gsk_vulkan_op_command (op, render, pipeline_layout, command_buffer);