diff --git a/gsk/gpu/gskglframe.c b/gsk/gpu/gskglframe.c index c69cbee08f..99d340899f 100644 --- a/gsk/gpu/gskglframe.c +++ b/gsk/gpu/gskglframe.c @@ -160,6 +160,15 @@ gsk_gl_frame_create_storage_buffer (GskGpuFrame *frame, return gsk_gl_copied_buffer_new (GL_UNIFORM_BUFFER, size); } +static void +gsk_gl_frame_write_texture_vertex_data (GskGpuFrame *self, + guchar *data, + GskGpuImage **images, + GskGpuSampler *samplers, + gsize n_images) +{ +} + static void gsk_gl_frame_submit (GskGpuFrame *frame, GskRenderPassType pass_type, @@ -218,6 +227,7 @@ gsk_gl_frame_class_init (GskGLFrameClass *klass) gpu_frame_class->create_descriptors = gsk_gl_frame_create_descriptors; gpu_frame_class->create_vertex_buffer = gsk_gl_frame_create_vertex_buffer; gpu_frame_class->create_storage_buffer = gsk_gl_frame_create_storage_buffer; + gpu_frame_class->write_texture_vertex_data = gsk_gl_frame_write_texture_vertex_data; gpu_frame_class->submit = gsk_gl_frame_submit; object_class->finalize = gsk_gl_frame_finalize; diff --git a/gsk/gpu/gskgpuframe.c b/gsk/gpu/gskgpuframe.c index f7ed1083fc..0aa3e8eaf2 100644 --- a/gsk/gpu/gskgpuframe.c +++ b/gsk/gpu/gskgpuframe.c @@ -37,6 +37,7 @@ struct _GskGpuFramePrivate GskGpuRenderer *renderer; GskGpuDevice *device; GskGpuOptimizations optimizations; + gsize texture_vertex_size; gint64 timestamp; GskGpuOps ops; @@ -175,6 +176,28 @@ gsk_gpu_frame_setup (GskGpuFrame *self, GSK_GPU_FRAME_GET_CLASS (self)->setup (self); } +/* + * gsk_gpu_frame_set_texture_vertex_size: + * @self: the frame + * @texture_vertex_size: bytes to reserve in the vertex data per + * texture rendered + * + * Some renderers want to attach vertex data for textures, usually + * for supporting bindless textures. This is the number of bytes + * reserved per texture. + * + * GskGpuFrameClass::write_texture_vertex_data() is used to write that + * data. + **/ +void +gsk_gpu_frame_set_texture_vertex_size (GskGpuFrame *self, + gsize texture_vertex_size) +{ + GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self); + + priv->texture_vertex_size = texture_vertex_size; +} + void gsk_gpu_frame_begin (GskGpuFrame *self, GdkDrawContext *context, @@ -476,6 +499,15 @@ round_up (gsize number, gsize divisor) return (number + divisor - 1) / divisor * divisor; } +gsize +gsk_gpu_frame_get_texture_vertex_size (GskGpuFrame *self, + gsize n_textures) +{ + GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self); + + return priv->texture_vertex_size * n_textures; +} + gsize gsk_gpu_frame_reserve_vertex_data (GskGpuFrame *self, gsize size) @@ -535,6 +567,16 @@ gsk_gpu_frame_ensure_storage_buffer (GskGpuFrame *self) priv->storage_buffer_data = gsk_gpu_buffer_map (priv->storage_buffer); } +void +gsk_gpu_frame_write_texture_vertex_data (GskGpuFrame *self, + guchar *data, + GskGpuImage **images, + GskGpuSampler *samplers, + gsize n_images) +{ + GSK_GPU_FRAME_GET_CLASS (self)->write_texture_vertex_data (self, data, images, samplers, n_images); +} + GskGpuBuffer * gsk_gpu_frame_write_storage_buffer (GskGpuFrame *self, const guchar *data, diff --git a/gsk/gpu/gskgpuframeprivate.h b/gsk/gpu/gskgpuframeprivate.h index 9d120d68cf..10be903a77 100644 --- a/gsk/gpu/gskgpuframeprivate.h +++ b/gsk/gpu/gskgpuframeprivate.h @@ -41,6 +41,11 @@ struct _GskGpuFrameClass gsize size); GskGpuBuffer * (* create_storage_buffer) (GskGpuFrame *self, gsize size); + void (* write_texture_vertex_data) (GskGpuFrame *self, + guchar *data, + GskGpuImage **images, + GskGpuSampler *samplers, + gsize n_images); void (* submit) (GskGpuFrame *self, GskRenderPassType pass_type, GskGpuBuffer *vertex_buffer, @@ -54,6 +59,10 @@ void gsk_gpu_frame_setup (GskGpuF GskGpuRenderer *renderer, GskGpuDevice *device, GskGpuOptimizations optimizations); +void gsk_gpu_frame_set_texture_vertex_size (GskGpuFrame *self, + gsize texture_vertex_size); +gsize gsk_gpu_frame_get_texture_vertex_size (GskGpuFrame *self, + gsize n_textures); void gsk_gpu_frame_begin (GskGpuFrame *self, GdkDrawContext *context, @@ -78,6 +87,11 @@ gsize gsk_gpu_frame_reserve_vertex_data (GskGpuF gsize size); guchar * gsk_gpu_frame_get_vertex_data (GskGpuFrame *self, gsize offset); +void gsk_gpu_frame_write_texture_vertex_data (GskGpuFrame *self, + guchar *data, + GskGpuImage **images, + GskGpuSampler *samplers, + gsize n_images); GskGpuBuffer * gsk_gpu_frame_write_storage_buffer (GskGpuFrame *self, const guchar *data, gsize size, diff --git a/gsk/gpu/gskgpushaderop.c b/gsk/gpu/gskgpushaderop.c index 599f7a20da..d927fe7e6a 100644 --- a/gsk/gpu/gskgpushaderop.c +++ b/gsk/gpu/gskgpushaderop.c @@ -248,9 +248,19 @@ gsk_gpu_shader_op_alloc (GskGpuFrame *frame, { GskGpuOp *last; GskGpuShaderOp *last_shader; - gsize i, vertex_offset; + gsize i, vertex_offset, vertex_size, texture_vertex_size; + guchar *vertex_data; - vertex_offset = gsk_gpu_frame_reserve_vertex_data (frame, op_class->vertex_size); + texture_vertex_size = gsk_gpu_frame_get_texture_vertex_size (frame, op_class->n_textures); + vertex_size = texture_vertex_size + op_class->vertex_size; + vertex_offset = gsk_gpu_frame_reserve_vertex_data (frame, vertex_size); + vertex_data = gsk_gpu_frame_get_vertex_data (frame, vertex_offset); + + gsk_gpu_frame_write_texture_vertex_data (frame, + vertex_data, + images, + samplers, + op_class->n_textures); last = gsk_gpu_frame_get_last_op (frame); /* careful: We're casting without checking, but the if() does the check */ @@ -260,7 +270,7 @@ gsk_gpu_shader_op_alloc (GskGpuFrame *frame, last_shader->color_states == color_states && last_shader->variation == variation && last_shader->clip == clip && - last_shader->vertex_offset + last_shader->n_ops * op_class->vertex_size == vertex_offset && + last_shader->vertex_offset + last_shader->n_ops * vertex_size == vertex_offset && (op_class->n_textures < 1 || (last_shader->images[0] == images[0] && last_shader->samplers[0] == samplers[0])) && (op_class->n_textures < 2 || (last_shader->images[1] == images[1] && last_shader->samplers[1] == samplers[1]))) { @@ -287,6 +297,6 @@ gsk_gpu_shader_op_alloc (GskGpuFrame *frame, } } - *((gpointer *) out_vertex_data) = gsk_gpu_frame_get_vertex_data (frame, vertex_offset); + *((gpointer *) out_vertex_data) = vertex_data + texture_vertex_size; } diff --git a/gsk/gpu/gskvulkanframe.c b/gsk/gpu/gskvulkanframe.c index ce75043350..20bf03a647 100644 --- a/gsk/gpu/gskvulkanframe.c +++ b/gsk/gpu/gskvulkanframe.c @@ -355,6 +355,15 @@ gsk_vulkan_frame_create_storage_buffer (GskGpuFrame *frame, return gsk_vulkan_buffer_new_storage (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), size); } +static void +gsk_vulkan_frame_write_texture_vertex_data (GskGpuFrame *self, + guchar *data, + GskGpuImage **images, + GskGpuSampler *samplers, + gsize n_images) +{ +} + static void gsk_vulkan_frame_submit (GskGpuFrame *frame, GskRenderPassType pass_type, @@ -481,6 +490,7 @@ gsk_vulkan_frame_class_init (GskVulkanFrameClass *klass) gpu_frame_class->create_descriptors = gsk_vulkan_frame_create_descriptors; gpu_frame_class->create_vertex_buffer = gsk_vulkan_frame_create_vertex_buffer; gpu_frame_class->create_storage_buffer = gsk_vulkan_frame_create_storage_buffer; + gpu_frame_class->write_texture_vertex_data = gsk_vulkan_frame_write_texture_vertex_data; gpu_frame_class->submit = gsk_vulkan_frame_submit; object_class->finalize = gsk_vulkan_frame_finalize;