Commit b2f13103 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

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.
parent 8b5a3bc8
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment