Compare commits

...

3 Commits

Author SHA1 Message Date
Matthias Clasen
b883504f8c Use glMapBufferRange instead of glMapBuffer
glMapBufferRange has the advantage that it is available in GLES.
And the extra fun factor that it uses different flags.
2024-03-12 19:20:16 -04:00
Matthias Clasen
94cb4be21b gsk: Optionally use glMapBuffer
Add a gl buffer implementation that is using glMapBuffer, and
a 'no-gl-map-buffer' optimization flag to use it, with

GSK_GPU_SKIP=no-gl-map-buffer
2024-03-12 18:33:47 -04:00
Matthias Clasen
9212cf8ab1 gsk: Move the buffer upload counter
Move the sysprof counter for buffer uploads to the generic
code, so it works for both ngl and Vulkan. This partially
reverts commit ecf1b7c18a.
2024-03-12 08:44:20 -04:00
8 changed files with 158 additions and 12 deletions

View File

@@ -1,7 +1,5 @@
#include "config.h"
#include <gdk/gdkprofilerprivate.h>
#include "gskglbufferprivate.h"
struct _GskGLBuffer
@@ -16,9 +14,6 @@ struct _GskGLBuffer
G_DEFINE_TYPE (GskGLBuffer, gsk_gl_buffer, GSK_TYPE_GPU_BUFFER)
static guint profiler_buffer_uploads_id;
static gint64 profiler_buffer_uploads;
static void
gsk_gl_buffer_finalize (GObject *object)
{
@@ -49,9 +44,7 @@ gsk_gl_buffer_unmap (GskGpuBuffer *buffer,
gsk_gl_buffer_bind (self);
profiler_buffer_uploads += used;
glBufferSubData (self->target, 0, used, self->data);
gdk_profiler_set_int_counter (profiler_buffer_uploads_id, profiler_buffer_uploads);
}
static void
@@ -64,8 +57,6 @@ gsk_gl_buffer_class_init (GskGLBufferClass *klass)
buffer_class->unmap = gsk_gl_buffer_unmap;
gobject_class->finalize = gsk_gl_buffer_finalize;
profiler_buffer_uploads_id = gdk_profiler_define_int_counter ("ngl-buffer-uploads", "Number of bytes uploaded to GPU");
}
static void

View File

@@ -6,6 +6,7 @@
#include "gskgpuopprivate.h"
#include "gskgpushaderopprivate.h"
#include "gskglbufferprivate.h"
#include "gskglmapbufferprivate.h"
#include "gskgldescriptorsprivate.h"
#include "gskgldeviceprivate.h"
#include "gskglimageprivate.h"
@@ -124,14 +125,20 @@ gsk_gl_frame_create_vertex_buffer (GskGpuFrame *frame,
*/
g_hash_table_remove_all (self->vaos);
return gsk_gl_buffer_new (GL_ARRAY_BUFFER, size, GL_WRITE_ONLY);
if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_NO_GL_MAP_BUFFER))
return gsk_gl_buffer_new (GL_ARRAY_BUFFER, size, GL_WRITE_ONLY);
else
return gsk_gl_map_buffer_new (GL_ARRAY_BUFFER, size, GL_WRITE_ONLY);
}
static GskGpuBuffer *
gsk_gl_frame_create_storage_buffer (GskGpuFrame *frame,
gsize size)
{
return gsk_gl_buffer_new (GL_UNIFORM_BUFFER, size, GL_WRITE_ONLY);
if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_NO_GL_MAP_BUFFER))
return gsk_gl_buffer_new (GL_UNIFORM_BUFFER, size, GL_WRITE_ONLY);
else
return gsk_gl_map_buffer_new (GL_UNIFORM_BUFFER, size, GL_WRITE_ONLY);
}
static void

113
gsk/gpu/gskglmapbuffer.c Normal file
View File

