[PATCH 1/4] wined3d: Use the "bo user" mechanism to invalidate existing bindings in wined3d_buffer_gl_destroy_buffer_object().
Henri Verbeet
hverbeet at codeweavers.com
Fri Dec 4 08:45:32 CST 2020
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 6 ++---
dlls/wined3d/buffer.c | 47 +++++++++-------------------------
dlls/wined3d/context_gl.c | 20 ++++++++++++---
dlls/wined3d/state.c | 36 ++++++++++++++++++--------
dlls/wined3d/wined3d_private.h | 8 +++---
5 files changed, 62 insertions(+), 55 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 3fb9e4ce4b4..3da1615b1b5 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -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;
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 5dbc66449f4..e179f202cb8 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -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 (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);
- }
- }
+ if (context_gl->c.transform_feedback_active && resource->bind_count
+ && resource->bind_flags & WINED3D_BIND_STREAM_OUTPUT)
+ {
+ /* 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);
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 406b325cda8..305ca0507ff 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -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;
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 71f7ac53a2f..e40c23daf03 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -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");
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 67caf98ead7..67a55c4dedd 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -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;
--
2.20.1
More information about the wine-devel
mailing list