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:
parent
8b5a3bc832
commit
b2f13103d7
8 changed files with 62 additions and 39 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue