mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-10 20:50:12 +00:00
ngl: Conform to buffer offset alignment requirements
When using glMapBufferRange() for our globals we need to make sure the offset is a
multiple of GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT.
Since we've only been doing that for globals and GskGlobalsInstace is 128 bytes,
this is usually the case. But it is valid to require 256 bytes
alignment, and in those cases we used to fail.
The case that discovered this was an old card using nouveau, but it may
also affect some Applie hardware.
Fixes: b154c9caf4
Fixes: #7180
Related: #7053
This commit is contained in:
parent
eea3e662e6
commit
d8496d66c5
@ -235,7 +235,7 @@ gsk_gl_device_get_for_display (GdkDisplay *display,
|
||||
{
|
||||
GskGLDevice *self;
|
||||
GdkGLContext *context;
|
||||
GLint max_texture_size;
|
||||
GLint max_texture_size, globals_alignment;
|
||||
|
||||
self = g_object_get_data (G_OBJECT (display), "-gsk-gl-device");
|
||||
if (self)
|
||||
@ -259,10 +259,13 @@ gsk_gl_device_get_for_display (GdkDisplay *display,
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
glGetIntegerv (GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &globals_alignment);
|
||||
|
||||
gsk_gpu_device_setup (GSK_GPU_DEVICE (self),
|
||||
display,
|
||||
max_texture_size,
|
||||
GSK_GPU_DEVICE_DEFAULT_TILE_SIZE);
|
||||
GSK_GPU_DEVICE_DEFAULT_TILE_SIZE,
|
||||
globals_alignment);
|
||||
|
||||
self->version_string = gdk_gl_context_get_glsl_version_string (context);
|
||||
self->api = gdk_gl_context_get_api (context);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "gskgpudeviceprivate.h"
|
||||
|
||||
#include "gskgpucacheprivate.h"
|
||||
#include "gskgpuglobalsopprivate.h"
|
||||
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
|
||||
@ -17,6 +18,7 @@ struct _GskGpuDevicePrivate
|
||||
GdkDisplay *display;
|
||||
gsize max_image_size;
|
||||
gsize tile_size;
|
||||
gsize globals_aligned_size;
|
||||
|
||||
GskGpuCache *cache; /* we don't own a ref, but manage the cache */
|
||||
guint cache_gc_source;
|
||||
@ -143,11 +145,19 @@ static void
|
||||
gsk_gpu_device_init (GskGpuDevice *self)
|
||||
{
|
||||
}
|
||||
|
||||
static inline gsize
|
||||
round_up (gsize number, gsize divisor)
|
||||
{
|
||||
return (number + divisor - 1) / divisor * divisor;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_device_setup (GskGpuDevice *self,
|
||||
GdkDisplay *display,
|
||||
gsize max_image_size,
|
||||
gsize tile_size)
|
||||
gsize tile_size,
|
||||
gsize globals_alignment)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
const char *str;
|
||||
@ -156,6 +166,7 @@ gsk_gpu_device_setup (GskGpuDevice *self,
|
||||
priv->max_image_size = max_image_size;
|
||||
priv->tile_size = tile_size;
|
||||
priv->cache_timeout = CACHE_TIMEOUT;
|
||||
priv->globals_aligned_size = round_up (sizeof (GskGpuGlobalsInstance), globals_alignment);
|
||||
|
||||
str = g_getenv ("GSK_CACHE_TIMEOUT");
|
||||
if (str != NULL)
|
||||
@ -246,6 +257,25 @@ gsk_gpu_device_get_tile_size (GskGpuDevice *self)
|
||||
return priv->tile_size;
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gsk_gpu_device_get_globals_aligned_size:
|
||||
* @self: a device
|
||||
*
|
||||
* The required size for allocating arrays of globals.
|
||||
* This value will be at least sizeof (GskGpuGlobalsInstance) but due to constraints
|
||||
* of how buffers are mapped, it might be larger to allow a single buffer to hold
|
||||
* all the globals instances.
|
||||
*
|
||||
* Returns: The minimum aligned size for a GskGpuGlobalsInstance
|
||||
**/
|
||||
gsize
|
||||
gsk_gpu_device_get_globals_aligned_size (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
return priv->globals_aligned_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_gpu_device_create_offscreen_image:
|
||||
* @self: the device to create the offscreen in
|
||||
|
@ -52,13 +52,15 @@ GType gsk_gpu_device_get_type (void) G
|
||||
void gsk_gpu_device_setup (GskGpuDevice *self,
|
||||
GdkDisplay *display,
|
||||
gsize max_image_size,
|
||||
gsize tile_size);
|
||||
gsize tile_size,
|
||||
gsize globals_alignment);
|
||||
void gsk_gpu_device_maybe_gc (GskGpuDevice *self);
|
||||
void gsk_gpu_device_queue_gc (GskGpuDevice *self);
|
||||
GdkDisplay * gsk_gpu_device_get_display (GskGpuDevice *self);
|
||||
GskGpuCache * gsk_gpu_device_get_cache (GskGpuDevice *self);
|
||||
gsize gsk_gpu_device_get_max_image_size (GskGpuDevice *self);
|
||||
gsize gsk_gpu_device_get_tile_size (GskGpuDevice *self);
|
||||
gsize gsk_gpu_device_get_globals_aligned_size (GskGpuDevice *self);
|
||||
|
||||
GskGpuImage * gsk_gpu_device_create_offscreen_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
|
@ -25,8 +25,7 @@
|
||||
|
||||
/* GL_MAX_UNIFORM_BLOCK_SIZE is at 16384 */
|
||||
#define DEFAULT_STORAGE_BUFFER_SIZE 16 * 1024 * 64
|
||||
|
||||
#define DEFAULT_N_GLOBALS (16384 / sizeof (GskGpuGlobalsInstance))
|
||||
#define DEFAULT_N_GLOBALS_SIZE 16384
|
||||
|
||||
#define GDK_ARRAY_NAME gsk_gpu_ops
|
||||
#define GDK_ARRAY_TYPE_NAME GskGpuOps
|
||||
@ -52,7 +51,7 @@ struct _GskGpuFramePrivate
|
||||
guchar *vertex_buffer_data;
|
||||
gsize vertex_buffer_used;
|
||||
GskGpuBuffer *globals_buffer;
|
||||
GskGpuGlobalsInstance *globals_buffer_data;
|
||||
guchar *globals_buffer_data;
|
||||
gsize n_globals;
|
||||
GskGpuBuffer *storage_buffer;
|
||||
guchar *storage_buffer_data;
|
||||
@ -582,24 +581,26 @@ gsk_gpu_frame_add_globals (GskGpuFrame *self,
|
||||
const GskGpuGlobalsInstance *globals)
|
||||
{
|
||||
GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self);
|
||||
gsize size_needed, result;
|
||||
gsize size_needed, globals_size, result;
|
||||
|
||||
globals_size = gsk_gpu_device_get_globals_aligned_size (priv->device);
|
||||
|
||||
if (priv->globals_buffer == NULL)
|
||||
{
|
||||
priv->globals_buffer = gsk_gpu_frame_create_globals_buffer (self, sizeof (GskGpuGlobalsInstance) * DEFAULT_N_GLOBALS);
|
||||
priv->globals_buffer = gsk_gpu_frame_create_globals_buffer (self, DEFAULT_N_GLOBALS_SIZE);
|
||||
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);
|
||||
priv->globals_buffer_data = gsk_gpu_buffer_map (priv->globals_buffer);
|
||||
|
||||
size_needed = sizeof (GskGpuGlobalsInstance) * (priv->n_globals + 1);
|
||||
size_needed = globals_size * (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);
|
||||
guchar *new_data = gsk_gpu_buffer_map (new_buffer);
|
||||
|
||||
if (priv->globals_buffer_data)
|
||||
{
|
||||
@ -613,7 +614,7 @@ gsk_gpu_frame_add_globals (GskGpuFrame *self,
|
||||
|
||||
result = priv->n_globals;
|
||||
|
||||
priv->globals_buffer_data[priv->n_globals] = *globals;
|
||||
*((GskGpuGlobalsInstance *) (priv->globals_buffer_data + priv->n_globals * globals_size)) = *globals;
|
||||
priv->n_globals++;
|
||||
|
||||
return result;
|
||||
|
@ -67,10 +67,13 @@ gsk_gpu_globals_op_gl_command (GskGpuOp *op,
|
||||
GskGLCommandState *state)
|
||||
{
|
||||
GskGpuGlobalsOp *self = (GskGpuGlobalsOp *) op;
|
||||
gsize globals_size;
|
||||
|
||||
globals_size = gsk_gpu_device_get_globals_aligned_size (gsk_gpu_frame_get_device (frame));
|
||||
|
||||
gsk_gl_buffer_bind_range (GSK_GL_BUFFER (state->globals),
|
||||
0,
|
||||
self->id * sizeof (GskGpuGlobalsInstance),
|
||||
self->id * globals_size,
|
||||
sizeof (GskGpuGlobalsInstance));
|
||||
|
||||
return op->next;
|
||||
|
@ -407,7 +407,8 @@ gsk_vulkan_device_setup (GskVulkanDevice *self,
|
||||
gsk_gpu_device_setup (GSK_GPU_DEVICE (self),
|
||||
display,
|
||||
vk_props.properties.limits.maxImageDimension2D,
|
||||
GSK_GPU_DEVICE_DEFAULT_TILE_SIZE);
|
||||
GSK_GPU_DEVICE_DEFAULT_TILE_SIZE,
|
||||
vk_props.properties.limits.minUniformBufferOffsetAlignment);
|
||||
}
|
||||
|
||||
GskGpuDevice *
|
||||
|
Loading…
Reference in New Issue
Block a user