[PATCH 1/5] wined3d: Use the chunk allocator for GL indirect draw buffers.
Zebediah Figura
zfigura at codeweavers.com
Tue Feb 1 15:28:29 CST 2022
From: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 1 +
dlls/wined3d/context_gl.c | 258 +++++++++++++++++++++++++++++----
dlls/wined3d/device.c | 110 ++++++++++++++
dlls/wined3d/wined3d_private.h | 66 ++++++---
4 files changed, 390 insertions(+), 45 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 5511a70a8ff..e903c67b56a 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4283,6 +4283,7 @@ static void adapter_gl_destroy_device(struct wined3d_device *device)
struct wined3d_device_gl *device_gl = wined3d_device_gl(device);
wined3d_device_cleanup(&device_gl->d);
+ heap_free(device_gl->retired_blocks);
heap_free(device_gl);
}
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 3a83027522a..9b8a887bd92 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2618,6 +2618,37 @@ static void wined3d_context_gl_poll_fences(struct wined3d_context_gl *context_gl
}
}
+static void wined3d_context_gl_cleanup_resources(struct wined3d_context_gl *context_gl)
+{
+ struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
+ struct wined3d_retired_block_gl *r, *blocks;
+ SIZE_T count, i = 0;
+ uint64_t id;
+
+ wined3d_context_gl_poll_fences(context_gl);
+ id = device_gl->completed_fence_id;
+
+ blocks = device_gl->retired_blocks;
+ count = device_gl->retired_block_count;
+ while (i < count)
+ {
+ r = &blocks[i];
+
+ if (r->fence_id > id)
+ {
+ ++i;
+ continue;
+ }
+
+ wined3d_allocator_block_free(r->block);
+ if (i != --count)
+ *r = blocks[count];
+ else
+ ++i;
+ }
+ device_gl->retired_block_count = count;
+}
+
void wined3d_context_gl_wait_command_fence(struct wined3d_context_gl *context_gl, uint64_t id)
{
struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
@@ -2635,7 +2666,7 @@ void wined3d_context_gl_wait_command_fence(struct wined3d_context_gl *context_gl
if ((ret = wined3d_fence_wait(context_gl->submitted.fences[i].fence, &device_gl->d)) != WINED3D_FENCE_OK)
ERR("Failed to wait for command fence with id 0x%s, ret %#x.\n", wine_dbgstr_longlong(id), ret);
- wined3d_context_gl_poll_fences(context_gl);
+ wined3d_context_gl_cleanup_resources(context_gl);
return;
}
@@ -2665,7 +2696,133 @@ void wined3d_context_gl_submit_command_fence(struct wined3d_context_gl *context_
device_gl->completed_fence_id = 0;
device_gl->current_fence_id = 1;
}
- wined3d_context_gl_poll_fences(context_gl);
+ wined3d_context_gl_cleanup_resources(context_gl);
+}
+
+static void wined3d_context_gl_destroy_allocator_block(struct wined3d_context_gl *context_gl,
+ struct wined3d_allocator_block *block, uint64_t fence_id)
+{
+ struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
+ struct wined3d_retired_block_gl *r;
+
+ if (device_gl->completed_fence_id > fence_id)
+ {
+ wined3d_allocator_block_free(block);
+ TRACE("Freed block %p.\n", block);
+ return;
+ }
+
+ if (!wined3d_array_reserve((void **)&device_gl->retired_blocks,
+ &device_gl->retired_blocks_size, device_gl->retired_block_count + 1,
+ sizeof(*device_gl->retired_blocks)))
+ {
+ ERR("Leaking block %p.\n", block);
+ return;
+ }
+
+ r = &device_gl->retired_blocks[device_gl->retired_block_count++];
+ r->block = block;
+ r->fence_id = fence_id;
+}
+
+/* We always have buffer storage here. */
+GLuint wined3d_context_gl_allocate_vram_chunk_buffer(struct wined3d_context_gl *context_gl,
+ unsigned int pool, size_t size)
+{
+ const struct wined3d_gl_info *gl_info = context_gl->gl_info;
+ GLbitfield flags;
+ GLuint id = 0;
+
+ TRACE("context_gl %p, pool %u, size %zu.\n", context_gl, pool, size);
+
+ GL_EXTCALL(glGenBuffers(1, &id));
+ if (!id)
+ {
+ checkGLcall("buffer object creation");
+ return 0;
+ }
+ wined3d_context_gl_bind_bo(context_gl, GL_PIXEL_UNPACK_BUFFER, id);
+
+ flags = wined3d_device_gl_get_memory_type_flags(pool) | GL_DYNAMIC_STORAGE_BIT;
+ if (flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))
+ flags |= GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
+ GL_EXTCALL(glBufferStorage(GL_PIXEL_UNPACK_BUFFER, size, NULL, flags));
+
+ checkGLcall("buffer object creation");
+
+ TRACE("Created buffer object %u.\n", id);
+
+ return id;
+}
+
+static struct wined3d_allocator_block *wined3d_context_gl_allocate_memory(struct wined3d_context_gl *context_gl,
+ unsigned int memory_type, GLsizeiptr size, GLuint *id)
+{
+ struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
+ struct wined3d_allocator *allocator = &device_gl->allocator;
+ struct wined3d_allocator_block *block;
+
+ if (size > WINED3D_ALLOCATOR_CHUNK_SIZE / 2)
+ {
+ *id = wined3d_context_gl_allocate_vram_chunk_buffer(context_gl, memory_type, size);
+ return NULL;
+ }
+
+ if (!(block = wined3d_allocator_allocate(allocator, &context_gl->c, memory_type, size)))
+ {
+ *id = 0;
+ return NULL;
+ }
+
+ *id = wined3d_allocator_chunk_gl(block->chunk)->gl_buffer;
+
+ return block;
+}
+
+static void *wined3d_allocator_chunk_gl_map(struct wined3d_allocator_chunk_gl *chunk_gl,
+ struct wined3d_context_gl *context_gl)
+{
+ const struct wined3d_gl_info *gl_info = context_gl->gl_info;
+
+ TRACE("chunk %p, gl_buffer %u, map_ptr %p.\n", chunk_gl, chunk_gl->gl_buffer, chunk_gl->c.map_ptr);
+
+ if (!chunk_gl->c.map_ptr)
+ {
+ unsigned int flags = wined3d_device_gl_get_memory_type_flags(chunk_gl->memory_type) & ~GL_CLIENT_STORAGE_BIT;
+
+ flags |= GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
+ if (!(flags & GL_MAP_READ_BIT))
+ flags |= GL_MAP_UNSYNCHRONIZED_BIT;
+ if (flags & GL_MAP_WRITE_BIT)
+ flags |= GL_MAP_FLUSH_EXPLICIT_BIT;
+ wined3d_context_gl_bind_bo(context_gl, GL_PIXEL_UNPACK_BUFFER, chunk_gl->gl_buffer);
+ chunk_gl->c.map_ptr = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER,
+ 0, WINED3D_ALLOCATOR_CHUNK_SIZE, flags));
+ if (!chunk_gl->c.map_ptr)
+ {
+ ERR("Failed to map chunk memory.\n");
+ return NULL;
+ }
+ }
+
+ ++chunk_gl->c.map_count;
+
+ return chunk_gl->c.map_ptr;
+}
+
+static void wined3d_allocator_chunk_gl_unmap(struct wined3d_allocator_chunk_gl *chunk_gl,
+ struct wined3d_context_gl *context_gl)
+{
+ const struct wined3d_gl_info *gl_info = context_gl->gl_info;
+
+ TRACE("chunk_gl %p, context_gl %p.\n", chunk_gl, context_gl);
+
+ if (!--chunk_gl->c.map_count && !wined3d_map_persistent())
+ {
+ wined3d_context_gl_bind_bo(context_gl, GL_PIXEL_UNPACK_BUFFER, chunk_gl->gl_buffer);
+ GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
+ chunk_gl->c.map_ptr = NULL;
+ }
}
static void *wined3d_bo_gl_map(struct wined3d_bo_gl *bo, struct wined3d_context_gl *context_gl, uint32_t flags)
@@ -2708,6 +2865,15 @@ map:
if (bo->b.map_ptr)
return bo->b.map_ptr;
+ if (bo->memory)
+ {
+ struct wined3d_allocator_chunk_gl *chunk_gl = wined3d_allocator_chunk_gl(bo->memory->chunk);
+
+ if (!(map_ptr = wined3d_allocator_chunk_gl_map(chunk_gl, context_gl)))
+ ERR("Failed to map chunk.\n");
+ return map_ptr;
+ }
+
gl_info = context_gl->gl_info;
wined3d_context_gl_bind_bo(context_gl, bo->binding, bo->id);
@@ -2766,7 +2932,12 @@ static void wined3d_bo_gl_unmap(struct wined3d_bo_gl *bo, struct wined3d_context
return;
wined3d_context_gl_bind_bo(context_gl, bo->binding, bo->id);
- GL_EXTCALL(glUnmapBuffer(bo->binding));
+
+ if (bo->memory)
+ wined3d_allocator_chunk_gl_unmap(wined3d_allocator_chunk_gl(bo->memory->chunk), context_gl);
+ else
+ GL_EXTCALL(glUnmapBuffer(bo->binding));
+
wined3d_context_gl_bind_bo(context_gl, bo->binding, 0);
checkGLcall("Unmap buffer object");
}
@@ -2920,7 +3091,23 @@ void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct
TRACE("context_gl %p, bo %p.\n", context_gl, bo);
+ if (bo->memory)
+ {
+ if (bo->b.map_ptr)
+ wined3d_allocator_chunk_gl_unmap(wined3d_allocator_chunk_gl(bo->memory->chunk), context_gl);
+ wined3d_context_gl_destroy_allocator_block(context_gl, bo->memory, bo->command_fence_id);
+ bo->id = 0;
+ return;
+ }
+
+ if (bo->b.map_ptr)
+ {
+ wined3d_context_gl_bind_bo(context_gl, bo->binding, bo->id);
+ GL_EXTCALL(glUnmapBuffer(bo->binding));
+ }
+
TRACE("Destroying GL buffer %u.\n", bo->id);
+
GL_EXTCALL(glDeleteBuffers(1, &bo->id));
checkGLcall("buffer object destruction");
bo->id = 0;
@@ -2929,42 +3116,61 @@ void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct
bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizeiptr size,
GLenum binding, GLenum usage, bool coherent, GLbitfield flags, struct wined3d_bo_gl *bo)
{
+ unsigned int memory_type_idx = wined3d_device_gl_find_memory_type(flags);
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
+ struct wined3d_allocator_block *memory = NULL;
+ GLsizeiptr buffer_offset = 0;
GLuint id = 0;
TRACE("context_gl %p, size %lu, binding %#x, usage %#x, coherent %#x, flags %#x, bo %p.\n",
context_gl, size, binding, usage, coherent, flags, bo);
- GL_EXTCALL(glGenBuffers(1, &id));
- if (!id)
- {
- checkGLcall("buffer object creation");
- return false;
- }
- wined3d_context_gl_bind_bo(context_gl, binding, id);
-
- if (!coherent && gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
- {
- GL_EXTCALL(glBufferParameteriAPPLE(binding, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE));
- GL_EXTCALL(glBufferParameteriAPPLE(binding, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE));
- }
-
if (gl_info->supported[ARB_BUFFER_STORAGE])
{
- if (flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))
- flags |= GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
- GL_EXTCALL(glBufferStorage(binding, size, NULL, flags | GL_DYNAMIC_STORAGE_BIT));
+ switch (binding)
+ {
+ case GL_DRAW_INDIRECT_BUFFER:
+ if ((memory = wined3d_context_gl_allocate_memory(context_gl, memory_type_idx, size, &id)))
+ buffer_offset = memory->offset;
+ break;
+
+ default:
+ WARN_(d3d_perf)("Not allocating chunk memory for binding type %#x.\n", binding);
+ id = wined3d_context_gl_allocate_vram_chunk_buffer(context_gl, memory_type_idx, size);
+ break;
+ }
+
+ if (!id)
+ {
+ WARN("Failed to allocate buffer.\n");
+ return false;
+ }
}
else
{
- GL_EXTCALL(glBufferData(binding, size, NULL, usage));
- }
+ GL_EXTCALL(glGenBuffers(1, &id));
+ if (!id)
+ {
+ checkGLcall("buffer object creation");
+ return false;
+ }
+ wined3d_context_gl_bind_bo(context_gl, binding, id);
- wined3d_context_gl_bind_bo(context_gl, binding, 0);
- checkGLcall("buffer object creation");
+ if (!coherent && gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
+ {
+ GL_EXTCALL(glBufferParameteriAPPLE(binding, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE));
+ GL_EXTCALL(glBufferParameteriAPPLE(binding, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE));
+ }
+
+ GL_EXTCALL(glBufferData(binding, size, NULL, usage));
+
+ wined3d_context_gl_bind_bo(context_gl, binding, 0);
+ checkGLcall("buffer object creation");
+ }
TRACE("Created buffer object %u.\n", id);
bo->id = id;
+ bo->memory = memory;
bo->size = size;
bo->binding = binding;
bo->usage = usage;
@@ -2972,8 +3178,8 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
bo->b.coherent = coherent;
list_init(&bo->b.users);
bo->command_fence_id = 0;
- bo->b.memory_offset = 0;
- bo->b.buffer_offset = 0;
+ bo->b.buffer_offset = buffer_offset;
+ bo->b.memory_offset = bo->b.buffer_offset;
bo->b.map_ptr = NULL;
return true;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index aa456d3e702..09be992dd2f 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -955,6 +955,101 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi
wined3d_device_context_set_depth_stencil_view(context, ds_enable ? device->auto_depth_stencil_view : NULL);
}
+static struct wined3d_allocator_chunk *wined3d_allocator_gl_create_chunk(struct wined3d_allocator *allocator,
+ struct wined3d_context *context, unsigned int memory_type, size_t chunk_size)
+{
+ struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
+ struct wined3d_allocator_chunk_gl *chunk_gl;
+
+ TRACE("allocator %p, context %p, memory_type %u, chunk_size %zu.\n", allocator, context, memory_type, chunk_size);
+
+ if (!(chunk_gl = heap_alloc(sizeof(*chunk_gl))))
+ return NULL;
+
+ if (!wined3d_allocator_chunk_init(&chunk_gl->c, allocator))
+ {
+ heap_free(chunk_gl);
+ return NULL;
+ }
+
+ chunk_gl->memory_type = memory_type;
+ if (!(chunk_gl->gl_buffer = wined3d_context_gl_allocate_vram_chunk_buffer(context_gl, memory_type, chunk_size)))
+ {
+ wined3d_allocator_chunk_cleanup(&chunk_gl->c);
+ heap_free(chunk_gl);
+ return NULL;
+ }
+ list_add_head(&allocator->pools[memory_type].chunks, &chunk_gl->c.entry);
+
+ return &chunk_gl->c;
+}
+
+static void wined3d_allocator_gl_destroy_chunk(struct wined3d_allocator_chunk *chunk)
+{
+ struct wined3d_allocator_chunk_gl *chunk_gl = wined3d_allocator_chunk_gl(chunk);
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context_gl *context_gl;
+ struct wined3d_device_gl *device_gl;
+
+ TRACE("chunk %p.\n", chunk);
+
+ device_gl = CONTAINING_RECORD(chunk_gl->c.allocator, struct wined3d_device_gl, allocator);
+ context_gl = wined3d_context_gl(context_acquire(&device_gl->d, NULL, 0));
+ gl_info = context_gl->gl_info;
+
+ wined3d_context_gl_bind_bo(context_gl, GL_PIXEL_UNPACK_BUFFER, chunk_gl->gl_buffer);
+ if (chunk_gl->c.map_ptr)
+ GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
+ GL_EXTCALL(glDeleteBuffers(1, &chunk_gl->gl_buffer));
+ TRACE("Freed buffer %u.\n", chunk_gl->gl_buffer);
+ wined3d_allocator_chunk_cleanup(&chunk_gl->c);
+ heap_free(chunk_gl);
+
+ context_release(&context_gl->c);
+}
+
+static const struct wined3d_allocator_ops wined3d_allocator_gl_ops =
+{
+ .allocator_create_chunk = wined3d_allocator_gl_create_chunk,
+ .allocator_destroy_chunk = wined3d_allocator_gl_destroy_chunk,
+};
+
+static const struct
+{
+ GLbitfield flags;
+}
+gl_memory_types[] =
+{
+ {0},
+ {GL_MAP_READ_BIT},
+ {GL_MAP_WRITE_BIT},
+ {GL_MAP_READ_BIT | GL_MAP_WRITE_BIT},
+
+ {GL_CLIENT_STORAGE_BIT},
+ {GL_CLIENT_STORAGE_BIT | GL_MAP_READ_BIT},
+ {GL_CLIENT_STORAGE_BIT | GL_MAP_WRITE_BIT},
+ {GL_CLIENT_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT},
+};
+
+unsigned int wined3d_device_gl_find_memory_type(GLbitfield flags)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(gl_memory_types); ++i)
+ {
+ if (gl_memory_types[i].flags == flags)
+ return i;
+ }
+
+ assert(0);
+ return 0;
+}
+
+GLbitfield wined3d_device_gl_get_memory_type_flags(unsigned int memory_type_idx)
+{
+ return gl_memory_types[memory_type_idx].flags;
+}
+
void wined3d_device_gl_delete_opengl_contexts_cs(void *object)
{
struct wined3d_device_gl *device_gl = object;
@@ -978,6 +1073,12 @@ void wined3d_device_gl_delete_opengl_contexts_cs(void *object)
device->blitter->ops->blitter_destroy(device->blitter, context);
device->shader_backend->shader_free_private(device, context);
wined3d_device_gl_destroy_dummy_textures(device_gl, context_gl);
+
+ wined3d_context_gl_submit_command_fence(context_gl);
+ wined3d_context_gl_wait_command_fence(context_gl,
+ wined3d_device_gl(context_gl->c.device)->current_fence_id - 1);
+ wined3d_allocator_cleanup(&device_gl->allocator);
+
context_release(context);
while (device->context_count)
@@ -1010,10 +1111,18 @@ void wined3d_device_gl_create_primary_opengl_context_cs(void *object)
return;
}
+ if (!wined3d_allocator_init(&device_gl->allocator, ARRAY_SIZE(gl_memory_types), &wined3d_allocator_gl_ops))
+ {
+ WARN("Failed to initialise allocator.\n");
+ context_release(context);
+ return;
+ }
+
if (FAILED(hr = device->shader_backend->shader_alloc_private(device,
device->adapter->vertex_pipe, device->adapter->fragment_pipe)))
{
ERR("Failed to allocate shader private data, hr %#x.\n", hr);
+ wined3d_allocator_cleanup(&device_gl->allocator);
context_release(context);
return;
}
@@ -1022,6 +1131,7 @@ void wined3d_device_gl_create_primary_opengl_context_cs(void *object)
{
ERR("Failed to create CPU blitter.\n");
device->shader_backend->shader_free_private(device, NULL);
+ wined3d_allocator_cleanup(&device_gl->allocator);
context_release(context);
return;
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1b3a13024f9..ef1062ec9b4 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1617,6 +1617,9 @@ struct wined3d_bo_gl
struct wined3d_bo b;
GLuint id;
+
+ struct wined3d_allocator_block *memory;
+
GLsizeiptr size;
GLenum binding;
GLenum usage;
@@ -2355,6 +2358,8 @@ void wined3d_context_gl_alloc_so_statistics_query(struct wined3d_context_gl *con
struct wined3d_so_statistics_query *query) DECLSPEC_HIDDEN;
void wined3d_context_gl_alloc_timestamp_query(struct wined3d_context_gl *context_gl,
struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN;
+GLuint wined3d_context_gl_allocate_vram_chunk_buffer(struct wined3d_context_gl *context_gl,
+ unsigned int pool, size_t size) DECLSPEC_HIDDEN;
void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl,
const struct wined3d_device *device) DECLSPEC_HIDDEN;
BOOL wined3d_context_gl_apply_clear_state(struct wined3d_context_gl *context_gl, const struct wined3d_state *state,
@@ -3956,25 +3961,6 @@ static inline struct wined3d_device_no3d *wined3d_device_no3d(struct wined3d_dev
return CONTAINING_RECORD(device, struct wined3d_device_no3d, d);
}
-struct wined3d_device_gl
-{
- struct wined3d_device d;
-
- /* Textures for when no other textures are bound. */
- struct wined3d_dummy_textures dummy_textures;
-
- uint64_t completed_fence_id;
- uint64_t current_fence_id;
-};
-
-static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device *device)
-{
- return CONTAINING_RECORD(device, struct wined3d_device_gl, d);
-}
-
-void wined3d_device_gl_create_primary_opengl_context_cs(void *object) DECLSPEC_HIDDEN;
-void wined3d_device_gl_delete_opengl_contexts_cs(void *object) DECLSPEC_HIDDEN;
-
struct wined3d_null_resources_vk
{
struct wined3d_bo_vk bo;
@@ -4021,6 +4007,18 @@ void wined3d_allocator_chunk_cleanup(struct wined3d_allocator_chunk *chunk) DECL
bool wined3d_allocator_chunk_init(struct wined3d_allocator_chunk *chunk,
struct wined3d_allocator *allocator) DECLSPEC_HIDDEN;
+struct wined3d_allocator_chunk_gl
+{
+ struct wined3d_allocator_chunk c;
+ unsigned int memory_type;
+ GLuint gl_buffer;
+};
+
+static inline struct wined3d_allocator_chunk_gl *wined3d_allocator_chunk_gl(struct wined3d_allocator_chunk *chunk)
+{
+ return CONTAINING_RECORD(chunk, struct wined3d_allocator_chunk_gl, c);
+}
+
struct wined3d_allocator_chunk_vk
{
struct wined3d_allocator_chunk c;
@@ -4155,6 +4153,36 @@ void wined3d_device_vk_destroy_null_views(struct wined3d_device_vk *device_vk,
void wined3d_device_vk_uav_clear_state_init(struct wined3d_device_vk *device_vk) DECLSPEC_HIDDEN;
void wined3d_device_vk_uav_clear_state_cleanup(struct wined3d_device_vk *device_vk) DECLSPEC_HIDDEN;
+struct wined3d_device_gl
+{
+ struct wined3d_device d;
+
+ /* Textures for when no other textures are bound. */
+ struct wined3d_dummy_textures dummy_textures;
+
+ struct wined3d_allocator allocator;
+ uint64_t completed_fence_id;
+ uint64_t current_fence_id;
+
+ struct wined3d_retired_block_gl
+ {
+ struct wined3d_allocator_block *block;
+ uint64_t fence_id;
+ } *retired_blocks;
+ SIZE_T retired_blocks_size;
+ SIZE_T retired_block_count;
+};
+
+static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device *device)
+{
+ return CONTAINING_RECORD(device, struct wined3d_device_gl, d);
+}
+
+void wined3d_device_gl_create_primary_opengl_context_cs(void *object) DECLSPEC_HIDDEN;
+void wined3d_device_gl_delete_opengl_contexts_cs(void *object) DECLSPEC_HIDDEN;
+unsigned int wined3d_device_gl_find_memory_type(GLbitfield flags) DECLSPEC_HIDDEN;
+GLbitfield wined3d_device_gl_get_memory_type_flags(unsigned int memory_type_idx) DECLSPEC_HIDDEN;
+
static inline float wined3d_alpha_ref(const struct wined3d_state *state)
{
return (state->render_states[WINED3D_RS_ALPHAREF] & 0xff) / 255.0f;
--
2.34.1
More information about the wine-devel
mailing list