Instead of creating a pipeline GObject, just ask for the VkPipeline.
And instead of having the Op handle it, just let the renderpass look
up/create the relevant pipeline while creating commands so that it can
insert vkCmdBindPipeline calls as-needed.
'vulkan/gskvulkancolortextpipeline.c',
'vulkan/gskvulkancommandpool.c',
'vulkan/gskvulkancrossfadepipeline.c',
- 'vulkan/gskvulkaneffectpipeline.c',
'vulkan/gskvulkanglyphcache.c',
'vulkan/gskvulkanimage.c',
'vulkan/gskvulkanlineargradientpipeline.c',
'vulkan/gskvulkanrenderpass.c',
'vulkan/gskvulkanscissorop.c',
'vulkan/gskvulkantextpipeline.c',
- 'vulkan/gskvulkantexturepipeline.c',
'vulkan/gskvulkantextureop.c',
'vulkan/gskvulkanuploadcairoop.c',
'vulkan/gskvulkanuploadop.c',
return gsk_rounded_rect_contains_rect (&self->rect, &r);
}
}
+
+const char *
+gsk_vulkan_clip_get_clip_type (const GskVulkanClip *self,
+ const graphene_point_t *offset,
+ const graphene_rect_t *rect)
+{
+ if (gsk_vulkan_clip_contains_rect (self, offset, rect))
+ return "";
+ else if (self->type == GSK_VULKAN_CLIP_RECT)
+ return "-clip";
+ else
+ return "-clip-rounded";
+}
+
gboolean gsk_vulkan_clip_may_intersect_rect (const GskVulkanClip *self,
const graphene_point_t *offset,
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
+const char * gsk_vulkan_clip_get_clip_type (const GskVulkanClip *self,
+ const graphene_point_t *offset,
+ const graphene_rect_t *rect);
G_END_DECLS
#include "gskvulkancolormatrixopprivate.h"
-#include "gskvulkaneffectpipelineprivate.h"
+#include "vulkan/resources/color-matrix.vert.h"
typedef struct _GskVulkanColorMatrixOp GskVulkanColorMatrixOp;
graphene_rect_t tex_rect;
guint32 image_descriptor;
- GskVulkanPipeline *pipeline;
gsize vertex_offset;
};
GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
gsize vertex_stride;
- vertex_stride = gsk_vulkan_pipeline_get_vertex_stride (self->pipeline);
+ vertex_stride = gsk_vulkan_color_matrix_info.pVertexBindingDescriptions[0].stride;
n_bytes = round_up (n_bytes, vertex_stride);
self->vertex_offset = n_bytes;
n_bytes += vertex_stride;
static void
gsk_vulkan_color_matrix_op_collect_vertex_data (GskVulkanOp *op,
- GskVulkanRenderPass *pass,
- GskVulkanRender *render,
- guchar *data)
+ GskVulkanRenderPass *pass,
+ GskVulkanRender *render,
+ guchar *data)
{
GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
-
- gsk_vulkan_effect_pipeline_collect_vertex_data (GSK_VULKAN_EFFECT_PIPELINE (self->pipeline),
- data + self->vertex_offset,
- self->image_descriptor,
- graphene_point_zero (),
- &self->rect,
- &self->tex_rect,
- &self->color_matrix,
- &self->color_offset);
+ GskVulkanColorMatrixInstance *instance = (GskVulkanColorMatrixInstance *) (data + self->vertex_offset);
+
+ instance->rect[0] = self->rect.origin.x;
+ instance->rect[1] = self->rect.origin.y;
+ instance->rect[2] = self->rect.size.width;
+ instance->rect[3] = self->rect.size.height;
+ instance->tex_rect[0] = self->tex_rect.origin.x;
+ instance->tex_rect[1] = self->tex_rect.origin.y;
+ instance->tex_rect[2] = self->tex_rect.size.width;
+ instance->tex_rect[3] = self->tex_rect.size.height;
+ graphene_matrix_to_float (&self->color_matrix, instance->color_matrix);
+ graphene_vec4_to_float (&self->color_offset, instance->color_offset);
+ instance->tex_id = self->image_descriptor;
}
static void
static VkPipeline
gsk_vulkan_color_matrix_op_get_pipeline (GskVulkanOp *op)
{
- GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
-
- return gsk_vulkan_pipeline_get_pipeline (self->pipeline);
+ return VK_NULL_HANDLE;
}
static void
{
GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
- gsk_vulkan_effect_pipeline_draw (GSK_VULKAN_EFFECT_PIPELINE (self->pipeline),
- command_buffer,
- self->vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (self->pipeline),
- 1);
+ vkCmdDraw (command_buffer,
+ 6, 1,
+ 0, self->vertex_offset / gsk_vulkan_color_matrix_info.pVertexBindingDescriptions[0].stride);
}
static const GskVulkanOpClass GSK_VULKAN_COLOR_MATRIX_OP_CLASS = {
GSK_VULKAN_OP_SIZE (GskVulkanColorMatrixOp),
+ "color-matrix",
+ &gsk_vulkan_color_matrix_info,
gsk_vulkan_color_matrix_op_finish,
gsk_vulkan_color_matrix_op_upload,
gsk_vulkan_color_matrix_op_count_vertex_data,
void
gsk_vulkan_color_matrix_op (GskVulkanRenderPass *render_pass,
- GskVulkanPipeline *pipeline,
+ const char *clip_type,
GskVulkanImage *image,
const graphene_rect_t *rect,
const graphene_point_t *offset,
self = (GskVulkanColorMatrixOp *) gsk_vulkan_op_alloc (render_pass, &GSK_VULKAN_COLOR_MATRIX_OP_CLASS);
- self->pipeline = pipeline;
+ ((GskVulkanOp *) self)->clip_type = g_intern_string (clip_type);
self->image = g_object_ref (image);
graphene_rect_offset_r (rect, offset->x, offset->y, &self->rect);
gsk_vulkan_normalize_tex_coords (&self->tex_rect, rect, tex_rect);
G_BEGIN_DECLS
void gsk_vulkan_color_matrix_op (GskVulkanRenderPass *render_pass,
- GskVulkanPipeline *pipeline,
+ const char *clip_type,
GskVulkanImage *image,
const graphene_rect_t *rect,
const graphene_point_t *offset,
+++ /dev/null
-#include "config.h"
-
-#include "gskvulkaneffectpipelineprivate.h"
-
-#include "vulkan/resources/color-matrix.vert.h"
-
-struct _GskVulkanEffectPipeline
-{
- GObject parent_instance;
-};
-
-G_DEFINE_TYPE (GskVulkanEffectPipeline, gsk_vulkan_effect_pipeline, GSK_TYPE_VULKAN_PIPELINE)
-
-static const VkPipelineVertexInputStateCreateInfo *
-gsk_vulkan_effect_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
-{
- return &gsk_vulkan_color_matrix_info;
-}
-
-static void
-gsk_vulkan_effect_pipeline_finalize (GObject *gobject)
-{
- //GskVulkanEffectPipeline *self = GSK_VULKAN_EFFECT_PIPELINE (gobject);
-
- G_OBJECT_CLASS (gsk_vulkan_effect_pipeline_parent_class)->finalize (gobject);
-}
-
-static void
-gsk_vulkan_effect_pipeline_class_init (GskVulkanEffectPipelineClass *klass)
-{
- GskVulkanPipelineClass *pipeline_class = GSK_VULKAN_PIPELINE_CLASS (klass);
-
- G_OBJECT_CLASS (klass)->finalize = gsk_vulkan_effect_pipeline_finalize;
-
- pipeline_class->get_input_state_create_info = gsk_vulkan_effect_pipeline_get_input_state_create_info;
-}
-
-static void
-gsk_vulkan_effect_pipeline_init (GskVulkanEffectPipeline *self)
-{
-}
-
-GskVulkanPipeline *
-gsk_vulkan_effect_pipeline_new (GdkVulkanContext *context,
- VkPipelineLayout layout,
- const char *shader_name,
- VkRenderPass render_pass)
-{
- return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_EFFECT_PIPELINE, context, layout, shader_name, render_pass);
-}
-
-void
-gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipeline,
- guchar *data,
- guint32 tex_id,
- const graphene_point_t *offset,
- const graphene_rect_t *rect,
- const graphene_rect_t *tex_rect,
- const graphene_matrix_t *color_matrix,
- const graphene_vec4_t *color_offset)
-{
- GskVulkanColorMatrixInstance *instance = (GskVulkanColorMatrixInstance *) data;
-
- instance->rect[0] = rect->origin.x + offset->x;
- instance->rect[1] = rect->origin.y + offset->y;
- instance->rect[2] = rect->size.width;
- instance->rect[3] = rect->size.height;
- instance->tex_rect[0] = tex_rect->origin.x;
- instance->tex_rect[1] = tex_rect->origin.y;
- instance->tex_rect[2] = tex_rect->size.width;
- instance->tex_rect[3] = tex_rect->size.height;
- graphene_matrix_to_float (color_matrix, instance->color_matrix);
- graphene_vec4_to_float (color_offset, instance->color_offset);
- instance->tex_id = tex_id;
-}
-
-gsize
-gsk_vulkan_effect_pipeline_draw (GskVulkanEffectPipeline *pipeline,
- VkCommandBuffer command_buffer,
- gsize offset,
- gsize n_commands)
-{
- vkCmdDraw (command_buffer,
- 6, n_commands,
- 0, offset);
-
- return n_commands;
-}
+++ /dev/null
-#pragma once
-
-#include <graphene.h>
-
-#include "gskvulkanpipelineprivate.h"
-
-G_BEGIN_DECLS
-
-typedef struct _GskVulkanEffectPipelineLayout GskVulkanEffectPipelineLayout;
-
-#define GSK_TYPE_VULKAN_EFFECT_PIPELINE (gsk_vulkan_effect_pipeline_get_type ())
-
-G_DECLARE_FINAL_TYPE (GskVulkanEffectPipeline, gsk_vulkan_effect_pipeline, GSK, VULKAN_EFFECT_PIPELINE, GskVulkanPipeline)
-
-GskVulkanPipeline * gsk_vulkan_effect_pipeline_new (GdkVulkanContext *context,
- VkPipelineLayout layout,
- const char *shader_name,
- VkRenderPass render_pass);
-
-void gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipeline,
- guchar *data,
- guint32 tex_id,
- const graphene_point_t *offset,
- const graphene_rect_t *rect,
- const graphene_rect_t *tex_rect,
- const graphene_matrix_t *color_matrix,
- const graphene_vec4_t *color_offset);
-gsize gsk_vulkan_effect_pipeline_draw (GskVulkanEffectPipeline *pipeline,
- VkCommandBuffer command_buffer,
- gsize offset,
- gsize n_commands);
-
-G_END_DECLS
-
static const GskVulkanOpClass GSK_VULKAN_OFFSCREEN_OP_CLASS = {
GSK_VULKAN_OP_SIZE (GskVulkanOffscreenOp),
+ NULL,
+ NULL,
gsk_vulkan_offscreen_op_finish,
gsk_vulkan_offscreen_op_upload,
gsk_vulkan_offscreen_op_count_vertex_data,
{
const GskVulkanOpClass *op_class;
- VkPipeline pipeline;
+ const /* interned */ char *clip_type;
};
struct _GskVulkanOpClass
{
gsize size;
+ const char * shader_name;
+ const VkPipelineVertexInputStateCreateInfo *vertex_input_state;
+
void (* finish) (GskVulkanOp *op);
void (* upload) (GskVulkanOp *op,
#include "gskvulkancolorpipelineprivate.h"
#include "gskvulkancolortextpipelineprivate.h"
#include "gskvulkancrossfadepipelineprivate.h"
-#include "gskvulkaneffectpipelineprivate.h"
#include "gskvulkanlineargradientpipelineprivate.h"
#include "gskvulkantextpipelineprivate.h"
-#include "gskvulkantexturepipelineprivate.h"
#include "gskvulkanpushconstantsprivate.h"
+#include "gdk/gdkvulkancontextprivate.h"
+
#define DESCRIPTOR_POOL_MAXITEMS 50000
#define GDK_ARRAY_NAME gsk_descriptor_image_infos
VkDescriptorPool descriptor_pool;
VkDescriptorSet descriptor_sets[N_DESCRIPTOR_SETS];
GskVulkanPipeline *pipelines[GSK_VULKAN_N_PIPELINES];
+ GHashTable *pipeline_cache;
GskVulkanImage *target;
GQuark gpu_time_timer;
};
+typedef struct _PipelineCacheKey PipelineCacheKey;
+
+struct _PipelineCacheKey
+{
+ const /* interned */ char *shader_name;
+ const /* interned */ char *clip_type;
+ VkFormat format;
+};
+
+static guint
+pipeline_cache_key_hash (gconstpointer data)
+{
+ const PipelineCacheKey *key = data;
+
+ return GPOINTER_TO_UINT (key->shader_name) ^
+ GPOINTER_TO_UINT (key->clip_type) ^
+ key->format;
+}
+
+static gboolean
+pipeline_cache_key_equal (gconstpointer a,
+ gconstpointer b)
+{
+ const PipelineCacheKey *keya = a;
+ const PipelineCacheKey *keyb = b;
+
+ return keya->shader_name == keyb->shader_name &&
+ keya->clip_type == keyb->clip_type &&
+ keya->format == keyb->format;
+}
+
static void
gsk_vulkan_render_setup (GskVulkanRender *self,
GskVulkanImage *target,
self->uploader = gsk_vulkan_uploader_new (self->vulkan, self->command_pool);
+ self->pipeline_cache = g_hash_table_new (pipeline_cache_key_hash, pipeline_cache_key_equal);
#ifdef G_ENABLE_DEBUG
self->render_pass_counter = g_quark_from_static_string ("render-passes");
gsk_vulkan_uploader_upload (self->uploader);
}
+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)
+{
+ PipelineCacheKey cache_key;
+ VkPipeline pipeline;
+ GdkDisplay *display;
+ char *vertex_shader_name, *fragment_shader_name;
+
+ cache_key = (PipelineCacheKey) {
+ .shader_name = g_intern_string (shader_name),
+ .clip_type = g_intern_string (clip_type),
+ .format = format,
+ };
+ pipeline = g_hash_table_lookup (self->pipeline_cache, &cache_key);
+ if (pipeline)
+ 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);
+
+ GSK_VK_CHECK (vkCreateGraphicsPipelines, gdk_vulkan_context_get_device (self->vulkan),
+ gdk_vulkan_context_get_pipeline_cache (self->vulkan),
+ 1,
+ &(VkGraphicsPipelineCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+ .stageCount = 2,
+ .pStages = (VkPipelineShaderStageCreateInfo[2]) {
+ {
+ .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) {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+ .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
+ .primitiveRestartEnable = VK_FALSE,
+ },
+ .pTessellationState = NULL,
+ .pViewportState = &(VkPipelineViewportStateCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+ .viewportCount = 1,
+ .scissorCount = 1
+ },
+ .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+ .depthClampEnable = VK_FALSE,
+ .rasterizerDiscardEnable = VK_FALSE,
+ .polygonMode = VK_POLYGON_MODE_FILL,
+ .cullMode = VK_CULL_MODE_NONE,
+ .frontFace = VK_FRONT_FACE_CLOCKWISE,
+ .lineWidth = 1.0f,
+ },
+ .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+ .rasterizationSamples = 1,
+ },
+ .pDepthStencilState = &(VkPipelineDepthStencilStateCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
+ },
+ .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
+ .attachmentCount = 1,
+ .pAttachments = (VkPipelineColorBlendAttachmentState []) {
+ {
+ .blendEnable = VK_TRUE,
+ .colorBlendOp = VK_BLEND_OP_ADD,
+ .srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
+ .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
+ .alphaBlendOp = VK_BLEND_OP_ADD,
+ .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
+ .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
+ .colorWriteMask = VK_COLOR_COMPONENT_A_BIT
+ | VK_COLOR_COMPONENT_R_BIT
+ | VK_COLOR_COMPONENT_G_BIT
+ | VK_COLOR_COMPONENT_B_BIT
+ },
+ }
+ },
+ .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+ .dynamicStateCount = 2,
+ .pDynamicStates = (VkDynamicState[2]) {
+ VK_DYNAMIC_STATE_VIEWPORT,
+ VK_DYNAMIC_STATE_SCISSOR
+ },
+ },
+ .layout = self->pipeline_layout,
+ .renderPass = render_pass,
+ .subpass = 0,
+ .basePipelineHandle = VK_NULL_HANDLE,
+ .basePipelineIndex = -1,
+ },
+ NULL,
+ &pipeline);
+
+ g_free (fragment_shader_name);
+ g_free (vertex_shader_name);
+
+ g_hash_table_insert (self->pipeline_cache, g_memdup (&cache_key, sizeof (PipelineCacheKey)), pipeline);
+ gdk_vulkan_context_pipeline_cache_updated (self->vulkan);
+
+ return pipeline;
+}
+
GskVulkanPipeline *
gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
GskVulkanPipelineType type,
guint num_textures;
GskVulkanPipeline * (* create_func) (GdkVulkanContext *context, VkPipelineLayout layout, const char *name, VkRenderPass render_pass);
} pipeline_info[GSK_VULKAN_N_PIPELINES] = {
- { "texture", 1, gsk_vulkan_texture_pipeline_new },
- { "texture-clip", 1, gsk_vulkan_texture_pipeline_new },
- { "texture-clip-rounded", 1, gsk_vulkan_texture_pipeline_new },
{ "color", 0, gsk_vulkan_color_pipeline_new },
{ "color-clip", 0, gsk_vulkan_color_pipeline_new },
{ "color-clip-rounded", 0, gsk_vulkan_color_pipeline_new },
{ "linear", 0, gsk_vulkan_linear_gradient_pipeline_new },
{ "linear-clip", 0, gsk_vulkan_linear_gradient_pipeline_new },
{ "linear-clip-rounded", 0, gsk_vulkan_linear_gradient_pipeline_new },
- { "color-matrix", 1, gsk_vulkan_effect_pipeline_new },
- { "color-matrix-clip", 1, gsk_vulkan_effect_pipeline_new },
- { "color-matrix-clip-rounded", 1, gsk_vulkan_effect_pipeline_new },
{ "border", 0, gsk_vulkan_border_pipeline_new },
{ "border-clip", 0, gsk_vulkan_border_pipeline_new },
{ "border-clip-rounded", 0, gsk_vulkan_border_pipeline_new },
gsk_vulkan_render_free (GskVulkanRender *self)
{
VkDevice device;
+ GHashTableIter iter;
+ gpointer key, value;
guint i;
gsk_vulkan_render_cleanup (self);
device = gdk_vulkan_context_get_device (self->vulkan);
+ g_hash_table_iter_init (&iter, self->pipeline_cache);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ g_free (key);
+ vkDestroyPipeline (device, value, NULL);
+ }
+ g_hash_table_unref (self->pipeline_cache);
+
for (i = 0; i < GSK_VULKAN_N_PIPELINES; i++)
g_clear_object (&self->pipelines[i]);
const GskVulkanParseState *state,
GskRenderNode *node)
{
- GskVulkanPipelineType pipeline_type;
GskVulkanImage *image;
graphene_rect_t clipped;
&state->scale,
&clipped);
- if (gsk_vulkan_clip_contains_rect (&state->clip, &state->offset, &node->bounds))
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE;
- else if (state->clip.type == GSK_VULKAN_CLIP_RECT)
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP;
- else
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP_ROUNDED;
-
gsk_vulkan_texture_op (self,
- gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type),
+ gsk_vulkan_clip_get_clip_type (&state->clip, &state->offset, &node->bounds),
image,
GSK_VULKAN_SAMPLER_DEFAULT,
&node->bounds,
const GskVulkanParseState *state,
GskRenderNode *node)
{
- GskVulkanPipelineType pipeline_type;
GskVulkanImage *image;
GskVulkanRenderer *renderer;
GdkTexture *texture;
- if (gsk_vulkan_clip_contains_rect (&state->clip, &state->offset, &node->bounds))
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE;
- else if (state->clip.type == GSK_VULKAN_CLIP_RECT)
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP;
- else
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP_ROUNDED;
-
renderer = GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render));
texture = gsk_texture_node_get_texture (node);
image = gsk_vulkan_renderer_get_texture_image (renderer, texture);
}
gsk_vulkan_texture_op (self,
- gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type),
+ gsk_vulkan_clip_get_clip_type (&state->clip, &state->offset, &node->bounds),
image,
GSK_VULKAN_SAMPLER_DEFAULT,
&node->bounds,
const GskVulkanParseState *state,
GskRenderNode *node)
{
- GskVulkanPipelineType pipeline_type;
GskVulkanImage *image;
GskVulkanRenderer *renderer;
GskVulkanRenderSampler sampler;
GdkTexture *texture;
- if (gsk_vulkan_clip_contains_rect (&state->clip, &state->offset, &node->bounds))
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE;
- else if (state->clip.type == GSK_VULKAN_CLIP_RECT)
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP;
- else
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP_ROUNDED;
-
renderer = GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render));
texture = gsk_texture_scale_node_get_texture (node);
switch (gsk_texture_scale_node_get_filter (node))
}
gsk_vulkan_texture_op (self,
- gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type),
+ gsk_vulkan_clip_get_clip_type (&state->clip, &state->offset, &node->bounds),
image,
sampler,
&node->bounds,
{
graphene_matrix_t color_matrix;
graphene_vec4_t color_offset;
- GskVulkanPipelineType pipeline_type;
GskVulkanImage *image;
graphene_rect_t tex_rect;
if (image == NULL)
return TRUE;
- if (gsk_vulkan_clip_contains_rect (&state->clip, &state->offset, &node->bounds))
- pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX;
- else if (state->clip.type == GSK_VULKAN_CLIP_RECT)
- pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP;
- else
- pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED;
-
graphene_matrix_init_from_float (&color_matrix,
(float[16]) {
1.0, 0.0, 0.0, 0.0,
graphene_vec4_init (&color_offset, 0.0, 0.0, 0.0, 0.0);
gsk_vulkan_color_matrix_op (self,
- gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type),
+ gsk_vulkan_clip_get_clip_type (&state->clip, &state->offset, &node->bounds),
image,
&node->bounds,
&state->offset,
const GskVulkanParseState *state,
GskRenderNode *node)
{
- GskVulkanPipelineType pipeline_type;
GskVulkanImage *image;
graphene_rect_t tex_rect;
if (image == NULL)
return TRUE;
- if (gsk_vulkan_clip_contains_rect (&state->clip, &state->offset, &node->bounds))
- pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX;
- else if (state->clip.type == GSK_VULKAN_CLIP_RECT)
- pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP;
- else
- pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED;
-
gsk_vulkan_color_matrix_op (self,
- gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type),
+ gsk_vulkan_clip_get_clip_type (&state->clip, &state->offset, &node->bounds),
image,
&node->bounds,
&state->offset,
const GskVulkanParseState *state,
GskRenderNode *node)
{
- GskVulkanPipelineType pipeline_type;
const graphene_rect_t *child_bounds;
VkSemaphore semaphore;
GskVulkanImage *image;
semaphore,
gsk_repeat_node_get_child (node));
- if (gsk_vulkan_clip_contains_rect (&state->clip, &state->offset, &node->bounds))
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE;
- else if (state->clip.type == GSK_VULKAN_CLIP_RECT)
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP;
- else
- pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP_ROUNDED;
-
gsk_vulkan_texture_op (self,
- gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type),
+ gsk_vulkan_clip_get_clip_type (&state->clip, &state->offset, &node->bounds),
image,
GSK_VULKAN_SAMPLER_REPEAT,
&node->bounds,
{
op = (GskVulkanOp *) gsk_vulkan_render_ops_index (&self->render_ops, i);
- op_pipeline = gsk_vulkan_op_get_pipeline (op);
+ if (op->op_class->shader_name)
+ {
+ 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);
+ }
+ else
+ op_pipeline = gsk_vulkan_op_get_pipeline (op);
+
if (op_pipeline && op_pipeline != current_pipeline)
{
current_pipeline = op_pipeline;
static const GskVulkanOpClass GSK_VULKAN_OP_ALL_CLASS = {
sizeof (GskVulkanOpAll),
+ NULL,
+ NULL,
gsk_vulkan_render_op_finish,
gsk_vulkan_render_op_upload,
gsk_vulkan_render_op_count_vertex_data,
G_BEGIN_DECLS
typedef enum {
- GSK_VULKAN_PIPELINE_TEXTURE,
- GSK_VULKAN_PIPELINE_TEXTURE_CLIP,
- GSK_VULKAN_PIPELINE_TEXTURE_CLIP_ROUNDED,
GSK_VULKAN_PIPELINE_COLOR,
GSK_VULKAN_PIPELINE_COLOR_CLIP,
GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED,
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT,
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP,
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP_ROUNDED,
- GSK_VULKAN_PIPELINE_COLOR_MATRIX,
- GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP,
- GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED,
GSK_VULKAN_PIPELINE_BORDER,
GSK_VULKAN_PIPELINE_BORDER_CLIP,
GSK_VULKAN_PIPELINE_BORDER_CLIP_ROUNDED,
void 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);
GskVulkanPipeline * gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
GskVulkanPipelineType pipeline_type,
VkRenderPass render_pass);
static const GskVulkanOpClass GSK_VULKAN_SCISSOR_OP_CLASS = {
GSK_VULKAN_OP_SIZE (GskVulkanScissorOp),
+ NULL,
+ NULL,
gsk_vulkan_scissor_op_finish,
gsk_vulkan_scissor_op_upload,
gsk_vulkan_scissor_op_count_vertex_data,
#include "gskvulkantextureopprivate.h"
-#include "gskvulkantexturepipelineprivate.h"
+#include "vulkan/resources/texture.vert.h"
typedef struct _GskVulkanTextureOp GskVulkanTextureOp;
graphene_rect_t tex_rect;
guint32 image_descriptor;
- GskVulkanPipeline *pipeline;
gsize vertex_offset;
};
GskVulkanTextureOp *self = (GskVulkanTextureOp *) op;
gsize vertex_stride;
- vertex_stride = gsk_vulkan_pipeline_get_vertex_stride (self->pipeline);
+ vertex_stride = gsk_vulkan_texture_info.pVertexBindingDescriptions[0].stride;
n_bytes = round_up (n_bytes, vertex_stride);
self->vertex_offset = n_bytes;
n_bytes += vertex_stride;
guchar *data)
{
GskVulkanTextureOp *self = (GskVulkanTextureOp *) op;
-
- gsk_vulkan_texture_pipeline_collect_vertex_data (GSK_VULKAN_TEXTURE_PIPELINE (self->pipeline),
- data + self->vertex_offset,
- self->image_descriptor,
- graphene_point_zero (),
- &self->rect,
- &self->tex_rect);
+ GskVulkanTextureInstance *instance = (GskVulkanTextureInstance *) (data + self->vertex_offset);
+
+ instance->rect[0] = self->rect.origin.x;
+ instance->rect[1] = self->rect.origin.y;
+ instance->rect[2] = self->rect.size.width;
+ instance->rect[3] = self->rect.size.height;
+ instance->tex_rect[0] = self->tex_rect.origin.x;
+ instance->tex_rect[1] = self->tex_rect.origin.y;
+ instance->tex_rect[2] = self->tex_rect.size.width;
+ instance->tex_rect[3] = self->tex_rect.size.height;
+ instance->tex_id = self->image_descriptor;
}
static void
static VkPipeline
gsk_vulkan_texture_op_get_pipeline (GskVulkanOp *op)
{
- GskVulkanTextureOp *self = (GskVulkanTextureOp *) op;
-
- return gsk_vulkan_pipeline_get_pipeline (self->pipeline);
+ return VK_NULL_HANDLE;
}
static void
{
GskVulkanTextureOp *self = (GskVulkanTextureOp *) op;
- gsk_vulkan_texture_pipeline_draw (GSK_VULKAN_TEXTURE_PIPELINE (self->pipeline),
- command_buffer,
- self->vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (self->pipeline),
- 1);
+ vkCmdDraw (command_buffer,
+ 6, 1,
+ 0, self->vertex_offset / gsk_vulkan_texture_info.pVertexBindingDescriptions[0].stride);
}
static const GskVulkanOpClass GSK_VULKAN_TEXTURE_OP_CLASS = {
GSK_VULKAN_OP_SIZE (GskVulkanTextureOp),
+ "texture",
+ &gsk_vulkan_texture_info,
gsk_vulkan_texture_op_finish,
gsk_vulkan_texture_op_upload,
gsk_vulkan_texture_op_count_vertex_data,
void
gsk_vulkan_texture_op (GskVulkanRenderPass *render_pass,
- GskVulkanPipeline *pipeline,
+ const char *clip_type,
GskVulkanImage *image,
GskVulkanRenderSampler sampler,
const graphene_rect_t *rect,
self = (GskVulkanTextureOp *) gsk_vulkan_op_alloc (render_pass, &GSK_VULKAN_TEXTURE_OP_CLASS);
- self->pipeline = pipeline;
+ ((GskVulkanOp *) self)->clip_type = g_intern_string (clip_type);
self->image = g_object_ref (image);
self->sampler = sampler;
graphene_rect_offset_r (rect, offset->x, offset->y, &self->rect);
G_BEGIN_DECLS
void gsk_vulkan_texture_op (GskVulkanRenderPass *render_pass,
- GskVulkanPipeline *pipeline,
+ const char *clip_type,
GskVulkanImage *image,
GskVulkanRenderSampler sampler,
const graphene_rect_t *rect,
+++ /dev/null
-#include "config.h"
-
-#include "gskvulkantexturepipelineprivate.h"
-
-#include "vulkan/resources/texture.vert.h"
-
-struct _GskVulkanTexturePipeline
-{
- GObject parent_instance;
-};
-
-G_DEFINE_TYPE (GskVulkanTexturePipeline, gsk_vulkan_texture_pipeline, GSK_TYPE_VULKAN_PIPELINE)
-
-static const VkPipelineVertexInputStateCreateInfo *
-gsk_vulkan_texture_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
-{
- return &gsk_vulkan_texture_info;
-}
-
-static void
-gsk_vulkan_texture_pipeline_finalize (GObject *gobject)
-{
- //GskVulkanTexturePipeline *self = GSK_VULKAN_TEXTURE_PIPELINE (gobject);
-
- G_OBJECT_CLASS (gsk_vulkan_texture_pipeline_parent_class)->finalize (gobject);
-}
-
-static void
-gsk_vulkan_texture_pipeline_class_init (GskVulkanTexturePipelineClass *klass)
-{
- GskVulkanPipelineClass *pipeline_class = GSK_VULKAN_PIPELINE_CLASS (klass);
-
- G_OBJECT_CLASS (klass)->finalize = gsk_vulkan_texture_pipeline_finalize;
-
- pipeline_class->get_input_state_create_info = gsk_vulkan_texture_pipeline_get_input_state_create_info;
-}
-
-static void
-gsk_vulkan_texture_pipeline_init (GskVulkanTexturePipeline *self)
-{
-}
-
-GskVulkanPipeline *
-gsk_vulkan_texture_pipeline_new (GdkVulkanContext *context,
- VkPipelineLayout layout,
- const char *shader_name,
- VkRenderPass render_pass)
-{
- return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_TEXTURE_PIPELINE, context, layout, shader_name, render_pass);
-}
-
-void
-gsk_vulkan_texture_pipeline_collect_vertex_data (GskVulkanTexturePipeline *pipeline,
- guchar *data,
- guint32 tex_id,
- const graphene_point_t *offset,
- const graphene_rect_t *rect,
- const graphene_rect_t *tex_rect)
-{
- GskVulkanTextureInstance *instance = (GskVulkanTextureInstance *) data;
-
- instance->rect[0] = rect->origin.x + offset->x;
- instance->rect[1] = rect->origin.y + offset->y;
- instance->rect[2] = rect->size.width;
- instance->rect[3] = rect->size.height;
- instance->tex_rect[0] = tex_rect->origin.x;
- instance->tex_rect[1] = tex_rect->origin.y;
- instance->tex_rect[2] = tex_rect->size.width;
- instance->tex_rect[3] = tex_rect->size.height;
- instance->tex_id = tex_id;
-}
-
-gsize
-gsk_vulkan_texture_pipeline_draw (GskVulkanTexturePipeline *pipeline,
- VkCommandBuffer command_buffer,
- gsize offset,
- gsize n_commands)
-{
- vkCmdDraw (command_buffer,
- 6, n_commands,
- 0, offset);
-
- return n_commands;
-}
+++ /dev/null
-#pragma once
-
-#include <graphene.h>
-
-#include "gskvulkanpipelineprivate.h"
-
-G_BEGIN_DECLS
-
-typedef struct _GskVulkanTexturePipelineLayout GskVulkanTexturePipelineLayout;
-
-#define GSK_TYPE_VULKAN_TEXTURE_PIPELINE (gsk_vulkan_texture_pipeline_get_type ())
-
-G_DECLARE_FINAL_TYPE (GskVulkanTexturePipeline, gsk_vulkan_texture_pipeline, GSK, VULKAN_TEXTURE_PIPELINE, GskVulkanPipeline)
-
-GskVulkanPipeline * gsk_vulkan_texture_pipeline_new (GdkVulkanContext *context,
- VkPipelineLayout layout,
- const char *shader_name,
- VkRenderPass render_pass);
-
-void gsk_vulkan_texture_pipeline_collect_vertex_data (GskVulkanTexturePipeline *pipeline,
- guchar *data,
- guint32 tex_id,
- const graphene_point_t *offset,
- const graphene_rect_t *rect,
- const graphene_rect_t *tex_rect);
-gsize gsk_vulkan_texture_pipeline_draw (GskVulkanTexturePipeline *pipeline,
- VkCommandBuffer command_buffer,
- gsize offset,
- gsize n_commands);
-
-G_END_DECLS
-
static const GskVulkanOpClass GSK_VULKAN_UPLOAD_CAIRO_OP_CLASS = {
GSK_VULKAN_OP_SIZE (GskVulkanUploadCairoOp),
+ NULL,
+ NULL,
gsk_vulkan_upload_cairo_op_finish,
gsk_vulkan_upload_cairo_op_upload,
gsk_vulkan_upload_cairo_op_count_vertex_data,
static const GskVulkanOpClass GSK_VULKAN_UPLOAD_OP_CLASS = {
GSK_VULKAN_OP_SIZE (GskVulkanUploadOp),
+ NULL,
+ NULL,
gsk_vulkan_upload_op_finish,
gsk_vulkan_upload_op_upload,
gsk_vulkan_upload_op_count_vertex_data,