Merge branch 'wip/otte/global-globals' into 'main'
ngl: Use a single buffer for globals See merge request GNOME/gtk!7753
This commit is contained in:
@@ -63,10 +63,16 @@ gsk_gl_buffer_bind (GskGLBuffer *self)
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_buffer_bind_base (GskGLBuffer *self,
|
||||
GLuint index)
|
||||
gsk_gl_buffer_bind_range (GskGLBuffer *self,
|
||||
GLuint index,
|
||||
GLintptr offset,
|
||||
GLsizeiptr size)
|
||||
{
|
||||
glBindBufferBase (self->target, index, self->buffer_id);
|
||||
glBindBufferRange (self->target,
|
||||
index,
|
||||
self->buffer_id,
|
||||
offset,
|
||||
size);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -20,8 +20,10 @@ GskGpuBuffer * gsk_gl_copied_buffer_new (GLenum
|
||||
gsize size);
|
||||
|
||||
void gsk_gl_buffer_bind (GskGLBuffer *self);
|
||||
void gsk_gl_buffer_bind_base (GskGLBuffer *self,
|
||||
GLuint index);
|
||||
void gsk_gl_buffer_bind_range (GskGLBuffer *self,
|
||||
GLuint index,
|
||||
GLintptr offset,
|
||||
GLsizeiptr size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ struct _GskGLFrame
|
||||
{
|
||||
GskGpuFrame parent_instance;
|
||||
|
||||
GLuint globals_buffer_id;
|
||||
guint next_texture_slot;
|
||||
GLsync sync;
|
||||
|
||||
@@ -142,6 +141,17 @@ gsk_gl_frame_create_vertex_buffer (GskGpuFrame *frame,
|
||||
return gsk_gl_copied_buffer_new (GL_ARRAY_BUFFER, size);
|
||||
}
|
||||
|
||||
static GskGpuBuffer *
|
||||
gsk_gl_frame_create_globals_buffer (GskGpuFrame *frame,
|
||||
gsize size)
|
||||
{
|
||||
if (gdk_gl_context_has_feature (GDK_GL_CONTEXT (gsk_gpu_frame_get_context (frame)),
|
||||
GDK_GL_FEATURE_BUFFER_STORAGE))
|
||||
return gsk_gl_mapped_buffer_new (GL_UNIFORM_BUFFER, size);
|
||||
else
|
||||
return gsk_gl_copied_buffer_new (GL_UNIFORM_BUFFER, size);
|
||||
}
|
||||
|
||||
static GskGpuBuffer *
|
||||
gsk_gl_frame_create_storage_buffer (GskGpuFrame *frame,
|
||||
gsize size)
|
||||
@@ -166,12 +176,14 @@ static void
|
||||
gsk_gl_frame_submit (GskGpuFrame *frame,
|
||||
GskRenderPassType pass_type,
|
||||
GskGpuBuffer *vertex_buffer,
|
||||
GskGpuBuffer *globals_buffer,
|
||||
GskGpuOp *op)
|
||||
{
|
||||
GskGLFrame *self = GSK_GL_FRAME (frame);
|
||||
GskGLCommandState state = {
|
||||
/* rest is 0 */
|
||||
.current_samplers = { GSK_GPU_SAMPLER_N_SAMPLERS, GSK_GPU_SAMPLER_N_SAMPLERS }
|
||||
.current_samplers = { GSK_GPU_SAMPLER_N_SAMPLERS, GSK_GPU_SAMPLER_N_SAMPLERS },
|
||||
.globals = globals_buffer,
|
||||
};
|
||||
|
||||
glEnable (GL_SCISSOR_TEST);
|
||||
@@ -182,12 +194,6 @@ gsk_gl_frame_submit (GskGpuFrame *frame,
|
||||
if (vertex_buffer)
|
||||
gsk_gl_buffer_bind (GSK_GL_BUFFER (vertex_buffer));
|
||||
|
||||
gsk_gl_frame_bind_globals (self);
|
||||
glBufferData (GL_UNIFORM_BUFFER,
|
||||
sizeof (GskGpuGlobalsInstance),
|
||||
NULL,
|
||||
GL_STREAM_DRAW);
|
||||
|
||||
while (op)
|
||||
{
|
||||
op = gsk_gpu_op_gl_command (op, frame, &state);
|
||||
@@ -202,8 +208,6 @@ gsk_gl_frame_finalize (GObject *object)
|
||||
GskGLFrame *self = GSK_GL_FRAME (object);
|
||||
|
||||
g_hash_table_unref (self->vaos);
|
||||
if (self->globals_buffer_id != 0)
|
||||
glDeleteBuffers (1, &self->globals_buffer_id);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gl_frame_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -219,6 +223,7 @@ gsk_gl_frame_class_init (GskGLFrameClass *klass)
|
||||
gpu_frame_class->cleanup = gsk_gl_frame_cleanup;
|
||||
gpu_frame_class->upload_texture = gsk_gl_frame_upload_texture;
|
||||
gpu_frame_class->create_vertex_buffer = gsk_gl_frame_create_vertex_buffer;
|
||||
gpu_frame_class->create_globals_buffer = gsk_gl_frame_create_globals_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;
|
||||
@@ -266,12 +271,3 @@ gsk_gl_frame_use_program (GskGLFrame *self,
|
||||
g_hash_table_insert (self->vaos, (gpointer) op_class, GUINT_TO_POINTER (vao));
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_frame_bind_globals (GskGLFrame *self)
|
||||
{
|
||||
if (self->globals_buffer_id == 0)
|
||||
glGenBuffers (1, &self->globals_buffer_id);
|
||||
|
||||
glBindBufferBase (GL_UNIFORM_BUFFER, 0, self->globals_buffer_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,4 @@ void gsk_gl_frame_use_program (GskGLFr
|
||||
GskGpuColorStates color_states,
|
||||
guint32 variation);
|
||||
|
||||
void gsk_gl_frame_bind_globals (GskGLFrame *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "gskgpucacheprivate.h"
|
||||
#include "gskgpudeviceprivate.h"
|
||||
#include "gskgpudownloadopprivate.h"
|
||||
#include "gskgpuglobalsopprivate.h"
|
||||
#include "gskgpuimageprivate.h"
|
||||
#include "gskgpunodeprocessorprivate.h"
|
||||
#include "gskgpuopprivate.h"
|
||||
@@ -24,6 +25,8 @@
|
||||
/* GL_MAX_UNIFORM_BLOCK_SIZE is at 16384 */
|
||||
#define DEFAULT_STORAGE_BUFFER_SIZE 16 * 1024 * 64
|
||||
|
||||
#define DEFAULT_N_GLOBALS (16384 / sizeof (GskGpuGlobalsInstance))
|
||||
|
||||
#define GDK_ARRAY_NAME gsk_gpu_ops
|
||||
#define GDK_ARRAY_TYPE_NAME GskGpuOps
|
||||
#define GDK_ARRAY_ELEMENT_TYPE guchar
|
||||
@@ -47,6 +50,9 @@ struct _GskGpuFramePrivate
|
||||
GskGpuBuffer *vertex_buffer;
|
||||
guchar *vertex_buffer_data;
|
||||
gsize vertex_buffer_used;
|
||||
GskGpuBuffer *globals_buffer;
|
||||
GskGpuGlobalsInstance *globals_buffer_data;
|
||||
gsize n_globals;
|
||||
GskGpuBuffer *storage_buffer;
|
||||
guchar *storage_buffer_data;
|
||||
gsize storage_buffer_used;
|
||||
@@ -66,6 +72,8 @@ gsk_gpu_frame_default_cleanup (GskGpuFrame *self)
|
||||
GskGpuOp *op;
|
||||
gsize i;
|
||||
|
||||
priv->n_globals = 0;
|
||||
|
||||
for (i = 0; i < gsk_gpu_ops_get_size (&priv->ops); i += op->op_class->size)
|
||||
{
|
||||
op = (GskGpuOp *) gsk_gpu_ops_index (&priv->ops, i);
|
||||
@@ -139,6 +147,7 @@ gsk_gpu_frame_finalize (GObject *object)
|
||||
gsk_gpu_ops_clear (&priv->ops);
|
||||
|
||||
g_clear_object (&priv->vertex_buffer);
|
||||
g_clear_object (&priv->globals_buffer);
|
||||
g_clear_object (&priv->storage_buffer);
|
||||
|
||||
g_object_unref (priv->device);
|
||||
@@ -505,6 +514,13 @@ gsk_gpu_frame_create_vertex_buffer (GskGpuFrame *self,
|
||||
return GSK_GPU_FRAME_GET_CLASS (self)->create_vertex_buffer (self, size);
|
||||
}
|
||||
|
||||
static GskGpuBuffer *
|
||||
gsk_gpu_frame_create_globals_buffer (GskGpuFrame *self,
|
||||
gsize size)
|
||||
{
|
||||
return GSK_GPU_FRAME_GET_CLASS (self)->create_globals_buffer (self, size);
|
||||
}
|
||||
|
||||
static GskGpuBuffer *
|
||||
gsk_gpu_frame_create_storage_buffer (GskGpuFrame *self,
|
||||
gsize size)
|
||||
@@ -560,6 +576,48 @@ gsk_gpu_frame_reserve_vertex_data (GskGpuFrame *self,
|
||||
return size_needed - size;
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_gpu_frame_add_globals (GskGpuFrame *self,
|
||||
const GskGpuGlobalsInstance *globals)
|
||||
{
|
||||
GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self);
|
||||
gsize size_needed, result;
|
||||
|
||||
if (priv->globals_buffer == NULL)
|
||||
{
|
||||
priv->globals_buffer = gsk_gpu_frame_create_globals_buffer (self, sizeof (GskGpuGlobalsInstance) * DEFAULT_N_GLOBALS);
|
||||
if (priv->globals_buffer == NULL)
|
||||
return 0;
|
||||
}
|
||||
if (priv->globals_buffer_data == NULL)
|
||||
priv->globals_buffer_data = (GskGpuGlobalsInstance *) gsk_gpu_buffer_map (priv->globals_buffer);
|
||||
|
||||
size_needed = sizeof (GskGpuGlobalsInstance) * (priv->n_globals + 1);
|
||||
|
||||
if (gsk_gpu_buffer_get_size (priv->globals_buffer) < size_needed)
|
||||
{
|
||||
gsize old_size = gsk_gpu_buffer_get_size (priv->globals_buffer);
|
||||
GskGpuBuffer *new_buffer = gsk_gpu_frame_create_globals_buffer (self, old_size * 2);
|
||||
GskGpuGlobalsInstance *new_data = (GskGpuGlobalsInstance *) gsk_gpu_buffer_map (new_buffer);
|
||||
|
||||
if (priv->globals_buffer_data)
|
||||
{
|
||||
memcpy (new_data, priv->globals_buffer_data, old_size);
|
||||
gsk_gpu_buffer_unmap (priv->globals_buffer, old_size);
|
||||
}
|
||||
g_object_unref (priv->globals_buffer);
|
||||
priv->globals_buffer = new_buffer;
|
||||
priv->globals_buffer_data = new_data;
|
||||
}
|
||||
|
||||
result = priv->n_globals;
|
||||
|
||||
priv->globals_buffer_data[priv->n_globals] = *globals;
|
||||
priv->n_globals++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
guchar *
|
||||
gsk_gpu_frame_get_vertex_data (GskGpuFrame *self,
|
||||
gsize offset)
|
||||
@@ -691,6 +749,12 @@ gsk_gpu_frame_submit (GskGpuFrame *self,
|
||||
priv->vertex_buffer_used = 0;
|
||||
}
|
||||
|
||||
if (priv->globals_buffer)
|
||||
{
|
||||
gsk_gpu_buffer_unmap (priv->globals_buffer, sizeof (GskGpuGlobalsInstance) * priv->n_globals);
|
||||
priv->globals_buffer_data = NULL;
|
||||
}
|
||||
|
||||
if (priv->storage_buffer_data)
|
||||
{
|
||||
gsk_gpu_buffer_unmap (priv->storage_buffer, priv->storage_buffer_used);
|
||||
@@ -701,6 +765,7 @@ gsk_gpu_frame_submit (GskGpuFrame *self,
|
||||
GSK_GPU_FRAME_GET_CLASS (self)->submit (self,
|
||||
pass_type,
|
||||
priv->vertex_buffer,
|
||||
priv->globals_buffer,
|
||||
priv->first_op);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ struct _GskGpuFrameClass
|
||||
GdkTexture *texture);
|
||||
GskGpuBuffer * (* create_vertex_buffer) (GskGpuFrame *self,
|
||||
gsize size);
|
||||
GskGpuBuffer * (* create_globals_buffer) (GskGpuFrame *self,
|
||||
gsize size);
|
||||
GskGpuBuffer * (* create_storage_buffer) (GskGpuFrame *self,
|
||||
gsize size);
|
||||
void (* write_texture_vertex_data) (GskGpuFrame *self,
|
||||
@@ -49,6 +51,7 @@ struct _GskGpuFrameClass
|
||||
void (* submit) (GskGpuFrame *self,
|
||||
GskRenderPassType pass_type,
|
||||
GskGpuBuffer *vertex_buffer,
|
||||
GskGpuBuffer *globals_buffer,
|
||||
GskGpuOp *op);
|
||||
};
|
||||
|
||||
@@ -92,6 +95,8 @@ void gsk_gpu_frame_write_texture_vertex_data (GskGpuF
|
||||
GskGpuImage **images,
|
||||
GskGpuSampler *samplers,
|
||||
gsize n_images);
|
||||
gsize gsk_gpu_frame_add_globals (GskGpuFrame *self,
|
||||
const GskGpuGlobalsInstance *globals);
|
||||
GskGpuBuffer * gsk_gpu_frame_write_storage_buffer (GskGpuFrame *self,
|
||||
const guchar *data,
|
||||
gsize size,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "gskgpuglobalsopprivate.h"
|
||||
|
||||
#include "gskglframeprivate.h"
|
||||
#include "gskglbufferprivate.h"
|
||||
#include "gskgpuframeprivate.h"
|
||||
#include "gskgpuprintprivate.h"
|
||||
#include "gskroundedrectprivate.h"
|
||||
@@ -17,6 +17,7 @@ struct _GskGpuGlobalsOp
|
||||
{
|
||||
GskGpuOp op;
|
||||
|
||||
gsize id;
|
||||
GskGpuGlobalsInstance instance;
|
||||
};
|
||||
|
||||
@@ -67,13 +68,10 @@ gsk_gpu_globals_op_gl_command (GskGpuOp *op,
|
||||
{
|
||||
GskGpuGlobalsOp *self = (GskGpuGlobalsOp *) op;
|
||||
|
||||
gsk_gl_frame_bind_globals (GSK_GL_FRAME (frame));
|
||||
|
||||
/* FIXME: Does it matter if we glBufferData() or glSubBufferData() here? */
|
||||
glBufferSubData (GL_UNIFORM_BUFFER,
|
||||
0,
|
||||
sizeof (self->instance),
|
||||
&self->instance);
|
||||
gsk_gl_buffer_bind_range (GSK_GL_BUFFER (state->globals),
|
||||
0,
|
||||
self->id * sizeof (GskGpuGlobalsInstance),
|
||||
sizeof (GskGpuGlobalsInstance));
|
||||
|
||||
return op->next;
|
||||
}
|
||||
@@ -102,4 +100,5 @@ gsk_gpu_globals_op (GskGpuFrame *frame,
|
||||
graphene_matrix_to_float (mvp, self->instance.mvp);
|
||||
gsk_rounded_rect_to_float (clip, graphene_point_zero (), self->instance.clip);
|
||||
graphene_vec2_to_float (scale, self->instance.scale);
|
||||
self->id = gsk_gpu_frame_add_globals (frame, &self->instance);
|
||||
}
|
||||
|
||||
@@ -7,15 +7,17 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskGpuGlobalsInstance GskGpuGlobalsInstance;
|
||||
|
||||
struct _GskGpuGlobalsInstance
|
||||
{
|
||||
float mvp[16];
|
||||
float clip[12];
|
||||
float scale[2];
|
||||
float padding[2];
|
||||
};
|
||||
|
||||
/* GPUs often want 32bit alignment */
|
||||
G_STATIC_ASSERT (sizeof (GskGpuGlobalsInstance) % 32 == 0);
|
||||
|
||||
void gsk_gpu_globals_op (GskGpuFrame *frame,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_matrix_t *mvp,
|
||||
|
||||
@@ -29,6 +29,7 @@ struct _GskGLCommandState
|
||||
GskGpuColorStates color_states;
|
||||
guint32 variation;
|
||||
} current_program;
|
||||
GskGpuBuffer *globals;
|
||||
GskGpuImage *current_images[2];
|
||||
GskGpuSampler current_samplers[2];
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@ typedef struct _GskGpuClip GskGpuClip;
|
||||
typedef guint32 GskGpuColorStates;
|
||||
typedef struct _GskGpuDevice GskGpuDevice;
|
||||
typedef struct _GskGpuFrame GskGpuFrame;
|
||||
typedef struct _GskGpuGlobalsInstance GskGpuGlobalsInstance;
|
||||
typedef struct _GskGpuImage GskGpuImage;
|
||||
typedef struct _GskGpuOp GskGpuOp;
|
||||
typedef struct _GskGpuOpClass GskGpuOpClass;
|
||||
|
||||
@@ -229,6 +229,13 @@ gsk_vulkan_frame_create_vertex_buffer (GskGpuFrame *frame,
|
||||
return gsk_vulkan_buffer_new_vertex (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), size);
|
||||
}
|
||||
|
||||
static GskGpuBuffer *
|
||||
gsk_vulkan_frame_create_globals_buffer (GskGpuFrame *frame,
|
||||
gsize size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GskGpuBuffer *
|
||||
gsk_vulkan_frame_create_storage_buffer (GskGpuFrame *frame,
|
||||
gsize size)
|
||||
@@ -249,6 +256,7 @@ static void
|
||||
gsk_vulkan_frame_submit (GskGpuFrame *frame,
|
||||
GskRenderPassType pass_type,
|
||||
GskGpuBuffer *vertex_buffer,
|
||||
GskGpuBuffer *globals_buffer,
|
||||
GskGpuOp *op)
|
||||
{
|
||||
GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
|
||||
@@ -351,6 +359,7 @@ gsk_vulkan_frame_class_init (GskVulkanFrameClass *klass)
|
||||
gpu_frame_class->begin = gsk_vulkan_frame_begin;
|
||||
gpu_frame_class->upload_texture = gsk_vulkan_frame_upload_texture;
|
||||
gpu_frame_class->create_vertex_buffer = gsk_vulkan_frame_create_vertex_buffer;
|
||||
gpu_frame_class->create_globals_buffer = gsk_vulkan_frame_create_globals_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;
|
||||
|
||||
Reference in New Issue
Block a user