summaryrefslogtreecommitdiff
path: root/gsk/gskvulkanshader.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2016-12-05 02:50:06 +0100
committerBenjamin Otte <otte@redhat.com>2016-12-09 18:35:51 +0100
commit2a0e7f88295b8d73f9c2a248c18dd5301bff513c (patch)
tree63e40059d439f408b3ff14d3f93e96c6dc0a150a /gsk/gskvulkanshader.c
parent3f7cc013cc588fd1ce4d53921bc5cfe51af21bfe (diff)
downloadgtk+-2a0e7f88295b8d73f9c2a248c18dd5301bff513c.tar.gz
gsk: Loads of work on Vulkan backend
We can now upload vertices. And we use this to draw a yellow background. Which is clearly superior to not drawing anything. Also, we have shaders now. If you modify them, you need glslc installed so they can be recompiled into Spir-V bytecode.
Diffstat (limited to 'gsk/gskvulkanshader.c')
-rw-r--r--gsk/gskvulkanshader.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/gsk/gskvulkanshader.c b/gsk/gskvulkanshader.c
new file mode 100644
index 0000000000..1010b21304
--- /dev/null
+++ b/gsk/gskvulkanshader.c
@@ -0,0 +1,102 @@
+#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_slice_new0 (GskVulkanShader);
+
+ 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_NOTE (VULKAN, g_printerr ("Error loading shader data: %s\n", 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_slice_free (GskVulkanShader, self);
+}
+
+GskVulkanShaderType
+gsk_vulkan_shader_get_type (GskVulkanShader *shader)
+{
+ return shader->type;
+}
+
+VkShaderModule
+gsk_vulkan_shader_get_module (GskVulkanShader *shader)
+{
+ return shader->vk_shader;
+}
+