vulkan: Don't intern strings
authorBenjamin Otte <otte@redhat.com>
Fri, 7 Jul 2023 00:38:22 +0000 (02:38 +0200)
committerBenjamin Otte <otte@redhat.com>
Sun, 16 Jul 2023 10:13:00 +0000 (12:13 +0200)
Interning strings is slow, especially if we can instead do direct
pointer compares.

Also refactor the pipeline lookup code a bit to make use of the
refactored code.

gsk/vulkan/gskvulkanrender.c
gsk/vulkan/gskvulkanrenderpass.c
gsk/vulkan/gskvulkanrenderprivate.h

index f98102163c1e8f953dc863f81413d235b6da5419..f1c0bf9e621565acb4089164b48d56509cfe3088 100644 (file)
@@ -73,7 +73,7 @@ typedef struct _PipelineCacheKey PipelineCacheKey;
 
 struct _PipelineCacheKey
 {
-  const /* interned */ char *shader_name;
+  const GskVulkanOpClass *op_class;
   const /* interned */ char *clip_type;
   VkFormat format;
 };
@@ -83,7 +83,7 @@ pipeline_cache_key_hash (gconstpointer data)
 {
   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;
 }
@@ -95,7 +95,7 @@ pipeline_cache_key_equal (gconstpointer a,
   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;
 }
@@ -355,12 +355,11 @@ gsk_vulkan_render_upload (GskVulkanRender *self)
 }
 
 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;
@@ -368,8 +367,8 @@ gsk_vulkan_render_create_pipeline (GskVulkanRender                            *s
   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);
@@ -377,8 +376,8 @@ gsk_vulkan_render_create_pipeline (GskVulkanRender                            *s
     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),
@@ -400,7 +399,7 @@ gsk_vulkan_render_create_pipeline (GskVulkanRender                            *s
                                                        .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,
index 21c4776c04e47ce1363ca9c3555573516ea654ff..ec54694ce340e688e890859d598813ec78571595 100644 (file)
@@ -1491,9 +1491,10 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass     *self,
                                   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);
 
@@ -1508,22 +1509,20 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass     *self,
 
   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);
index 3ae0a1e2a9a299c2352eed09388d48821e385726..4569c0e6f1f40fe1126b7909478a03d2f9e5cd55 100644 (file)
@@ -31,9 +31,8 @@ GskRenderer *           gsk_vulkan_render_get_renderer                  (GskVulk
 void                    gsk_vulkan_render_upload                        (GskVulkanRender        *self);
 
 VkPipeline              gsk_vulkan_render_create_pipeline               (GskVulkanRender        *self,
-                                                                         const char             *shader_name,
+                                                                         const GskVulkanOpClass *op_class,
                                                                          const char             *clip_type,
-                                                                         const VkPipelineVertexInputStateCreateInfo *vertex_input_state,
                                                                          VkFormat                format,
                                                                          VkRenderPass            render_pass);
 gsize                   gsk_vulkan_render_get_image_descriptor          (GskVulkanRender        *self,