[PATCH 3/5] wined3d: Introduce wined3d_context_gl_create_bo().

Henri Verbeet hverbeet at codeweavers.com
Mon Nov 30 08:41:23 CST 2020


From: Matteo Bruni <mbruni at codeweavers.com>

Signed-off-by: Henri Verbeet <hverbeet at 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,
-- 
2.20.1




More information about the wine-devel mailing list