1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

wined3d: Remove BO users from the list when invalidating them.

This makes it easier to invalidate in the case where multiple resources share
the same BO, which in turn is necessary to implement copy-on-write semantics for
BOs.

This is also necessary if we ever want to evict resources which have views,
although it's not clear if this will ever be necessary. If nothing else, though,
it removes that implicit dependency.
This commit is contained in:
Zebediah Figura 2023-07-17 19:36:54 -05:00 committed by Alexandre Julliard
parent 8b5a3bc832
commit b2f13103d7
8 changed files with 62 additions and 39 deletions

View file

@ -921,16 +921,15 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
if (wined3d_context_vk_create_bo(context_vk, bo->size, bo->usage, bo->memory_type, &tmp))
{
bool host_synced = bo->host_synced;
list_move_head(&tmp.b.users, &bo->b.users);
LIST_FOR_EACH_ENTRY(bo_user, &bo->b.users, struct wined3d_bo_user, entry)
bo_user->valid = false;
list_init(&bo->b.users);
wined3d_context_vk_destroy_bo(context_vk, bo);
*bo = tmp;
bo->host_synced = host_synced;
list_init(&bo->b.users);
list_move_head(&bo->b.users, &tmp.b.users);
LIST_FOR_EACH_ENTRY(bo_user, &bo->b.users, struct wined3d_bo_user, entry)
{
bo_user->valid = false;
}
goto map;
}

View file

@ -194,8 +194,11 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu
wined3d_context_gl_end_transform_feedback(context_gl);
}
buffer_gl->b.bo_user.valid = false;
list_remove(&buffer_gl->b.bo_user.entry);
if (buffer_gl->b.bo_user.valid)
{
buffer_gl->b.bo_user.valid = false;
list_remove(&buffer_gl->b.bo_user.entry);
}
wined3d_context_gl_destroy_bo(context_gl, bo_gl);
heap_free(bo_gl);
buffer_gl->b.buffer_object = NULL;
@ -237,7 +240,6 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
return FALSE;
}
list_add_head(&bo->b.users, &buffer_gl->b.bo_user.entry);
buffer_gl->b.buffer_object = &bo->b;
buffer_invalidate_bo_range(&buffer_gl->b, 0, 0);
@ -1127,16 +1129,13 @@ static void wined3d_buffer_set_bo(struct wined3d_buffer *buffer, struct wined3d_
LIST_FOR_EACH_ENTRY(bo_user, &prev_bo->users, struct wined3d_bo_user, entry)
bo_user->valid = false;
list_init(&prev_bo->users);
assert(list_empty(&bo->users));
list_move_head(&bo->users, &prev_bo->users);
wined3d_context_destroy_bo(context, prev_bo);
heap_free(prev_bo);
}
else
{
list_add_head(&bo->users, &buffer->bo_user.entry);
}
buffer->buffer_object = bo;
}
@ -1516,8 +1515,6 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
return FALSE;
}
list_init(&buffer_vk->b.bo_user.entry);
list_add_head(&bo_vk->b.users, &buffer_vk->b.bo_user.entry);
buffer_vk->b.buffer_object = &bo_vk->b;
buffer_invalidate_bo_range(&buffer_vk->b, 0, 0);
@ -1534,7 +1531,7 @@ const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_b
buffer_vk->buffer_info.buffer = bo->vk_buffer;
buffer_vk->buffer_info.offset = bo->b.buffer_offset;
buffer_vk->buffer_info.range = buffer_vk->b.resource.size;
buffer_vk->b.bo_user.valid = true;
wined3d_buffer_validate_user(&buffer_vk->b);
return &buffer_vk->buffer_info;
}
@ -1570,8 +1567,11 @@ static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer,
switch (location)
{
case WINED3D_LOCATION_BUFFER:
buffer->bo_user.valid = false;
list_remove(&buffer->bo_user.entry);
if (buffer->bo_user.valid)
{
buffer->bo_user.valid = false;
list_remove(&buffer->bo_user.entry);
}
wined3d_context_vk_destroy_bo(context_vk, bo_vk);
heap_free(bo_vk);
buffer->buffer_object = NULL;

View file

@ -2859,15 +2859,13 @@ static void *wined3d_bo_gl_map(struct wined3d_bo_gl *bo, struct wined3d_context_
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);
LIST_FOR_EACH_ENTRY(bo_user, &bo->b.users, struct wined3d_bo_user, entry)
bo_user->valid = false;
list_init(&bo->b.users);
wined3d_context_gl_destroy_bo(context_gl, bo);
*bo = tmp;
list_init(&bo->b.users);
list_move_head(&bo->b.users, &tmp.b.users);
LIST_FOR_EACH_ENTRY(bo_user, &bo->b.users, struct wined3d_bo_user, entry)
{
bo_user->valid = false;
}
goto map;
}
@ -3153,6 +3151,8 @@ void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct
TRACE("context_gl %p, bo %p.\n", context_gl, bo);
assert(list_empty(&bo->b.users));
if (bo->memory)
{
unsigned int order = bo->memory->order;
@ -5421,7 +5421,7 @@ void wined3d_context_gl_load_tex_coords(const struct wined3d_context_gl *context
gl_info->gl_ops.gl.p_glTexCoordPointer(format_gl->vtx_format, format_gl->vtx_type, e->stride,
get_vertex_attrib_pointer(e, state));
gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
state->streams[e->stream_idx].buffer->bo_user.valid = true;
wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer);
}
else
{
@ -5508,7 +5508,7 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte
checkGLcall("glVertexPointer(...)");
gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
state->streams[e->stream_idx].buffer->bo_user.valid = true;
wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer);
}
/* Normals */
@ -5531,7 +5531,7 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte
checkGLcall("glNormalPointer(...)");
gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
state->streams[e->stream_idx].buffer->bo_user.valid = true;
wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer);
}
else
{
@ -5560,7 +5560,7 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte
checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
state->streams[e->stream_idx].buffer->bo_user.valid = true;
wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer);
}
else
{
@ -5624,7 +5624,7 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte
}
gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
state->streams[e->stream_idx].buffer->bo_user.valid = true;
wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer);
}
else
{
@ -5725,7 +5725,7 @@ static void wined3d_context_gl_load_numbered_arrays(struct wined3d_context_gl *c
format_gl = wined3d_format_gl(element->format);
stream = &state->streams[element->stream_idx];
stream->buffer->bo_user.valid = true;
wined3d_buffer_validate_user(stream->buffer);
if (gl_info->supported[ARB_INSTANCED_ARRAYS])

View file

@ -1080,6 +1080,8 @@ void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const
TRACE("context_vk %p, bo %p.\n", context_vk, bo);
assert(list_empty(&bo->b.users));
if (bo->command_buffer_id == context_vk->current_command_buffer.id)
context_vk->retired_bo_size += bo->size;

View file

@ -4264,7 +4264,7 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st
if (buffer->buffer_object)
{
GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wined3d_bo_gl(buffer->buffer_object)->id));
buffer->bo_user.valid = true;
wined3d_buffer_validate_user(buffer);
}
else
{
@ -4394,7 +4394,7 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state
bo_gl->id, bo_gl->b.buffer_offset + buffer_state->offset,
min(buffer_state->size, buffer->resource.size - buffer_state->offset)));
buffer->bo_user.valid = true;
wined3d_buffer_validate_user(buffer);
}
checkGLcall("bind constant buffers");
}
@ -4471,7 +4471,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
size = buffer->resource.size - offset;
GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i,
bo_gl->id, bo_gl->b.buffer_offset + offset, size));
buffer->bo_user.valid = true;
wined3d_buffer_validate_user(buffer);
}
checkGLcall("bind transform feedback buffers");
}

