wined3d: Use the "bo user" mechanism to invalidate existing bindings in wined3d_buffer_gl_destroy_buffer_object().

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:32 +03:30 committed by Alexandre Julliard
parent 38d9020f29
commit 4c5581c2eb
5 changed files with 61 additions and 54 deletions

View File

@ -860,10 +860,10 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
{
struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
const struct wined3d_vk_info *vk_info;
struct wined3d_bo_user_vk *bo_user_vk;
struct wined3d_device_vk *device_vk;
VkCommandBuffer vk_command_buffer;
VkBufferMemoryBarrier vk_barrier;
struct wined3d_bo_user *bo_user;
struct wined3d_bo_vk *bo, tmp;
VkMappedMemoryRange range;
void *map_ptr;
@ -886,9 +886,9 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
*bo = tmp;
list_init(&bo->users);
list_move_head(&bo->users, &tmp.users);
LIST_FOR_EACH_ENTRY(bo_user_vk, &bo->users, struct wined3d_bo_user_vk, entry)
LIST_FOR_EACH_ENTRY(bo_user, &bo->users, struct wined3d_bo_user, entry)
{
bo_user_vk->valid = false;
bo_user->valid = false;
}
goto map;

View File

@ -143,47 +143,22 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu
struct wined3d_context_gl *context_gl)
{
struct wined3d_resource *resource = &buffer_gl->b.resource;
struct wined3d_buffer *buffer = &buffer_gl->b;
struct wined3d_cs *cs = resource->device->cs;
if (!buffer_gl->b.buffer_object)
return;
/* The stream source state handler might have read the memory of the
* vertex buffer already and got the memory in the vbo which is not
* valid any longer. Dirtify the stream source to force a reload. This
* happens only once per changed vertexbuffer and should occur rather
* rarely. */
if (resource->bind_count)
if (context_gl->c.transform_feedback_active && resource->bind_count
&& resource->bind_flags & WINED3D_BIND_STREAM_OUTPUT)
{
if (resource->bind_flags & WINED3D_BIND_VERTEX_BUFFER)
device_invalidate_state(resource->device, STATE_STREAMSRC);
if (resource->bind_flags & WINED3D_BIND_INDEX_BUFFER
&& cs->state.index_buffer == buffer)
device_invalidate_state(resource->device, STATE_INDEXBUFFER);
if (resource->bind_flags & WINED3D_BIND_CONSTANT_BUFFER)
{
device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX));
device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL));
device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN));
device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY));
device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL));
device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE));
}
if (resource->bind_flags & WINED3D_BIND_STREAM_OUTPUT)
{
device_invalidate_state(resource->device, STATE_STREAM_OUTPUT);
if (context_gl->c.transform_feedback_active)
{
/* We have to make sure that transform feedback is not active
* when deleting a potentially bound transform feedback buffer.
* This may happen when the device is being destroyed. */
WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer_gl);
wined3d_context_gl_end_transform_feedback(context_gl);
}
}
/* We have to make sure that transform feedback is not active
* when deleting a potentially bound transform feedback buffer.
* This may happen when the device is being destroyed. */
WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer_gl);
wined3d_context_gl_end_transform_feedback(context_gl);
}
buffer_gl->bo_user.valid = false;
list_remove(&buffer_gl->bo_user.entry);
wined3d_context_gl_destroy_bo(context_gl, &buffer_gl->bo);
buffer_gl->b.buffer_object = 0;
@ -225,6 +200,8 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
if (!coherent && gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
buffer_gl->b.flags |= WINED3D_BUFFER_APPLESYNC;
list_init(&buffer_gl->bo_user.entry);
list_add_head(&buffer_gl->bo.users, &buffer_gl->bo_user.entry);
buffer_gl->b.buffer_object = (uintptr_t)bo;
buffer_invalidate_bo_range(&buffer_gl->b, 0, 0);

View File

@ -2823,6 +2823,7 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
bo->id = id;
bo->binding = binding;
bo->usage = usage;
list_init(&bo->users);
bo->command_fence_id = 0;
return true;
@ -3718,6 +3719,8 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
buffer_gl = wined3d_buffer_gl(state->cb[i][j]);
wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
if (!buffer_gl->bo_user.valid)
device_invalidate_state(context_gl->c.device, STATE_CONSTANT_BUFFER(i));
}
for (j = 0; j < shader->reg_maps.sampler_map.count; ++j)
@ -3793,6 +3796,8 @@ static void context_gl_load_stream_output_buffers(struct wined3d_context_gl *con
wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state);
wined3d_buffer_invalidate_location(&buffer_gl->b, ~WINED3D_LOCATION_BUFFER);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
if (!buffer_gl->bo_user.valid)
device_invalidate_state(context_gl->c.device, STATE_STREAM_OUTPUT);
}
}
@ -3848,7 +3853,10 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
e = &context->stream_info.elements[wined3d_bit_scan(&map)];
buffer_gl = wined3d_buffer_gl(state->streams[e->stream_idx].buffer);
wined3d_buffer_load(&buffer_gl->b, context, state);
if (!buffer_gl->bo_user.valid)
device_invalidate_state(device, STATE_STREAMSRC);
else
wined3d_buffer_load(&buffer_gl->b, context, state);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
}
/* Loading the buffers above may have invalidated the stream info. */
@ -3862,6 +3870,8 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
if (context->stream_info.all_vbo)
{
wined3d_buffer_load(&buffer_gl->b, context, state);
if (!buffer_gl->bo_user.valid)
device_invalidate_state(device, STATE_INDEXBUFFER);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
}
else
@ -4989,6 +4999,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,
e->data.addr + state->load_base_vertex_index * e->stride);
gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
wined3d_buffer_gl(state->streams[e->stream_idx].buffer)->bo_user.valid = true;
}
else
{
@ -5077,6 +5088,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)");
wined3d_buffer_gl(state->streams[e->stream_idx].buffer)->bo_user.valid = true;
}
/* Normals */
@ -5100,7 +5112,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)");
wined3d_buffer_gl(state->streams[e->stream_idx].buffer)->bo_user.valid = true;
}
else
{
@ -5130,7 +5142,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)");
wined3d_buffer_gl(state->streams[e->stream_idx].buffer)->bo_user.valid = true;
}
else
{
@ -5199,6 +5211,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)");
wined3d_buffer_gl(state->streams[e->stream_idx].buffer)->bo_user.valid = true;
}
else
{
@ -5292,6 +5305,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];
wined3d_buffer_gl(stream->buffer)->bo_user.valid = true;
if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count)
context->instance_count = state->streams[0].frequency;

