gpu: Add infrastructure to write texture vertex data

This allows GskGpuFrame implementations to store data per vertex
attribute.

This is just the plumbing, no actual implementation is done in this
commit.
This commit is contained in:
Benjamin Otte
2024-07-20 01:20:17 +02:00
parent 677b6c1a81
commit 163278af0d
5 changed files with 90 additions and 4 deletions

View File

@@ -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;

View File

@@ -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,

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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;