View file

@ -4649,8 +4649,9 @@ static void wined3d_texture_set_bo(struct wined3d_texture *texture,
LIST_FOR_EACH_ENTRY(bo_user, &prev_bo->users, struct wined3d_bo_user, entry)
bo_user->valid = false;
list_init(&prev_bo->users);
assert(list_empty(&bo->users));
list_move_head(&bo->users, &prev_bo->users);
wined3d_context_destroy_bo(context, prev_bo);
heap_free(prev_bo);

View file

@ -997,9 +997,13 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader
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);
struct wined3d_buffer *buffer = buffer_from_resource(srv_gl->v.resource);
assert(!srv_gl->bo_user.valid);
create_buffer_view(&srv_gl->gl_view, &context_gl->c, &srv_gl->v.desc, buffer, srv_gl->v.format);
srv_gl->bo_user.valid = true;
list_add_head(&buffer->buffer_object->users, &srv_gl->bo_user.entry);
}
static void wined3d_shader_resource_view_gl_cs_init(void *object)
@ -1112,12 +1116,15 @@ void wined3d_shader_resource_view_vk_update_buffer(struct wined3d_shader_resourc
struct wined3d_buffer_vk *buffer_vk;
VkBufferView vk_buffer_view;
assert(!view_vk->bo_user.valid);
buffer_vk = wined3d_buffer_vk(buffer_from_resource(resource));
wined3d_context_vk_destroy_vk_buffer_view(context_vk, view_vk->u.vk_buffer_view, view_vk->command_buffer_id);
if ((vk_buffer_view = wined3d_view_vk_create_vk_buffer_view(context_vk, desc, buffer_vk, view_format_vk)))
{
view_vk->u.vk_buffer_view = vk_buffer_view;
view_vk->bo_user.valid = true;
list_add_head(&buffer_vk->b.buffer_object->users, &view_vk->bo_user.entry);
}
}
@ -1715,9 +1722,12 @@ void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_
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);
struct wined3d_buffer *buffer = buffer_from_resource(uav_gl->v.resource);
assert(!uav_gl->bo_user.valid);
create_buffer_view(&uav_gl->gl_view, &context_gl->c, &uav_gl->v.desc, buffer, uav_gl->v.format);
uav_gl->bo_user.valid = true;
list_add_head(&buffer->buffer_object->users, &uav_gl->bo_user.entry);
}
static void wined3d_unordered_access_view_gl_cs_init(void *object)
@ -2280,12 +2290,15 @@ void wined3d_unordered_access_view_vk_update(struct wined3d_unordered_access_vie
struct wined3d_buffer_vk *buffer_vk;
VkBufferView vk_buffer_view;
assert(!view_vk->bo_user.valid);
buffer_vk = wined3d_buffer_vk(buffer_from_resource(resource));
wined3d_context_vk_destroy_vk_buffer_view(context_vk, view_vk->u.vk_buffer_view, view_vk->command_buffer_id);
if ((vk_buffer_view = wined3d_view_vk_create_vk_buffer_view(context_vk, desc, buffer_vk, view_format_vk)))
{
view_vk->u.vk_buffer_view = vk_buffer_view;
view_vk->bo_user.valid = true;
list_add_head(&buffer_vk->b.buffer_object->users, &view_vk->bo_user.entry);
}
}

View file

@ -4394,6 +4394,14 @@ static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resourc
return CONTAINING_RECORD(resource, struct wined3d_buffer, resource);
}
static inline void wined3d_buffer_validate_user(struct wined3d_buffer *buffer)
{
if (buffer->bo_user.valid)
return;
buffer->bo_user.valid = true;
list_add_head(&buffer->buffer_object->users, &buffer->bo_user.entry);
}
void wined3d_buffer_cleanup(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN;
void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset,
struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) DECLSPEC_HIDDEN;