diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index cab93ccc4e3..7c3537e466e 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -201,6 +201,7 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buffer_gl, struct wined3d_context_gl *context_gl) { + struct wined3d_device_gl *device_gl = wined3d_device_gl(buffer_gl->b.resource.device); const struct wined3d_gl_info *gl_info = context_gl->gl_info; GLenum usage = GL_STATIC_DRAW; GLbitfield gl_storage_flags; @@ -223,7 +224,7 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf coherent = false; } gl_storage_flags = wined3d_resource_gl_storage_flags(&buffer_gl->b.resource); - if (!wined3d_context_gl_create_bo(context_gl, size, binding, usage, coherent, gl_storage_flags, bo)) + if (!wined3d_device_gl_create_bo(device_gl, context_gl, size, binding, usage, coherent, gl_storage_flags, bo)) { ERR("Failed to create OpenGL buffer object.\n"); buffer_gl->b.flags &= ~WINED3D_BUFFER_USE_BO; diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 77e0379ee61..8901bafcce3 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -2766,30 +2766,6 @@ GLuint wined3d_context_gl_allocate_vram_chunk_buffer(struct wined3d_context_gl * 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) { @@ -2852,7 +2828,7 @@ static void *wined3d_bo_gl_map(struct wined3d_bo_gl *bo, struct wined3d_context_ if ((flags & WINED3D_MAP_DISCARD) && bo->command_fence_id > device_gl->completed_fence_id) { - if (wined3d_context_gl_create_bo(context_gl, bo->size, + if (wined3d_device_gl_create_bo(device_gl, context_gl, bo->size, bo->binding, bo->usage, bo->b.coherent, bo->flags, &tmp)) { list_move_head(&tmp.b.users, &bo->b.users); @@ -3157,96 +3133,6 @@ void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct bo->id = 0; } -static bool use_buffer_chunk_suballocation(const struct wined3d_gl_info *gl_info, GLenum binding) -{ - switch (binding) - { - case GL_ARRAY_BUFFER: - case GL_ATOMIC_COUNTER_BUFFER: - case GL_DRAW_INDIRECT_BUFFER: - case GL_PIXEL_UNPACK_BUFFER: - case GL_UNIFORM_BUFFER: - return true; - - case GL_TEXTURE_BUFFER: - return gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]; - - default: - return false; - } -} - -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); - - if (gl_info->supported[ARB_BUFFER_STORAGE]) - { - if (use_buffer_chunk_suballocation(gl_info, binding)) - { - if ((memory = wined3d_context_gl_allocate_memory(context_gl, memory_type_idx, size, &id))) - buffer_offset = memory->offset; - } - else - { - 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); - } - - if (!id) - { - WARN("Failed to allocate buffer.\n"); - return false; - } - } - else - { - 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)); - } - - 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; - bo->flags = flags; - bo->b.coherent = coherent; - list_init(&bo->b.users); - bo->command_fence_id = 0; - bo->b.buffer_offset = buffer_offset; - bo->b.memory_offset = bo->b.buffer_offset; - bo->b.map_ptr = NULL; - bo->b.client_map_count = 0; - - return true; -} - static void wined3d_context_gl_set_render_offscreen(struct wined3d_context_gl *context_gl, BOOL offscreen) { if (context_gl->c.render_offscreen == offscreen) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 4dac9220f0f..84d2e3a0ce8 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -29,6 +29,7 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); WINE_DECLARE_DEBUG_CHANNEL(winediag); struct wined3d_matrix_3x3 @@ -1033,7 +1034,7 @@ gl_memory_types[] = {GL_CLIENT_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT}, }; -unsigned int wined3d_device_gl_find_memory_type(GLbitfield flags) +static unsigned int wined3d_device_gl_find_memory_type(GLbitfield flags) { unsigned int i; @@ -1052,6 +1053,119 @@ GLbitfield wined3d_device_gl_get_memory_type_flags(unsigned int memory_type_idx) return gl_memory_types[memory_type_idx].flags; } +static struct wined3d_allocator_block *wined3d_device_gl_allocate_memory(struct wined3d_device_gl *device_gl, + struct wined3d_context_gl *context_gl, unsigned int memory_type, GLsizeiptr size, GLuint *id) +{ + 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 bool use_buffer_chunk_suballocation(const struct wined3d_gl_info *gl_info, GLenum binding) +{ + switch (binding) + { + case GL_ARRAY_BUFFER: + case GL_ATOMIC_COUNTER_BUFFER: + case GL_DRAW_INDIRECT_BUFFER: + case GL_PIXEL_UNPACK_BUFFER: + case GL_UNIFORM_BUFFER: + return true; + + case GL_TEXTURE_BUFFER: + return gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]; + + default: + return false; + } +} + +bool wined3d_device_gl_create_bo(struct wined3d_device_gl *device_gl, 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 = &device_gl->d.adapter->gl_info; + struct wined3d_allocator_block *memory = NULL; + GLsizeiptr buffer_offset = 0; + GLuint id = 0; + + TRACE("device_gl %p, context_gl %p, size %lu, binding %#x, usage %#x, coherent %#x, flags %#x, bo %p.\n", + device_gl, context_gl, size, binding, usage, coherent, flags, bo); + + if (gl_info->supported[ARB_BUFFER_STORAGE]) + { + if (use_buffer_chunk_suballocation(gl_info, binding)) + { + if ((memory = wined3d_device_gl_allocate_memory(device_gl, context_gl, memory_type_idx, size, &id))) + buffer_offset = memory->offset; + } + else + { + 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); + } + + if (!id) + { + WARN("Failed to allocate buffer.\n"); + return false; + } + } + else + { + 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)); + } + + 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; + bo->flags = flags; + bo->b.coherent = coherent; + list_init(&bo->b.users); + bo->command_fence_id = 0; + bo->b.buffer_offset = buffer_offset; + bo->b.memory_offset = bo->b.buffer_offset; + bo->b.map_ptr = NULL; + bo->b.client_map_count = 0; + + return true; +} + void wined3d_device_gl_delete_opengl_contexts_cs(void *object) { struct wined3d_device_gl *device_gl = object; diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 18925338285..b1fd1e7bde2 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -2019,8 +2019,9 @@ static void wined3d_texture_gl_prepare_buffer_object(struct wined3d_texture_gl * if (bo->id) return; - if (!wined3d_context_gl_create_bo(context_gl, sub_resource->size, GL_PIXEL_UNPACK_BUFFER, - GL_STREAM_DRAW, true, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_CLIENT_STORAGE_BIT, bo)) + if (!wined3d_device_gl_create_bo(wined3d_device_gl(texture_gl->t.resource.device), + context_gl, sub_resource->size, GL_PIXEL_UNPACK_BUFFER, GL_STREAM_DRAW, true, + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_CLIENT_STORAGE_BIT, bo)) return; TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", bo->id, texture_gl, sub_resource_idx); diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 4483a21a6d0..a345626cf5e 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -1671,10 +1671,11 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object) if (resource->type == WINED3D_RTYPE_BUFFER) { + struct wined3d_device_gl *device_gl = wined3d_device_gl(resource->device); struct wined3d_buffer *buffer = buffer_from_resource(resource); struct wined3d_context_gl *context_gl; - context_gl = wined3d_context_gl(context_acquire(resource->device, NULL, 0)); + context_gl = wined3d_context_gl(context_acquire(&device_gl->d, NULL, 0)); create_buffer_view(&view_gl->gl_view, &context_gl->c, desc, buffer, view_gl->v.format); view_gl->bo_user.valid = true; list_add_head(&buffer->buffer_object->users, &view_gl->bo_user.entry); @@ -1683,7 +1684,7 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object) struct wined3d_bo_gl *bo = &view_gl->counter_bo; view_gl->v.counter_bo = &bo->b; - wined3d_context_gl_create_bo(context_gl, sizeof(uint32_t), GL_ATOMIC_COUNTER_BUFFER, + wined3d_device_gl_create_bo(device_gl, context_gl, sizeof(uint32_t), GL_ATOMIC_COUNTER_BUFFER, GL_STATIC_DRAW, true, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_CLIENT_STORAGE_BIT, bo); wined3d_unordered_access_view_set_counter(&view_gl->v, 0); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index cfd1d98d6ad..48b760edc1b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2382,8 +2382,6 @@ void wined3d_context_gl_check_fbo_status(const struct wined3d_context_gl *contex void wined3d_context_gl_copy_bo_address(struct wined3d_context_gl *context_gl, const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src, unsigned int range_count, const struct wined3d_range *ranges) DECLSPEC_HIDDEN; -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) DECLSPEC_HIDDEN; void wined3d_context_gl_destroy(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct wined3d_bo_gl *bo) DECLSPEC_HIDDEN; void wined3d_context_gl_draw_shaded_quad(struct wined3d_context_gl *context_gl, struct wined3d_texture_gl *texture_gl, @@ -4214,9 +4212,11 @@ static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device return CONTAINING_RECORD(device, struct wined3d_device_gl, d); } +bool wined3d_device_gl_create_bo(struct wined3d_device_gl *device_gl, + struct wined3d_context_gl *context_gl, GLsizeiptr size, GLenum binding, + GLenum usage, bool coherent, GLbitfield flags, struct wined3d_bo_gl *bo) DECLSPEC_HIDDEN; 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)