'vulkan/gskvulkanshader.c',
'vulkan/gskvulkantextpipeline.c',
'vulkan/gskvulkantexturepipeline.c',
+ 'vulkan/gskvulkantextureop.c',
+ 'vulkan/gskvulkanuploadop.c',
])
subdir('vulkan/resources')
{
return self->vk_format;
}
+
+GdkMemoryFormat
+gsk_vulkan_image_get_format (GskVulkanImage *self)
+{
+ return self->format;
+}
+
VkImage gsk_vulkan_image_get_image (GskVulkanImage *self);
VkImageView gsk_vulkan_image_get_image_view (GskVulkanImage *self);
VkFormat gsk_vulkan_image_get_vk_format (GskVulkanImage *self);
+GdkMemoryFormat gsk_vulkan_image_get_format (GskVulkanImage *self);
G_END_DECLS
#include "gskvulkaneffectpipelineprivate.h"
#include "gskvulkanlineargradientpipelineprivate.h"
#include "gskvulkanopprivate.h"
+#include "gskvulkanrendererprivate.h"
#include "gskvulkantextpipelineprivate.h"
#include "gskvulkantexturepipelineprivate.h"
#include "gskvulkanimageprivate.h"
#include "gskvulkanpushconstantsprivate.h"
#include "gskvulkanscissoropprivate.h"
-#include "gskvulkanrendererprivate.h"
+#include "gskvulkantextureopprivate.h"
+#include "gskvulkanuploadopprivate.h"
#include "gskprivate.h"
#include "gdk/gdkvulkancontextprivate.h"
GSK_VULKAN_OP_FALLBACK,
GSK_VULKAN_OP_FALLBACK_CLIP,
GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP,
- GSK_VULKAN_OP_TEXTURE,
GSK_VULKAN_OP_TEXTURE_SCALE,
GSK_VULKAN_OP_COLOR,
GSK_VULKAN_OP_LINEAR_GRADIENT,
GskRenderNode *node)
{
GskVulkanPipelineType pipeline_type;
- GskVulkanOpRender op = {
- .type = GSK_VULKAN_OP_TEXTURE,
- .node = node,
- .offset = state->offset,
- };
+ 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
pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP_ROUNDED;
- op.pipeline = gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type);
- gsk_vulkan_render_pass_add_op (self, (GskVulkanOp *) &op);
+ 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);
+ if (image == NULL)
+ {
+ image = gsk_vulkan_upload_op_init_texture (gsk_vulkan_render_pass_alloc_op (self, gsk_vulkan_upload_op_size ()),
+ self->vulkan,
+ texture);
+ gsk_vulkan_renderer_add_texture_image (renderer, texture, image);
+ }
+
+ gsk_vulkan_texture_op_init (gsk_vulkan_render_pass_alloc_op (self, gsk_vulkan_texture_op_size ()),
+ gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type),
+ image,
+ GSK_VULKAN_SAMPLER_DEFAULT,
+ &node->bounds,
+ &state->offset,
+ &GRAPHENE_RECT_INIT(0, 0, 1, 1));
return TRUE;
}
}
break;
- case GSK_VULKAN_OP_TEXTURE:
- {
- op->render.source = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)),
- gsk_texture_node_get_texture (op->render.node),
- uploader);
- op->render.source_rect = GRAPHENE_RECT_INIT(0, 0, 1, 1);
- gsk_vulkan_render_add_cleanup_image (render, op->render.source);
- }
- break;
-
case GSK_VULKAN_OP_TEXTURE_SCALE:
{
op->render.source = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)),
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_FALLBACK_CLIP:
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
- case GSK_VULKAN_OP_TEXTURE:
case GSK_VULKAN_OP_TEXTURE_SCALE:
case GSK_VULKAN_OP_REPEAT:
case GSK_VULKAN_OP_COLOR:
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_FALLBACK_CLIP:
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
- case GSK_VULKAN_OP_TEXTURE:
case GSK_VULKAN_OP_TEXTURE_SCALE:
gsk_vulkan_texture_pipeline_collect_vertex_data (GSK_VULKAN_TEXTURE_PIPELINE (op->render.pipeline),
data + op->render.vertex_offset,
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_FALLBACK_CLIP:
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
- case GSK_VULKAN_OP_TEXTURE:
case GSK_VULKAN_OP_OPACITY:
case GSK_VULKAN_OP_BLUR:
case GSK_VULKAN_OP_COLOR_MATRIX:
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_FALLBACK_CLIP:
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
- case GSK_VULKAN_OP_TEXTURE:
case GSK_VULKAN_OP_TEXTURE_SCALE:
case GSK_VULKAN_OP_REPEAT:
case GSK_VULKAN_OP_COLOR:
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_FALLBACK_CLIP:
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
- case GSK_VULKAN_OP_TEXTURE:
case GSK_VULKAN_OP_TEXTURE_SCALE:
case GSK_VULKAN_OP_REPEAT:
if (!op->render.source)
--- /dev/null
+#include "config.h"
+
+#include "gskvulkantextureopprivate.h"
+
+#include "gskvulkantexturepipelineprivate.h"
+
+typedef struct _GskVulkanTextureOp GskVulkanTextureOp;
+
+struct _GskVulkanTextureOp
+{
+ GskVulkanOp op;
+
+ GskVulkanImage *image;
+ GskVulkanRenderSampler sampler;
+ graphene_rect_t rect;
+ graphene_rect_t tex_rect;
+
+ guint32 image_descriptor;
+ guint32 sampler_descriptor;
+ GskVulkanPipeline *pipeline;
+ gsize vertex_offset;
+};
+
+static void
+gsk_vulkan_texture_op_finish (GskVulkanOp *op)
+{
+ GskVulkanTextureOp *self = (GskVulkanTextureOp *) op;
+
+ g_object_unref (self->image);
+}
+
+static void
+gsk_vulkan_texture_op_upload (GskVulkanOp *op,
+ GskVulkanRenderPass *pass,
+ GskVulkanRender *render,
+ GskVulkanUploader *uploader,
+ const graphene_rect_t *clip,
+ const graphene_vec2_t *scale)
+{
+}
+
+static inline gsize
+round_up (gsize number, gsize divisor)
+{
+ return (number + divisor - 1) / divisor * divisor;
+}
+
+static gsize
+gsk_vulkan_texture_op_count_vertex_data (GskVulkanOp *op,
+ gsize n_bytes)
+{
+ GskVulkanTextureOp *self = (GskVulkanTextureOp *) op;
+ gsize vertex_stride;
+
+ vertex_stride = gsk_vulkan_pipeline_get_vertex_stride (self->pipeline);
+ n_bytes = round_up (n_bytes, vertex_stride);
+ self->vertex_offset = n_bytes;
+ n_bytes += vertex_stride;
+ return n_bytes;
+}
+
+static void
+gsk_vulkan_texture_op_collect_vertex_data (GskVulkanOp *op,
+ GskVulkanRenderPass *pass,
+ GskVulkanRender *render,
+ guchar *data)
+{
+ GskVulkanTextureOp *self = (GskVulkanTextureOp *) op;
+
+ gsk_vulkan_texture_pipeline_collect_vertex_data (GSK_VULKAN_TEXTURE_PIPELINE (self->pipeline),
+ data + self->vertex_offset,
+ (guint32[2]) {
+ self->image_descriptor,
+ self->sampler_descriptor,
+ },
+ graphene_point_zero (),
+ &self->rect,
+ &self->tex_rect);
+}
+
+static void
+gsk_vulkan_texture_op_reserve_descriptor_sets (GskVulkanOp *op,
+ GskVulkanRender *render)
+{
+ GskVulkanTextureOp *self = (GskVulkanTextureOp *) op;
+
+ self->image_descriptor = gsk_vulkan_render_get_image_descriptor (render, self->image);
+ self->sampler_descriptor = gsk_vulkan_render_get_sampler_descriptor (render, self->sampler);
+}
+
+static GskVulkanPipeline *
+gsk_vulkan_texture_op_get_pipeline (GskVulkanOp *op)
+{
+ GskVulkanTextureOp *self = (GskVulkanTextureOp *) op;
+
+ return self->pipeline;
+}
+
+static void
+gsk_vulkan_texture_op_command (GskVulkanOp *op,
+ VkPipelineLayout pipeline_layout,
+ VkCommandBuffer command_buffer)
+{
+ 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);
+}
+
+static const GskVulkanOpClass GSK_VULKAN_TEXTURE_OP_CLASS = {
+ GSK_VULKAN_OP_SIZE (GskVulkanTextureOp),
+ gsk_vulkan_texture_op_finish,
+ gsk_vulkan_texture_op_upload,
+ gsk_vulkan_texture_op_count_vertex_data,
+ gsk_vulkan_texture_op_collect_vertex_data,
+ gsk_vulkan_texture_op_reserve_descriptor_sets,
+ gsk_vulkan_texture_op_get_pipeline,
+ gsk_vulkan_texture_op_command
+};
+
+gsize
+gsk_vulkan_texture_op_size (void)
+{
+ return GSK_VULKAN_TEXTURE_OP_CLASS.size;
+}
+
+void
+gsk_vulkan_texture_op_init (GskVulkanOp *op,
+ GskVulkanPipeline *pipeline,
+ GskVulkanImage *image,
+ GskVulkanRenderSampler sampler,
+ const graphene_rect_t *rect,
+ const graphene_point_t *offset,
+ const graphene_rect_t *tex_rect)
+{
+ GskVulkanTextureOp *self = (GskVulkanTextureOp *) op;
+
+ gsk_vulkan_op_init (op, &GSK_VULKAN_TEXTURE_OP_CLASS);
+
+ self->pipeline = pipeline;
+ self->image = g_object_ref (image);
+ self->sampler = sampler;
+ graphene_rect_offset_r (rect, offset->x, offset->y, &self->rect);
+ self->tex_rect = *tex_rect;
+}
--- /dev/null
+#pragma once
+
+#include "gskvulkanopprivate.h"
+
+G_BEGIN_DECLS
+
+gsize gsk_vulkan_texture_op_size (void) G_GNUC_CONST;
+
+void gsk_vulkan_texture_op_init (GskVulkanOp *op,
+ GskVulkanPipeline *pipeline,
+ GskVulkanImage *image,
+ GskVulkanRenderSampler sampler,
+ const graphene_rect_t *rect,
+ const graphene_point_t *offset,
+ const graphene_rect_t *tex_rect);
+
+
+G_END_DECLS
+
--- /dev/null
+#include "config.h"
+
+#include "gskvulkanuploadopprivate.h"
+
+typedef struct _GskVulkanUploadOp GskVulkanUploadOp;
+
+struct _GskVulkanUploadOp
+{
+ GskVulkanOp op;
+
+ GskVulkanImage *image;
+ GdkTexture *texture;
+};
+
+static void
+gsk_vulkan_upload_op_finish (GskVulkanOp *op)
+{
+ GskVulkanUploadOp *self = (GskVulkanUploadOp *) op;
+
+ g_object_unref (self->image);
+ g_object_unref (self->texture);
+}
+
+static void
+gsk_vulkan_upload_op_upload (GskVulkanOp *op,
+ GskVulkanRenderPass *pass,
+ GskVulkanRender *render,
+ GskVulkanUploader *uploader,
+ const graphene_rect_t *clip,
+ const graphene_vec2_t *scale)
+{
+ GskVulkanUploadOp *self = (GskVulkanUploadOp *) op;
+ GdkTextureDownloader *downloader;
+ GskVulkanImageMap map;
+
+ downloader = gdk_texture_downloader_new (self->texture);
+ gdk_texture_downloader_set_format (downloader, gsk_vulkan_image_get_format (self->image));
+ gsk_vulkan_image_map_memory (self->image, uploader, GSK_VULKAN_WRITE, &map);
+ gdk_texture_downloader_download_into (downloader, map.data, map.stride);
+ gsk_vulkan_image_unmap_memory (self->image, uploader, &map);
+ gdk_texture_downloader_free (downloader);
+}
+
+static gsize
+gsk_vulkan_upload_op_count_vertex_data (GskVulkanOp *op,
+ gsize n_bytes)
+{
+ return n_bytes;
+}
+
+static void
+gsk_vulkan_upload_op_collect_vertex_data (GskVulkanOp *op,
+ GskVulkanRenderPass *pass,
+ GskVulkanRender *render,
+ guchar *data)
+{
+}
+
+static void
+gsk_vulkan_upload_op_reserve_descriptor_sets (GskVulkanOp *op,
+ GskVulkanRender *render)
+{
+}
+
+static GskVulkanPipeline *
+gsk_vulkan_upload_op_get_pipeline (GskVulkanOp *op)
+{
+ return NULL;
+}
+
+static void
+gsk_vulkan_upload_op_command (GskVulkanOp *op,
+ VkPipelineLayout pipeline_layout,
+ VkCommandBuffer command_buffer)
+{
+}
+
+static const GskVulkanOpClass GSK_VULKAN_UPLOAD_OP_CLASS = {
+ GSK_VULKAN_OP_SIZE (GskVulkanUploadOp),
+ gsk_vulkan_upload_op_finish,
+ gsk_vulkan_upload_op_upload,
+ gsk_vulkan_upload_op_count_vertex_data,
+ gsk_vulkan_upload_op_collect_vertex_data,
+ gsk_vulkan_upload_op_reserve_descriptor_sets,
+ gsk_vulkan_upload_op_get_pipeline,
+ gsk_vulkan_upload_op_command
+};
+
+gsize
+gsk_vulkan_upload_op_size (void)
+{
+ return GSK_VULKAN_UPLOAD_OP_CLASS.size;
+}
+
+GskVulkanImage *
+gsk_vulkan_upload_op_init_texture (GskVulkanOp *op,
+ GdkVulkanContext *context,
+ GdkTexture *texture)
+{
+ GskVulkanUploadOp *self = (GskVulkanUploadOp *) op;
+
+ gsk_vulkan_op_init (op, &GSK_VULKAN_UPLOAD_OP_CLASS);
+
+ self->texture = g_object_ref (texture);
+ self->image = gsk_vulkan_image_new_for_upload (context,
+ gdk_texture_get_format (texture),
+ gdk_texture_get_width (texture),
+ gdk_texture_get_height (texture));
+
+ return self->image;
+}
--- /dev/null
+#pragma once
+
+#include "gskvulkanopprivate.h"
+
+G_BEGIN_DECLS
+
+gsize gsk_vulkan_upload_op_size (void) G_GNUC_CONST;
+
+GskVulkanImage * gsk_vulkan_upload_op_init_texture (GskVulkanOp *op,
+ GdkVulkanContext *context,
+ GdkTexture *texture);
+
+
+G_END_DECLS
+