@@ -0,0 +1,113 @@
#include "config.h"
#include "gskglmapbufferprivate.h"
struct _GskGLMapBuffer
{
GskGpuBuffer parent_instance;
GLenum target;
GLuint buffer_id;
GLenum access;
gsize size;
};
G_DEFINE_TYPE (GskGLMapBuffer, gsk_gl_map_buffer, GSK_TYPE_GPU_BUFFER)
static void
gsk_gl_map_buffer_finalize (GObject *object)
{
GskGLMapBuffer *self = GSK_GL_MAP_BUFFER (object);
glDeleteBuffers (1, &self->buffer_id);
G_OBJECT_CLASS (gsk_gl_map_buffer_parent_class)->finalize (object);
}
static guchar *
gsk_gl_map_buffer_map (GskGpuBuffer *buffer)
{
GskGLMapBuffer *self = GSK_GL_MAP_BUFFER (buffer);
int flags;
gsk_gl_map_buffer_bind (self);
switch (self->access)
{
case GL_READ_ONLY:
flags = GL_MAP_READ_BIT;
break;
case GL_WRITE_ONLY:
flags = GL_MAP_WRITE_BIT;
break;
case GL_READ_WRITE:
flags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
break;
default:
g_assert_not_reached ();
}
return glMapBufferRange (self->target, 0, self->size, flags);
}
static void
gsk_gl_map_buffer_unmap (GskGpuBuffer *buffer,
gsize used)
{
GskGLMapBuffer *self = GSK_GL_MAP_BUFFER (buffer);
if (!glUnmapBuffer (self->target))
g_warning ("glUnmapBuffer failed");
}
static void
gsk_gl_map_buffer_class_init (GskGLMapBufferClass *klass)
{
GskGpuBufferClass *buffer_class = GSK_GPU_BUFFER_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
buffer_class->map = gsk_gl_map_buffer_map;
buffer_class->unmap = gsk_gl_map_buffer_unmap;
gobject_class->finalize = gsk_gl_map_buffer_finalize;
}
static void
gsk_gl_map_buffer_init (GskGLMapBuffer *self)
{
}
GskGpuBuffer *
gsk_gl_map_buffer_new (GLenum target,
gsize size,
GLenum access)
{
GskGLMapBuffer *self;
self = g_object_new (GSK_TYPE_GL_MAP_BUFFER, NULL);
gsk_gpu_buffer_setup (GSK_GPU_BUFFER (self), size);
self->target = target;
self->access = access;
self->size = size;
glGenBuffers (1, &self->buffer_id);
glBindBuffer (target, self->buffer_id);
glBufferData (target, size, NULL, GL_STATIC_DRAW);
return GSK_GPU_BUFFER (self);
}
void
gsk_gl_map_buffer_bind (GskGLMapBuffer *self)
{
glBindBuffer (self->target, self->buffer_id);
}
void
gsk_gl_map_buffer_bind_base (GskGLMapBuffer *self,
GLuint index)
{
glBindBufferBase (self->target, index, self->buffer_id);
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include "gskgpubufferprivate.h"
#include "gskgldeviceprivate.h"
G_BEGIN_DECLS
#define GSK_TYPE_GL_MAP_BUFFER (gsk_gl_map_buffer_get_type ())
G_DECLARE_FINAL_TYPE (GskGLMapBuffer, gsk_gl_map_buffer, GSK, GL_MAP_BUFFER, GskGpuBuffer)
GskGpuBuffer * gsk_gl_map_buffer_new (GLenum target,
gsize size,
GLenum access);
void gsk_gl_map_buffer_bind (GskGLMapBuffer *self);
void gsk_gl_map_buffer_bind_base (GskGLMapBuffer *self,
GLuint index);
G_END_DECLS

View File

@@ -2,6 +2,8 @@
#include "gskgpubufferprivate.h"
#include <gdk/gdkprofilerprivate.h>
typedef struct _GskGpuBufferPrivate GskGpuBufferPrivate;
struct _GskGpuBufferPrivate
@@ -11,9 +13,13 @@ struct _GskGpuBufferPrivate
G_DEFINE_TYPE_WITH_PRIVATE (GskGpuBuffer, gsk_gpu_buffer, G_TYPE_OBJECT)
static guint profiler_buffer_uploads_id;
static gint64 profiler_buffer_uploads;
static void
gsk_gpu_buffer_class_init (GskGpuBufferClass *klass)
{
profiler_buffer_uploads_id = gdk_profiler_define_int_counter ("gpu-buffer-uploads", "Number of bytes uploaded to GPU");
}
static void
@@ -29,7 +35,7 @@ gsk_gpu_buffer_setup (GskGpuBuffer *self,
priv->size = size;
}
gsize
gsk_gpu_buffer_get_size (GskGpuBuffer *self)
{
@@ -49,5 +55,8 @@ gsk_gpu_buffer_unmap (GskGpuBuffer *self,
gsize size)
{
GSK_GPU_BUFFER_GET_CLASS (self)->unmap (self, size);
profiler_buffer_uploads += size;
gdk_profiler_set_int_counter (profiler_buffer_uploads_id, profiler_buffer_uploads);
}

View File

@@ -31,6 +31,7 @@ static const GdkDebugKey gsk_gpu_optimization_keys[] = {
{ "gradients", GSK_GPU_OPTIMIZE_GRADIENTS, "Don't supersample gradients" },
{ "mipmap", GSK_GPU_OPTIMIZE_MIPMAP, "Avoid creating mipmaps" },
{ "glyph-align", GSK_GPU_OPTIMIZE_GLYPH_ALIGN, "Never align glyphs to the subpixel grid" },
{ "no-gl-map-buffer", GSK_GPU_OPTIMIZE_NO_GL_MAP_BUFFER, "Use glMapBuffer" },
{ "gl-baseinstance", GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE, "Assume no ARB/EXT_base_instance support" },
};

View File

@@ -119,6 +119,8 @@ typedef enum {
GSK_GPU_OPTIMIZE_GRADIENTS = 1 << 4,
GSK_GPU_OPTIMIZE_MIPMAP = 1 << 5,
GSK_GPU_OPTIMIZE_GLYPH_ALIGN = 1 << 6,
GSK_GPU_OPTIMIZE_NO_GL_MAP_BUFFER = 1 << 7,
/* These require hardware support */
GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE = 1 << 7,
} GskGpuOptimizations;

View File

@@ -68,6 +68,7 @@ gsk_private_sources = files([
'gl/stb_rect_pack.c',
'gl/fp16.c',
'gpu/gskglbuffer.c',
'gpu/gskglmapbuffer.c',
'gpu/gskgldevice.c',
'gpu/gskgldescriptors.c',
'gpu/gskglframe.c',