From: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/buffer.c | 77 ++++++++-------------------------- dlls/wined3d/context_gl.c | 35 ++++++++++++++++ dlls/wined3d/texture.c | 20 ++++----- dlls/wined3d/view.c | 22 ++++------ dlls/wined3d/wined3d_private.h | 2 + 5 files changed, 72 insertions(+), 84 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 0caf933724a..285ae7231ec 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -200,79 +200,38 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf struct wined3d_context_gl *context_gl) { const struct wined3d_gl_info *gl_info = context_gl->gl_info; + GLenum usage = GL_STATIC_DRAW; struct wined3d_bo_gl *bo; - GLenum error; + bool coherent = true; + GLsizeiptr size; + GLenum binding;
TRACE("Creating an OpenGL buffer object for wined3d buffer %p with usage %s.\n", buffer_gl, debug_d3dusage(buffer_gl->b.resource.usage));
- /* Make sure that the gl error is cleared. Do not use checkGLcall - * here because checkGLcall just prints a fixme and continues. However, - * if an error during VBO creation occurs we can fall back to non-VBO operation - * with full functionality(but performance loss). - */ - while (gl_info->gl_ops.gl.p_glGetError() != GL_NO_ERROR); - - /* Basically the FVF parameter passed to CreateVertexBuffer is no good. - * The vertex declaration from the device determines how the data in the - * buffer is interpreted. This means that on each draw call the buffer has - * to be verified to check if the rhw and color values are in the correct - * format. */ - - bo = &buffer_gl->bo; - GL_EXTCALL(glGenBuffers(1, &bo->id)); - bo->binding = wined3d_buffer_gl_binding_from_bind_flags(gl_info, buffer_gl->b.resource.bind_flags); - bo->usage = GL_STATIC_DRAW; - buffer_gl->b.buffer_object = (uintptr_t)bo; - error = gl_info->gl_ops.gl.p_glGetError(); - if (!bo->id || error != GL_NO_ERROR) - { - ERR("Failed to create a BO with error %s (%#x).\n", debug_glerror(error), error); - goto fail; - } - - wined3d_buffer_gl_bind(buffer_gl, context_gl); - error = gl_info->gl_ops.gl.p_glGetError(); - if (error != GL_NO_ERROR) - { - ERR("Failed to bind the BO with error %s (%#x).\n", debug_glerror(error), error); - goto fail; - } - + size = buffer_gl->b.resource.size; + binding = wined3d_buffer_gl_binding_from_bind_flags(gl_info, buffer_gl->b.resource.bind_flags); if (buffer_gl->b.resource.usage & WINED3DUSAGE_DYNAMIC) { - TRACE("Buffer has WINED3DUSAGE_DYNAMIC set.\n"); - bo->usage = GL_STREAM_DRAW_ARB; - - if (gl_info->supported[APPLE_FLUSH_BUFFER_RANGE]) - { - GL_EXTCALL(glBufferParameteriAPPLE(bo->binding, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); - GL_EXTCALL(glBufferParameteriAPPLE(bo->binding, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); - checkGLcall("glBufferParameteriAPPLE"); - buffer_gl->b.flags |= WINED3D_BUFFER_APPLESYNC; - } - /* No setup is needed here for GL_ARB_map_buffer_range. */ + usage = GL_STREAM_DRAW_ARB; + coherent = false; } - - GL_EXTCALL(glBufferData(bo->binding, buffer_gl->b.resource.size, NULL, bo->usage)); - error = gl_info->gl_ops.gl.p_glGetError(); - if (error != GL_NO_ERROR) + bo = &buffer_gl->bo; + if (!wined3d_context_gl_create_bo(context_gl, size, binding, usage, coherent, bo)) { - ERR("glBufferData failed with error %s (%#x).\n", debug_glerror(error), error); - goto fail; + ERR("Failed to create OpenGL buffer object.\n"); + buffer_gl->b.flags &= ~WINED3D_BUFFER_USE_BO; + buffer_clear_dirty_areas(&buffer_gl->b); + return FALSE; }
+ if (!coherent && gl_info->supported[APPLE_FLUSH_BUFFER_RANGE]) + buffer_gl->b.flags |= WINED3D_BUFFER_APPLESYNC; + + buffer_gl->b.buffer_object = (uintptr_t)bo; buffer_invalidate_bo_range(&buffer_gl->b, 0, 0);
return TRUE; - -fail: - /* Clean up all BO init, but continue because we can work without a BO :-) */ - ERR("Failed to create a buffer object. Continuing, but performance issues may occur.\n"); - buffer_gl->b.flags &= ~WINED3D_BUFFER_USE_BO; - wined3d_buffer_gl_destroy_buffer_object(buffer_gl, context_gl); - buffer_clear_dirty_areas(&buffer_gl->b); - return FALSE; }
static BOOL buffer_process_converted_attribute(struct wined3d_buffer *buffer, diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 3a5718e6308..567d6ba56b7 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -2693,6 +2693,41 @@ void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct bo->id = 0; }
+bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizeiptr size, + GLenum binding, GLenum usage, bool coherent, struct wined3d_bo_gl *bo) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + GLuint id = 0; + + TRACE("context_gl %p, size %lu, binding %#x, usage %#x, coherent %#x, bo %p.\n", + context_gl, size, binding, usage, coherent, 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)); + } + + 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->binding = binding; + bo->usage = usage; + 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/texture.c b/dlls/wined3d/texture.c index 73821cc27a9..b311df0f896 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1913,26 +1913,22 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, unsig }
/* Context activation is done by the caller. */ -static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture, - unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) +static void wined3d_texture_gl_prepare_buffer_object(struct wined3d_texture_gl *texture_gl, + unsigned int sub_resource_idx, struct wined3d_context_gl *context_gl) { struct wined3d_texture_sub_resource *sub_resource; struct wined3d_bo_gl *bo;
- sub_resource = &texture->sub_resources[sub_resource_idx]; + sub_resource = &texture_gl->t.sub_resources[sub_resource_idx]; bo = &sub_resource->bo; if (bo->id) return;
- GL_EXTCALL(glGenBuffers(1, &bo->id)); - bo->binding = GL_PIXEL_UNPACK_BUFFER; - bo->usage = GL_STREAM_DRAW; - GL_EXTCALL(glBindBuffer(bo->binding, bo->id)); - GL_EXTCALL(glBufferData(bo->binding, sub_resource->size, NULL, bo->usage)); - GL_EXTCALL(glBindBuffer(bo->binding, 0)); - checkGLcall("Create buffer object"); + if (!wined3d_context_gl_create_bo(context_gl, sub_resource->size, + GL_PIXEL_UNPACK_BUFFER, GL_STREAM_DRAW, true, bo)) + return;
- TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", bo->id, texture, sub_resource_idx); + TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", bo->id, texture_gl, sub_resource_idx); }
static void wined3d_texture_force_reload(struct wined3d_texture *texture) @@ -3135,7 +3131,7 @@ static BOOL wined3d_texture_gl_prepare_location(struct wined3d_texture *texture, : wined3d_resource_prepare_sysmem(&texture->resource);
case WINED3D_LOCATION_BUFFER: - wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context_gl->gl_info); + wined3d_texture_gl_prepare_buffer_object(texture_gl, sub_resource_idx, context_gl); return TRUE;
case WINED3D_LOCATION_TEXTURE_RGB: diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index bf4c9ca5af1..1d77b0e44fb 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -1405,25 +1405,21 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object) if (resource->type == WINED3D_RTYPE_BUFFER) { struct wined3d_buffer *buffer = buffer_from_resource(resource); - struct wined3d_context *context; + struct wined3d_context_gl *context_gl;
- context = context_acquire(resource->device, NULL, 0); - gl_info = wined3d_context_gl(context)->gl_info; - create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_gl->v.format); + context_gl = wined3d_context_gl(context_acquire(resource->device, NULL, 0)); + gl_info = context_gl->gl_info; + create_buffer_view(&view_gl->gl_view, &context_gl->c, desc, buffer, view_gl->v.format); if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND)) { struct wined3d_bo_gl *bo = &view_gl->counter_bo; - static const GLuint initial_value = 0; - - GL_EXTCALL(glGenBuffers(1, &bo->id)); - bo->binding = GL_ATOMIC_COUNTER_BUFFER; - bo->usage = GL_STATIC_DRAW; - GL_EXTCALL(glBindBuffer(bo->binding, bo->id)); - GL_EXTCALL(glBufferData(bo->binding, sizeof(initial_value), &initial_value, bo->usage)); - checkGLcall("create atomic counter buffer"); + view_gl->v.counter_bo = (uintptr_t)bo; + wined3d_context_gl_create_bo(context_gl, sizeof(uint32_t), + GL_ATOMIC_COUNTER_BUFFER, GL_STATIC_DRAW, true, bo); + wined3d_unordered_access_view_set_counter(&view_gl->v, 0); } - context_release(context); + context_release(&context_gl->c); } else { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index dbdb10a182a..9b12295ec52 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2256,6 +2256,8 @@ void wined3d_context_gl_bind_texture(struct wined3d_context_gl *context_gl, void wined3d_context_gl_check_fbo_status(const struct wined3d_context_gl *context_gl, GLenum target) DECLSPEC_HIDDEN; 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, size_t size) DECLSPEC_HIDDEN; +bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizeiptr size, + GLenum binding, GLenum usage, bool coherent, 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,