View File

@ -4452,12 +4452,17 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st
{
const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
const struct wined3d_stream_info *stream_info = &context->stream_info;
const struct wined3d_buffer *ib = state->index_buffer;
struct wined3d_buffer_gl *buffer_gl;
if (!ib || !stream_info->all_vbo)
if (!state->index_buffer || !stream_info->all_vbo)
{
GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
else
GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wined3d_buffer_gl_const(ib)->bo.id));
return;
}
buffer_gl = wined3d_buffer_gl(state->index_buffer);
GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_gl->bo.id));
buffer_gl->bo_user.valid = true;
}
static void depth_clip(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info)
@ -4550,7 +4555,7 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state
{
const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
enum wined3d_shader_type shader_type;
struct wined3d_buffer *buffer;
struct wined3d_buffer_gl *buffer_gl;
unsigned int i, base, count;
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
@ -4563,8 +4568,15 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state
wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, shader_type, &base, &count);
for (i = 0; i < count; ++i)
{
buffer = state->cb[shader_type][i];
GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, buffer ? wined3d_buffer_gl(buffer)->bo.id : 0));
if (!state->cb[shader_type][i])
{
GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, 0));
continue;
}
buffer_gl = wined3d_buffer_gl(state->cb[shader_type][i]);
GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, buffer_gl->bo.id));
buffer_gl->bo_user.valid = true;
}
checkGLcall("bind constant buffers");
}
@ -4614,7 +4626,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
{
struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
struct wined3d_buffer *buffer;
struct wined3d_buffer_gl *buffer_gl;
unsigned int offset, size, i;
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
@ -4623,20 +4635,22 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i)
{
if (!(buffer = state->stream_output[i].buffer))
if (!state->stream_output[i].buffer)
{
GL_EXTCALL(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, 0));
continue;
}
buffer_gl = wined3d_buffer_gl(state->stream_output[i].buffer);
offset = state->stream_output[i].offset;
if (offset == ~0u)
{
FIXME("Appending to stream output buffers not implemented.\n");
offset = 0;
}
size = buffer->resource.size - offset;
GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, wined3d_buffer_gl(buffer)->bo.id, offset, size));
size = buffer_gl->b.resource.size - offset;
GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, buffer_gl->bo.id, offset, size));
buffer_gl->bo_user.valid = true;
}
checkGLcall("bind transform feedback buffers");
}

View File

@ -1575,6 +1575,7 @@ struct wined3d_bo_gl
GLenum binding;
GLenum usage;
struct list users;
uint64_t command_fence_id;
};
@ -1583,7 +1584,7 @@ static inline GLuint wined3d_bo_gl_id(uintptr_t bo)
return bo ? ((struct wined3d_bo_gl *)bo)->id : 0;
}
struct wined3d_bo_user_vk
struct wined3d_bo_user
{
struct list entry;
bool valid;
@ -4875,6 +4876,7 @@ struct wined3d_buffer_gl
struct wined3d_buffer b;
struct wined3d_bo_gl bo;
struct wined3d_bo_user bo_user;
};
static inline struct wined3d_buffer_gl *wined3d_buffer_gl(struct wined3d_buffer *buffer)
@ -4898,7 +4900,7 @@ struct wined3d_buffer_vk
struct wined3d_buffer b;
struct wined3d_bo_vk bo;
struct wined3d_bo_user_vk bo_user;
struct wined3d_bo_user bo_user;
VkDescriptorBufferInfo buffer_info;
};
@ -5029,7 +5031,7 @@ HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view
struct wined3d_view_vk
{
struct wined3d_bo_user_vk bo_user;
struct wined3d_bo_user bo_user;
union
{
VkBufferView vk_buffer_view;