From: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@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;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/context_gl.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 9b8a887bd92..587dc3059ca 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3129,6 +3129,7 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei { switch (binding) { + case GL_ATOMIC_COUNTER_BUFFER: case GL_DRAW_INDIRECT_BUFFER: if ((memory = wined3d_context_gl_allocate_memory(context_gl, memory_type_idx, size, &id))) buffer_offset = memory->offset;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/context_gl.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 587dc3059ca..2d37e29a655 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3131,6 +3131,7 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei { case GL_ATOMIC_COUNTER_BUFFER: case GL_DRAW_INDIRECT_BUFFER: + case GL_PIXEL_UNPACK_BUFFER: if ((memory = wined3d_context_gl_allocate_memory(context_gl, memory_type_idx, size, &id))) buffer_offset = memory->offset; break;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/context_gl.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 2d37e29a655..e58aac0ba19 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3132,6 +3132,7 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei case GL_ATOMIC_COUNTER_BUFFER: case GL_DRAW_INDIRECT_BUFFER: case GL_PIXEL_UNPACK_BUFFER: + case GL_TEXTURE_BUFFER: if ((memory = wined3d_context_gl_allocate_memory(context_gl, memory_type_idx, size, &id))) buffer_offset = memory->offset; break;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
On Tue, 1 Feb 2022 at 22:45, Zebediah Figura zfigura@codeweavers.com wrote:
@@ -3132,6 +3132,7 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei case GL_ATOMIC_COUNTER_BUFFER: case GL_DRAW_INDIRECT_BUFFER: case GL_PIXEL_UNPACK_BUFFER:
case GL_TEXTURE_BUFFER: if ((memory = wined3d_context_gl_allocate_memory(context_gl, memory_type_idx, size, &id))) buffer_offset = memory->offset; break;
Actually, note that sub-allocating texture buffers requires the ARB_texture_buffer_range extension.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/context_gl.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index e58aac0ba19..53e90340316 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3133,6 +3133,7 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei case GL_DRAW_INDIRECT_BUFFER: case GL_PIXEL_UNPACK_BUFFER: case GL_TEXTURE_BUFFER: + case GL_UNIFORM_BUFFER: if ((memory = wined3d_context_gl_allocate_memory(context_gl, memory_type_idx, size, &id))) buffer_offset = memory->offset; break;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Zebediah Figura zfigura@codeweavers.com writes:
From: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@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(-)
That series is causing crashes here:
tools/runtest -q -P wine -T . -M d2d1.dll -p dlls/d2d1/tests/d2d1_test.exe d2d1 && touch dlls/d2d1/tests/d2d1.ok Unhandled exception: page fault on write access to 0x00000028 in 32-bit code (0x794103bc). Register dump: CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b EIP:794103bc ESP:0403f870 EBP:55c79d10 EFLAGS:00010202( R- -- I - - - ) EAX:00000000 EBX:5fcc0db0 ECX:55c79d3c EDX:00000000 ESI:60000343 EDI:55c84724 Stack dump: 0x0403f870: 005a0094 00000000 00000004 5d400020 0x0403f880: 55c84724 7a4b4000 55c050b0 78f17b96 0x0403f890: 005a0094 00000002 005a0000 68f76b00 0x0403f8a0: 00000000 04cf0000 79067b00 55c846a0 0x0403f8b0: 5d473010 00000000 5d400020 78ef097f 0x0403f8c0: 5d400020 55c79d10 00000000 00000343 Backtrace: =>0 0x794103bc __driDriverGetExtensions_virtio_gpu+0x591abc() in radeonsi_dri.so (0x55c79d10) 1 0x78ef097f __driDriverGetExtensions_virtio_gpu+0x7207f() in radeonsi_dri.so (0x5d400020) 2 0x78f56944 __driDriverGetExtensions_virtio_gpu+0xd8044() in radeonsi_dri.so (0x7a4b4000) 3 0x7e7e7918 wined3d_allocator_chunk_gl_map+0x388(context_gl=<internal error>, chunk_gl=<internal error>) [Z:\home\julliard\wine\wine\dlls\wined3d\context_gl.c:2799] in wined3d (0x0403f9f8) 4 0x7e7e7918 wined3d_bo_gl_map+0x402(flags=<internal error>, context_gl=<internal error>, bo=<internal error>) [Z:\home\julliard\wine\wine\dlls\wined3d\context_gl.c:2922] in wined3d (0x0403f9f8) 5 0x7e7e7918 wined3d_context_gl_map_bo_address+0x418(context_gl=03764B10, data=0403FABC, size=0x12c000, flags=0x40000000) [Z:\home\julliard\wine\wine\dlls\wined3d\context_gl.c:2922] in wined3d (0x0403f9f8) 6 0x7e869ef3 surface_cpu_blt+0xcd3(dst_texture=0838B898, dst_sub_resource_idx=0, dst_box=0403FB68, src_texture=<register ESI not accessible in this frame>, src_sub_resource_idx=0, src_box=0403FB80, flags=0x20000000, fx=0403FB98, filter=WINED3D_TEXF_POINT) [Z:\home\julliard\wine\wine\dlls\wined3d\surface.c:774] in wined3d (0x0403fb28) 7 0x7e86b321 cpu_blitter_blit+0xb1(blitter=03767240, op=WINED3D_BLIT_OP_RAW_BLIT, context=03764B10, src_texture=04D1F1D8, src_sub_resource_idx=0, src_location=0x10, src_rect=0403FE20, dst_texture=0838B898, dst_sub_resource_idx=<is not available>, dst_location=0x8, dst_rect=0403FE30, color_key=00000000, filter=WINED3D_TEXF_POINT, resolve_format=00000000) [Z:\home\julliard\wine\wine\dlls\wined3d\surface.c:1438] in wined3d (0x0403fbc8) 8 0x7e8837d3 ffp_blitter_blit+0x73(blitter=<is not available>, op=<is not available>, context=<is not available>, src_texture=<is not available>, src_sub_resource_idx=<is not available>, src_location=<is not available>, src_rect=<is not available>, dst_texture=<is not available>, dst_sub_resource_idx=<is not available>, dst_location=<is not available>, dst_rect=<is not available>, colour_key=<is not available>, filter=<is not available>, resolve_format=<is not available>) [Z:\home\julliard\wine\wine\dlls\wined3d\texture.c:5871] in wined3d (0x0403fc88) 9 0x7e8345f3 glsl_blitter_blit+0x163(blitter=<is not available>, op=<is not available>, context=<is not available>, src_texture=<is not available>, src_sub_resource_idx=<is not available>, src_location=<is not available>, src_rect=<is not available>, dst_texture=<is not available>, dst_sub_resource_idx=<is not available>, dst_location=<is not available>, dst_rect=<is not available>, colour_key=<is not available>, filter=<is not available>, resolve_format=<is not available>) [Z:\home\julliard\wine\wine\dlls\wined3d\glsl_shader.c:13129] in wined3d (0x0403fd98) 10 0x7e86c0fc texture2d_blt+0x33c(dst_texture=<is not available>, dst_sub_resource_idx=<is not available>, dst_box=<is not available>, src_texture=<is not available>, src_sub_resource_idx=<is not available>, src_box=<is not available>, flags=<is not available>, fx=<is not available>, filter=<is not available>) [Z:\home\julliard\wine\wine\dlls\wined3d\surface.c:1736] in wined3d (0x0403fe58) 11 0x7e7fbb72 wined3d_cs_exec_blt_sub_resource+0x92(cs=03C30020, data=03C6EED4) [Z:\home\julliard\wine\wine\dlls\wined3d\cs.c:2644] in wined3d (0x0403fed8) 12 0x7e7fa514 wined3d_cs_command_unlock(cs=00000000, data=7B62DEF0) [Z:\home\julliard\wine\wine\dlls\wined3d\cs.c:3399] in wined3d (0x0403ff28) 13 0x7e7fa514 wined3d_cs_run+0xf4(ctx=<internal error>) [Z:\home\julliard\wine\wine\dlls\wined3d\cs.c:3398] in wined3d (0x0403ff28) 14 0x7b62def0 WriteTapemark+0x100(device=03C30020, type=<is not available>, count=<is not available>, immediate=<is not available>) [Z:\home\julliard\wine\wine\dlls\kernel32\tape.c:317] in kernel32 (0x0403ff48) 15 0x7bc57c27 RtlWakeConditionVariable+0x57(variable=7B62DEE0) [Z:\home\julliard\wine\wine\dlls\ntdll\sync.c:766] in ntdll (0x0403ff5c) 16 0x7bc582e0 RtlCreateUserThread(entry=7E7FA420, arg=03C30020) [Z:\home\julliard\wine\wine\dlls\ntdll\thread.c:261] in ntdll (0x0403ffec) 0x794103bc radeonsi_dri.so+0x63a3bc: movl %ecx,0x28(%edx)
On 2/2/22 16:22, Alexandre Julliard wrote:
Zebediah Figura zfigura@codeweavers.com writes:
From: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@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(-)
That series is causing crashes here:
I can reproduce the same crashes.
The crashes are because we run out of virtual address space. They are introduced by this patch set because we are, for performance reasons, suddenly mapping larger buffers than we strictly need to, and we are doing so $(nproc) times in a single process. In the case of d2d1 at least the main offender seems to be pixel unpack buffers.
Running the tests singlethreaded helps for me. I didn't come across this before because I'd been already running all of the tests singlethreaded anyway, mostly for nouveau reasons.
I don't know what to do about this really. We could potentially limit the number of concurrent tests on 32-bit wine, although determining how far to limit them is not exactly trivial.
Running the tests in separate processes would also help, instead of separate threads in the same process. That might be a better approach.
On Thu, 3 Feb 2022 at 02:11, Zebediah Figura zfigura@codeweavers.com wrote:
On 2/2/22 16:22, Alexandre Julliard wrote:
Zebediah Figura zfigura@codeweavers.com writes:
From: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@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(-)
That series is causing crashes here:
I can reproduce the same crashes.
The crashes are because we run out of virtual address space. They are introduced by this patch set because we are, for performance reasons, suddenly mapping larger buffers than we strictly need to, and we are doing so $(nproc) times in a single process. In the case of d2d1 at least the main offender seems to be pixel unpack buffers.
Running the tests singlethreaded helps for me. I didn't come across this before because I'd been already running all of the tests singlethreaded anyway, mostly for nouveau reasons.
I don't know what to do about this really. We could potentially limit the number of concurrent tests on 32-bit wine, although determining how far to limit them is not exactly trivial.
Running the tests in separate processes would also help, instead of separate threads in the same process. That might be a better approach.
I suppose my machine doesn't have enough cores to run into this...
One of the issues here is that we do buffer allocation per device instead of per GPU. Unfortunately, for GL in particular, that's not entirely trivial to fix. I suppose we could put an upper limit on the number of worker threads the D3D tests spawn, although that's also a little unfortunate.
On 2/2/22 16:22, Alexandre Julliard wrote:
Zebediah Figura zfigura@codeweavers.com writes:
From: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@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(-)
That series is causing crashes here:
These should be fixed now as of dece48b9fb. I believe this series can now be committed without changes, barring any other problems.
On Tue, 8 Feb 2022 at 18:52, Zebediah Figura zfigura@codeweavers.com wrote:
On 2/2/22 16:22, Alexandre Julliard wrote:
Zebediah Figura zfigura@codeweavers.com writes:
From: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@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(-)
That series is causing crashes here:
These should be fixed now as of dece48b9fb. I believe this series can now be committed without changes, barring any other problems.
Mostly, yes. Note the issue with texture buffers in patch 4/5.
On 2/8/22 11:57, Henri Verbeet wrote:
On Tue, 8 Feb 2022 at 18:52, Zebediah Figura zfigura@codeweavers.com wrote:
On 2/2/22 16:22, Alexandre Julliard wrote:
Zebediah Figura zfigura@codeweavers.com writes:
From: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@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(-)
That series is causing crashes here:
These should be fixed now as of dece48b9fb. I believe this series can now be committed without changes, barring any other problems.
Mostly, yes. Note the issue with texture buffers in patch 4/5.
Whoops, I thought I had resent this series to account for that, but clearly I did not. I'll send a new version.