wined3d: Introduce wined3d_context_gl_create_bo().

Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Matteo Bruni 2020-11-30 18:11:23 +03:30 committed by Alexandre Julliard
parent db42859977
commit 90f33067da
5 changed files with 71 additions and 83 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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:

View File

@ -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
{

View File

@ -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,