wined3d: Allocate a new bo for busy DISCARD maps.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2020-12-04 18:15:33 +03:30 committed by Alexandre Julliard
parent 4c5581c2eb
commit 8b3cc57df0
6 changed files with 95 additions and 44 deletions

View File

@ -4867,6 +4867,7 @@ static void adapter_gl_destroy_shader_resource_view(struct wined3d_shader_resour
* the refcount on a device that's in the process of being destroyed. */
if (swapchain_count)
wined3d_device_incref(device);
list_remove(&view_gl->bo_user.entry);
wined3d_shader_resource_view_cleanup(&view_gl->v);
wined3d_view_gl_destroy(device, &view_gl->gl_view, NULL, view_gl);
if (swapchain_count)
@ -4913,6 +4914,7 @@ static void adapter_gl_destroy_unordered_access_view(struct wined3d_unordered_ac
* the refcount on a device that's in the process of being destroyed. */
if (swapchain_count)
wined3d_device_incref(device);
list_remove(&view_gl->bo_user.entry);
wined3d_unordered_access_view_cleanup(&view_gl->v);
wined3d_view_gl_destroy(device, &view_gl->gl_view, &view_gl->counter_bo, view_gl);
if (swapchain_count)

View File

@ -714,29 +714,6 @@ void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer)
return buffer->resource.parent;
}
/* The caller provides a context and binds the buffer */
static void wined3d_buffer_gl_sync_apple(struct wined3d_buffer_gl *buffer_gl,
uint32_t flags, struct wined3d_context_gl *context_gl)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
struct wined3d_bo_gl *bo = &buffer_gl->bo;
/* No fencing needs to be done if the app promises not to overwrite
* existing data. */
if (flags & WINED3D_MAP_NOOVERWRITE)
return;
if (flags & WINED3D_MAP_DISCARD)
{
wined3d_buffer_gl_bind(buffer_gl, context_gl);
GL_EXTCALL(glBufferData(bo->binding, buffer_gl->b.resource.size, NULL, bo->usage));
checkGLcall("glBufferData");
bo->command_fence_id = 0;
return;
}
}
static void buffer_mark_used(struct wined3d_buffer *buffer)
{
buffer->flags &= ~WINED3D_BUFFER_DISCARD;
@ -954,9 +931,6 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
if (buffer->flags & WINED3D_BUFFER_DISCARD)
flags &= ~WINED3D_MAP_DISCARD;
if (buffer->flags & WINED3D_BUFFER_APPLESYNC)
wined3d_buffer_gl_sync_apple(wined3d_buffer_gl(buffer), flags, wined3d_context_gl(context));
addr.buffer_object = buffer->buffer_object;
addr.addr = 0;
buffer->map_ptr = wined3d_context_map_bo_address(context, &addr, resource->size, flags);

View File

@ -2650,20 +2650,39 @@ void wined3d_context_gl_submit_command_fence(struct wined3d_context_gl *context_
wined3d_context_gl_poll_fences(context_gl);
}
void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl,
const struct wined3d_bo_address *data, size_t size, uint32_t flags)
static void *wined3d_bo_gl_map(struct wined3d_bo_gl *bo,
struct wined3d_context_gl *context_gl, size_t offset, size_t size, uint32_t flags)
{
struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
const struct wined3d_gl_info *gl_info;
struct wined3d_bo_gl *bo;
BYTE *memory;
struct wined3d_bo_user *bo_user;
struct wined3d_bo_gl tmp;
uint8_t *map_ptr;
if (!(bo = (struct wined3d_bo_gl *)data->buffer_object))
return data->addr;
if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
if (flags & WINED3D_MAP_NOOVERWRITE)
goto map;
if ((flags & WINED3D_MAP_DISCARD) && bo->command_fence_id > device_gl->completed_fence_id)
{
if (wined3d_context_gl_create_bo(context_gl, bo->size,
bo->binding, bo->usage, bo->coherent, bo->flags, &tmp))
{
list_move_head(&tmp.users, &bo->users);
wined3d_context_gl_destroy_bo(context_gl, bo);
*bo = tmp;
list_init(&bo->users);
list_move_head(&bo->users, &tmp.users);
LIST_FOR_EACH_ENTRY(bo_user, &bo->users, struct wined3d_bo_user, entry)
{
bo_user->valid = false;
}
goto map;
}
ERR("Failed to create new buffer object.\n");
}
if (bo->command_fence_id == device_gl->current_fence_id)
wined3d_context_gl_submit_command_fence(context_gl);
wined3d_context_gl_wait_command_fence(context_gl, bo->command_fence_id);
@ -2674,19 +2693,33 @@ map:
if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
{
memory = GL_EXTCALL(glMapBufferRange(bo->binding, (INT_PTR)data->addr,
size, wined3d_resource_gl_map_flags(flags)));
map_ptr = GL_EXTCALL(glMapBufferRange(bo->binding, offset, size, wined3d_resource_gl_map_flags(flags)));
}
else
{
memory = GL_EXTCALL(glMapBuffer(bo->binding, wined3d_resource_gl_legacy_map_flags(flags)));
memory += (INT_PTR)data->addr;
map_ptr = GL_EXTCALL(glMapBuffer(bo->binding, wined3d_resource_gl_legacy_map_flags(flags)));
map_ptr += offset;
}
wined3d_context_gl_bind_bo(context_gl, bo->binding, 0);
checkGLcall("Map buffer object");
return memory;
return map_ptr;
}
void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl,
const struct wined3d_bo_address *data, size_t size, uint32_t flags)
{
struct wined3d_bo_gl *bo;
void *map_ptr;
if (!(bo = (struct wined3d_bo_gl *)data->buffer_object))
return data->addr;
if (!(map_ptr = wined3d_bo_gl_map(bo, context_gl, (uintptr_t)data->addr, size, flags)))
ERR("Failed to map bo.\n");
return map_ptr;
}
void wined3d_context_gl_unmap_bo_address(struct wined3d_context_gl *context_gl,
@ -2821,8 +2854,11 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
TRACE("Created buffer object %u.\n", id);
bo->id = id;
bo->size = size;
bo->binding = binding;
bo->usage = usage;
bo->flags = flags;
bo->coherent = coherent;
list_init(&bo->users);
bo->command_fence_id = 0;
@ -3698,6 +3734,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
const struct wined3d_state *state, unsigned int shader_mask)
{
struct wined3d_shader_sampler_map_entry *entry;
struct wined3d_shader_resource_view_gl *srv_gl;
struct wined3d_shader_resource_view *view;
struct wined3d_buffer_gl *buffer_gl;
struct wined3d_shader *shader;
@ -3735,6 +3772,10 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
buffer_gl = wined3d_buffer_gl(buffer_from_resource(view->resource));
wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
srv_gl = wined3d_shader_resource_view_gl(view);
if (!srv_gl->bo_user.valid)
wined3d_shader_resource_view_gl_update(srv_gl, context_gl);
}
else
{
@ -3747,6 +3788,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
static void context_gl_load_unordered_access_resources(struct wined3d_context_gl *context_gl,
const struct wined3d_shader *shader, struct wined3d_unordered_access_view * const *views)
{
struct wined3d_unordered_access_view_gl *uav_gl;
struct wined3d_unordered_access_view *view;
struct wined3d_buffer_gl *buffer_gl;
struct wined3d_texture *texture;
@ -3768,6 +3810,10 @@ static void context_gl_load_unordered_access_resources(struct wined3d_context_gl
wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
uav_gl = wined3d_unordered_access_view_gl(view);
if (!uav_gl->bo_user.valid)
wined3d_unordered_access_view_gl_update(uav_gl, context_gl);
}
else
{

View File

@ -451,12 +451,9 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags)
ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
if (d3d_flags & WINED3D_MAP_READ)
ret |= GL_MAP_READ_BIT;
else if (!(d3d_flags & WINED3D_MAP_DISCARD))
else
ret |= GL_MAP_UNSYNCHRONIZED_BIT;
if (d3d_flags & WINED3D_MAP_DISCARD)
ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
return ret;
}

View File

@ -268,7 +268,8 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c
wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
view->target = GL_TEXTURE_BUFFER;
gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
if (!view->name)
gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_BUFFER, view->name);
if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE])
@ -916,6 +917,14 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader
return view->parent;
}
void wined3d_shader_resource_view_gl_update(struct wined3d_shader_resource_view_gl *srv_gl,
struct wined3d_context_gl *context_gl)
{
create_buffer_view(&srv_gl->gl_view, &context_gl->c, &srv_gl->v.desc,
buffer_from_resource(srv_gl->v.resource), srv_gl->v.format);
srv_gl->bo_user.valid = true;
}
static void wined3d_shader_resource_view_gl_cs_init(void *object)
{
struct wined3d_shader_resource_view_gl *view_gl = object;
@ -936,6 +945,8 @@ static void wined3d_shader_resource_view_gl_cs_init(void *object)
context = context_acquire(resource->device, NULL, 0);
create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_format);
view_gl->bo_user.valid = true;
list_add_head(&wined3d_buffer_gl(buffer)->bo.users, &view_gl->bo_user.entry);
context_release(context);
}
else
@ -1006,6 +1017,7 @@ HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view
if (FAILED(hr = wined3d_shader_resource_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
return hr;
list_init(&view_gl->bo_user.entry);
wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_gl_cs_init, view_gl);
return hr;
@ -1394,6 +1406,14 @@ void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_
wined3d_buffer_invalidate_location(buffer, ~dst_location);
}
void wined3d_unordered_access_view_gl_update(struct wined3d_unordered_access_view_gl *uav_gl,
struct wined3d_context_gl *context_gl)
{
create_buffer_view(&uav_gl->gl_view, &context_gl->c, &uav_gl->v.desc,
buffer_from_resource(uav_gl->v.resource), uav_gl->v.format);
uav_gl->bo_user.valid = true;
}
static void wined3d_unordered_access_view_gl_cs_init(void *object)
{
struct wined3d_unordered_access_view_gl *view_gl = object;
@ -1410,6 +1430,8 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object)
context_gl = wined3d_context_gl(context_acquire(resource->device, 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(&wined3d_buffer_gl(buffer)->bo.users, &view_gl->bo_user.entry);
if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
{
struct wined3d_bo_gl *bo = &view_gl->counter_bo;
@ -1470,6 +1492,7 @@ HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_vi
if (FAILED(hr = wined3d_unordered_access_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
return hr;
list_init(&view_gl->bo_user.entry);
wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_gl_cs_init, view_gl);
return hr;

View File

@ -1572,9 +1572,12 @@ do { \
struct wined3d_bo_gl
{
GLuint id;
GLsizeiptr size;
GLenum binding;
GLenum usage;
GLbitfield flags;
bool coherent;
struct list users;
uint64_t command_fence_id;
};
@ -5014,6 +5017,7 @@ void shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view *
struct wined3d_shader_resource_view_gl
{
struct wined3d_shader_resource_view v;
struct wined3d_bo_user bo_user;
struct wined3d_gl_view gl_view;
};
@ -5028,6 +5032,8 @@ void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl
HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view_gl *view_gl,
const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
void wined3d_shader_resource_view_gl_update(struct wined3d_shader_resource_view_gl *srv_gl,
struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
struct wined3d_view_vk
{
@ -5083,6 +5089,7 @@ void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_v
struct wined3d_unordered_access_view_gl
{
struct wined3d_unordered_access_view v;
struct wined3d_bo_user bo_user;
struct wined3d_gl_view gl_view;
struct wined3d_bo_gl counter_bo;
};
@ -5098,6 +5105,8 @@ void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access
HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_view_gl *view_gl,
const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
void wined3d_unordered_access_view_gl_update(struct wined3d_unordered_access_view_gl *uav_gl,
struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
struct wined3d_unordered_access_view_vk
{