gsize vk_pipeline_cache_size;
char *vk_pipeline_cache_etag;
guint vk_save_pipeline_cache_source;
+ GHashTable *vk_shader_modules;
guint vulkan_refcount;
#endif /* GDK_RENDERING_VULKAN */
gdk_display_create_pipeline_cache (display);
+ display->vk_shader_modules = g_hash_table_new (g_str_hash, g_str_equal);
+
return TRUE;
}
void
gdk_display_unref_vulkan (GdkDisplay *display)
{
+ GHashTableIter iter;
+ gpointer key, value;
+
g_return_if_fail (GDK_IS_DISPLAY (display));
g_return_if_fail (display->vulkan_refcount > 0);
if (display->vulkan_refcount > 0)
return;
+ display->vk_shader_modules = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_iter_init (&iter, display->vk_shader_modules);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ g_free (key);
+ vkDestroyShaderModule (display->vk_device,
+ value,
+ NULL);
+ }
+
if (display->vk_save_pipeline_cache_source)
{
gdk_vulkan_save_pipeline_cache_cb (display);
display->vk_instance = VK_NULL_HANDLE;
}
+VkShaderModule
+gdk_display_get_vk_shader_module (GdkDisplay *self,
+ const char *resource_name)
+{
+ VkShaderModule shader;
+ GError *error = NULL;
+ GBytes *bytes;
+
+ shader = g_hash_table_lookup (self->vk_shader_modules, resource_name);
+ if (shader)
+ return shader;
+
+ bytes = g_resources_lookup_data (resource_name, 0, &error);
+ if (bytes == NULL)
+ {
+ GDK_DEBUG (VULKAN, "Error loading shader data: %s", error->message);
+ g_clear_error (&error);
+ return VK_NULL_HANDLE;
+ }
+
+ if (GDK_VK_CHECK (vkCreateShaderModule, self->vk_device,
+ &(VkShaderModuleCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+ .codeSize = g_bytes_get_size (bytes),
+ .pCode = (uint32_t *) g_bytes_get_data (bytes, NULL),
+ },
+ NULL,
+ &shader) == VK_SUCCESS)
+ {
+ g_hash_table_insert (self->vk_shader_modules, g_strdup (resource_name), shader);
+ }
+ else
+ {
+ shader = VK_NULL_HANDLE;
+ }
+
+ g_bytes_unref (bytes);
+
+ return shader;
+}
+
#else /* GDK_RENDERING_VULKAN */
static void
GError **error);
void gdk_display_unref_vulkan (GdkDisplay *display);
+VkShaderModule gdk_display_get_vk_shader_module (GdkDisplay *display,
+ const char *resource_name);
+
VkPipelineCache gdk_vulkan_context_get_pipeline_cache (GdkVulkanContext *self);
void gdk_vulkan_context_pipeline_cache_updated (GdkVulkanContext *self);
'vulkan/gskvulkanrenderer.c',
'vulkan/gskvulkanrenderpass.c',
'vulkan/gskvulkanscissorop.c',
- 'vulkan/gskvulkanshader.c',
'vulkan/gskvulkantextpipeline.c',
'vulkan/gskvulkantexturepipeline.c',
'vulkan/gskvulkantextureop.c',
#include "gskvulkanpipelineprivate.h"
#include "gskvulkanpushconstantsprivate.h"
-#include "gskvulkanshaderprivate.h"
#include "gdk/gdkvulkancontextprivate.h"
VkPipeline pipeline;
- GskVulkanShader *vertex_shader;
- GskVulkanShader *fragment_shader;
-
gsize vertex_stride;
};
priv->pipeline,
NULL);
- g_clear_pointer (&priv->fragment_shader, gsk_vulkan_shader_free);
- g_clear_pointer (&priv->vertex_shader, gsk_vulkan_shader_free);
-
G_OBJECT_CLASS (gsk_vulkan_pipeline_parent_class)->finalize (gobject);
}
const VkPipelineVertexInputStateCreateInfo *vertex_input_state;
GskVulkanPipelinePrivate *priv;
GskVulkanPipeline *self;
+ GdkDisplay *display;
VkDevice device;
+ char *vertex_shader_name, *fragment_shader_name;
g_return_val_if_fail (g_type_is_a (pipeline_type, GSK_TYPE_VULKAN_PIPELINE), NULL);
g_return_val_if_fail (layout != VK_NULL_HANDLE, NULL);
priv = gsk_vulkan_pipeline_get_instance_private (self);
+ display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
device = gdk_vulkan_context_get_device (context);
priv->context = context;
- priv->vertex_shader = gsk_vulkan_shader_new_from_resource (context, GSK_VULKAN_SHADER_VERTEX, shader_name, NULL);
- priv->fragment_shader = gsk_vulkan_shader_new_from_resource (context, GSK_VULKAN_SHADER_FRAGMENT, shader_name, NULL);
+ vertex_shader_name = g_strconcat ("/org/gtk/libgsk/vulkan/", shader_name, ".vert.spv", NULL);
+ fragment_shader_name = g_strconcat ("/org/gtk/libgsk/vulkan/", shader_name, ".frag.spv", NULL);
vertex_input_state = GSK_VULKAN_PIPELINE_GET_CLASS (self)->get_input_state_create_info (self);
g_assert (vertex_input_state->vertexBindingDescriptionCount == 1);
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.stageCount = 2,
.pStages = (VkPipelineShaderStageCreateInfo[2]) {
- GST_VULKAN_SHADER_STAGE_CREATE_INFO (priv->vertex_shader),
- GST_VULKAN_SHADER_STAGE_CREATE_INFO (priv->fragment_shader)
+ {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+ .stage = VK_SHADER_STAGE_VERTEX_BIT,
+ .module = gdk_display_get_vk_shader_module (display, vertex_shader_name),
+ .pName = "main",
+ },
+ {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+ .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
+ .module = gdk_display_get_vk_shader_module (display, fragment_shader_name),
+ .pName = "main",
+ },
},
.pVertexInputState = vertex_input_state,
.pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
NULL,
&priv->pipeline);
+ g_free (fragment_shader_name);
+ g_free (vertex_shader_name);
+
gdk_vulkan_context_pipeline_cache_updated (context);
return self;
+++ /dev/null
-#include "config.h"
-
-#include "gskvulkanshaderprivate.h"
-#include "gskvulkanpipelineprivate.h"
-
-struct _GskVulkanShader
-{
- GdkVulkanContext *vulkan;
-
- GskVulkanShaderType type;
- VkShaderModule vk_shader;
-};
-
-static GskVulkanShader *
-gsk_vulkan_shader_new_from_bytes (GdkVulkanContext *context,
- GskVulkanShaderType type,
- GBytes *bytes,
- GError **error)
-{
- GskVulkanShader *self;
- VkShaderModule shader;
- VkResult res;
-
- res = GSK_VK_CHECK (vkCreateShaderModule, gdk_vulkan_context_get_device (context),
- &(VkShaderModuleCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
- .codeSize = g_bytes_get_size (bytes),
- .pCode = (uint32_t *) g_bytes_get_data (bytes, NULL),
- },
- NULL,
- &shader);
- if (res != VK_SUCCESS)
- {
- /* Someone invent better error categories plz */
- g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,
- "Could not create shader: %s", gdk_vulkan_strerror (res));
- return NULL;
- }
-
- self = g_new0 (GskVulkanShader, 1);
-
- self->vulkan = g_object_ref (context);
- self->type = type;
- self->vk_shader = shader;
-
- return self;
-}
-
-GskVulkanShader *
-gsk_vulkan_shader_new_from_resource (GdkVulkanContext *context,
- GskVulkanShaderType type,
- const char *resource_name,
- GError **error)
-{
- GskVulkanShader *self;
- GBytes *bytes;
- GError *local_error = NULL;
- char *path;
-
- path = g_strconcat ("/org/gtk/libgsk/vulkan/",
- resource_name,
- type == GSK_VULKAN_SHADER_VERTEX ? ".vert.spv" : ".frag.spv",
- NULL);
- bytes = g_resources_lookup_data (path, 0, &local_error);
- g_free (path);
- if (bytes == NULL)
- {
- GSK_DEBUG (VULKAN, "Error loading shader data: %s", local_error->message);
- g_propagate_error (error, local_error);
- return NULL;
- }
-
- self = gsk_vulkan_shader_new_from_bytes (context, type, bytes, error);
- g_bytes_unref (bytes);
-
- return self;
-}
-
-void
-gsk_vulkan_shader_free (GskVulkanShader *self)
-{
- vkDestroyShaderModule (gdk_vulkan_context_get_device (self->vulkan),
- self->vk_shader,
- NULL);
-
- g_object_unref (self->vulkan);
-
- g_free (self);
-}
-
-GskVulkanShaderType
-gsk_vulkan_shader_get_type (GskVulkanShader *shader)
-{
- return shader->type;
-}
-
-VkShaderModule
-gsk_vulkan_shader_get_module (GskVulkanShader *shader)
-{
- return shader->vk_shader;
-}
-
+++ /dev/null
-#pragma once
-
-#include <gdk/gdk.h>
-
-G_BEGIN_DECLS
-
-typedef enum {
- GSK_VULKAN_SHADER_VERTEX,
- GSK_VULKAN_SHADER_FRAGMENT
-} GskVulkanShaderType;
-
-typedef struct _GskVulkanShader GskVulkanShader;
-
-#define GST_VULKAN_SHADER_STAGE_CREATE_INFO(shader) \
- (VkPipelineShaderStageCreateInfo) { \
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, \
- .stage = gsk_vulkan_shader_get_type (shader) == GSK_VULKAN_SHADER_VERTEX ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT, \
- .module = gsk_vulkan_shader_get_module (shader), \
- .pName = "main", \
-}
-
-GskVulkanShader * gsk_vulkan_shader_new_from_resource (GdkVulkanContext *context,
- GskVulkanShaderType type,
- const char *resource_name,
- GError **error);
-void gsk_vulkan_shader_free (GskVulkanShader *shader);
-
-GskVulkanShaderType gsk_vulkan_shader_get_type (GskVulkanShader *shader);
-VkShaderModule gsk_vulkan_shader_get_module (GskVulkanShader *shader);
-
-G_END_DECLS
-