It may load buffers into a different location.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/context_gl.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index d2dd9e0bd09..09c871efcd4 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3963,12 +3963,23 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, 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. */ if (wined3d_context_is_graphics_state_dirty(context, STATE_STREAMSRC)) context_update_stream_info(context, state);
+ map = context->stream_info.use_map; + while (map) + { + const struct wined3d_stream_info_element *e; + struct wined3d_buffer_gl *buffer_gl; + + e = &context->stream_info.elements[wined3d_bit_scan(&map)]; + buffer_gl = wined3d_buffer_gl(state->streams[e->stream_idx].buffer); + + wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + } + if (indexed && state->index_buffer) { struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(state->index_buffer);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/adapter_vk.c | 4 ++-- dlls/wined3d/buffer.c | 24 ++++++++++++------------ dlls/wined3d/context_vk.c | 8 ++++---- dlls/wined3d/cs.c | 2 +- dlls/wined3d/view.c | 6 +++--- dlls/wined3d/wined3d_private.h | 9 +++++++-- 6 files changed, 29 insertions(+), 24 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 8335a030b6b..62a9a342e9b 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -1745,7 +1745,7 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device,
if (parameters->indirect) { - struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)indirect_vk->b.buffer_object; + struct wined3d_bo_vk *bo = wined3d_bo_vk(indirect_vk->b.buffer_object); uint32_t stride, size;
wined3d_context_vk_reference_bo(context_vk, bo); @@ -1817,7 +1817,7 @@ static void adapter_vk_dispatch_compute(struct wined3d_device *device,
if (parameters->indirect) { - struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)indirect_vk->b.buffer_object; + struct wined3d_bo_vk *bo = wined3d_bo_vk(indirect_vk->b.buffer_object);
wined3d_context_vk_reference_bo(context_vk, bo); VK_CALL(vkCmdDispatchIndirect(vk_command_buffer, bo->vk_buffer, diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 56069cb9f16..be4d095eba0 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -190,7 +190,7 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu buffer_gl->b.bo_user.valid = false; list_remove(&buffer_gl->b.bo_user.entry); wined3d_context_gl_destroy_bo(context_gl, &buffer_gl->bo); - buffer_gl->b.buffer_object = 0; + buffer_gl->b.buffer_object = NULL; }
/* Context activation is done by the caller. */ @@ -226,7 +226,7 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf }
list_add_head(&buffer_gl->bo.b.users, &buffer_gl->b.bo_user.entry); - buffer_gl->b.buffer_object = (uintptr_t)bo; + buffer_gl->b.buffer_object = &bo->b; buffer_invalidate_bo_range(&buffer_gl->b, 0, 0);
return TRUE; @@ -657,7 +657,7 @@ DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_co } if (locations & WINED3D_LOCATION_BUFFER) { - data->buffer_object = buffer->buffer_object; + data->buffer_object = (uintptr_t)buffer->buffer_object; data->addr = NULL; return WINED3D_LOCATION_BUFFER; } @@ -969,7 +969,7 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
if (count == 1) { - addr.buffer_object = buffer->buffer_object; + addr.buffer_object = (uintptr_t)buffer->buffer_object; addr.addr = 0; buffer->map_ptr = wined3d_context_map_bo_address(context, &addr, resource->size, flags); /* We are accessing buffer->resource.client from the CS thread, @@ -1049,7 +1049,7 @@ static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resou
context = context_acquire(device, NULL, 0);
- addr.buffer_object = buffer->buffer_object; + addr.buffer_object = (uintptr_t)buffer->buffer_object; addr.addr = 0; wined3d_context_unmap_bo_address(context, &addr, range_count, buffer->maps);
@@ -1455,7 +1455,7 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
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 = (uintptr_t)bo_vk; + buffer_vk->b.buffer_object = &bo_vk->b; buffer_invalidate_bo_range(&buffer_vk->b, 0, 0);
return TRUE; @@ -1463,7 +1463,7 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_buffer_vk *buffer_vk) { - struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object; + struct wined3d_bo_vk *bo = wined3d_bo_vk(buffer_vk->b.buffer_object);
if (buffer_vk->b.bo_user.valid) return &buffer_vk->buffer_info; @@ -1499,8 +1499,8 @@ static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer, static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer, struct wined3d_context *context, unsigned int location) { - struct wined3d_bo_vk *bo_vk = (struct wined3d_bo_vk *)buffer->buffer_object; struct wined3d_context_vk *context_vk = wined3d_context_vk(context); + struct wined3d_bo_vk *bo_vk = wined3d_bo_vk(buffer->buffer_object);
TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
@@ -1511,7 +1511,7 @@ static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer, list_remove(&buffer->bo_user.entry); wined3d_context_vk_destroy_bo(context_vk, bo_vk); heap_free(bo_vk); - buffer->buffer_object = 0u; + buffer->buffer_object = NULL; break;
default: @@ -1535,14 +1535,14 @@ static void wined3d_buffer_vk_upload_ranges(struct wined3d_buffer *buffer, struc if (!range_count) return;
- dst.buffer_object = buffer->buffer_object; + dst.buffer_object = (uintptr_t)buffer->buffer_object; dst.addr = NULL;
flags = WINED3D_MAP_WRITE; if (!ranges->offset && ranges->size == resource->size) flags |= WINED3D_MAP_DISCARD;
- dst_bo = (struct wined3d_bo_vk *)buffer->buffer_object; + dst_bo = wined3d_bo_vk(buffer->buffer_object); if (!(dst_bo->memory_type & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) || (!(flags & WINED3D_MAP_DISCARD) && dst_bo->command_buffer_id > context_vk->completed_command_buffer_id)) { @@ -1634,7 +1634,7 @@ void wined3d_buffer_vk_barrier(struct wined3d_buffer_vk *buffer_vk,
if (src_bind_mask) { - const struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object; + const struct wined3d_bo_vk *bo = wined3d_bo_vk(buffer_vk->b.buffer_object); const struct wined3d_vk_info *vk_info = context_vk->vk_info; VkBufferMemoryBarrier vk_barrier;
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 46769be516e..ec3554ddc30 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2519,7 +2519,7 @@ static void wined3d_context_vk_bind_vertex_buffers(struct wined3d_context_vk *co { buffer_vk = wined3d_buffer_vk(buffer); buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk); - wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer->buffer_object); + wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer->buffer_object)); buffers[count] = buffer_info->buffer; offsets[count] = buffer_info->offset + stream->offset; ++count; @@ -2558,7 +2558,7 @@ static void wined3d_context_vk_bind_stream_output_buffers(struct wined3d_context { buffer_vk = wined3d_buffer_vk(buffer); buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk); - wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer->buffer_object); + wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer->buffer_object)); buffers[count] = buffer_info->buffer; if ((offsets[count] = stream->offset) == ~0u) { @@ -2760,7 +2760,7 @@ static bool wined3d_shader_descriptor_writes_vk_add_cbv_write(struct wined3d_sha if (!wined3d_shader_descriptor_writes_vk_add_write(writes, vk_descriptor_set, binding->binding_idx, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, buffer_info, NULL, NULL)) return false; - wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer->buffer_object); + wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer->buffer_object)); return true; }
@@ -3408,7 +3408,7 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c idx_type = VK_INDEX_TYPE_UINT32; buffer_vk = wined3d_buffer_vk(state->index_buffer); buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk); - wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer_vk->b.buffer_object); + wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer_vk->b.buffer_object)); VK_CALL(vkCmdBindIndexBuffer(vk_command_buffer, buffer_info->buffer, buffer_info->offset + state->index_offset, idx_type)); } diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index e6ff448b028..3143865c469 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -2747,7 +2747,7 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi struct wined3d_buffer *buffer = buffer_from_resource(resource); size_t size = box->right - box->left;
- if (op->bo.addr.buffer_object && op->bo.addr.buffer_object == buffer->buffer_object) + if (op->bo.addr.buffer_object && op->bo.addr.buffer_object == (uintptr_t)buffer->buffer_object) wined3d_context_flush_bo_address(context, &op->bo.addr, size); else wined3d_buffer_copy_bo_address(buffer, context, box->left, &op->bo.addr, size); diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index ee398be15f0..8746d9168c2 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -677,7 +677,7 @@ static VkBufferView wined3d_view_vk_create_vk_buffer_view(struct wined3d_context
get_buffer_view_range(&buffer_vk->b, desc, &view_format_vk->f, &offset, &size); wined3d_buffer_prepare_location(&buffer_vk->b, &context_vk->c, WINED3D_LOCATION_BUFFER); - bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object; + bo = wined3d_bo_vk(buffer_vk->b.buffer_object);
create_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; create_info.pNext = NULL; @@ -1102,7 +1102,7 @@ static void wined3d_shader_resource_view_vk_cs_init(void *object)
if (!vk_buffer_view) return; - bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object; + bo = wined3d_bo_vk(buffer_vk->b.buffer_object);
TRACE("Created buffer view 0x%s.\n", wine_dbgstr_longlong(vk_buffer_view));
@@ -2208,7 +2208,7 @@ static void wined3d_unordered_access_view_vk_cs_init(void *object)
if ((vk_buffer_view = wined3d_view_vk_create_vk_buffer_view(context_vk, desc, buffer_vk, format_vk))) { - struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object; + struct wined3d_bo_vk *bo = wined3d_bo_vk(buffer_vk->b.buffer_object);
TRACE("Created buffer view 0x%s.\n", wine_dbgstr_longlong(vk_buffer_view));
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 398bd73c5c0..63fea9da0e7 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1642,6 +1642,11 @@ struct wined3d_bo_vk bool host_synced; };
+static inline struct wined3d_bo_vk *wined3d_bo_vk(struct wined3d_bo *bo) +{ + return CONTAINING_RECORD(bo, struct wined3d_bo_vk, b); +} + struct wined3d_bo_slab_vk_key { VkMemoryPropertyFlags memory_type; @@ -5033,7 +5038,7 @@ struct wined3d_buffer DWORD flags; DWORD locations; void *map_ptr; - uintptr_t buffer_object; + struct wined3d_bo *buffer_object; struct wined3d_bo_user bo_user;
struct wined3d_range *maps; @@ -6319,7 +6324,7 @@ static inline void wined3d_context_vk_reference_resource(const struct wined3d_co struct wined3d_resource *resource) { if (resource->type == WINED3D_RTYPE_BUFFER) - wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer_from_resource(resource)->buffer_object); + wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer_from_resource(resource)->buffer_object)); else wined3d_context_vk_reference_texture(context_vk, wined3d_texture_vk(texture_from_resource(resource))); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/buffer.c | 14 +++++++++----- dlls/wined3d/context_gl.c | 22 ++++++++++++---------- dlls/wined3d/state.c | 20 ++++++++++++++++---- dlls/wined3d/view.c | 22 +++++++++++++++------- dlls/wined3d/wined3d_private.h | 11 +++++++++++ 5 files changed, 63 insertions(+), 26 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index be4d095eba0..a3004fcecff 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -133,7 +133,9 @@ void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD loc /* Context activation is done by the caller. */ static void wined3d_buffer_gl_bind(struct wined3d_buffer_gl *buffer_gl, struct wined3d_context_gl *context_gl) { - wined3d_context_gl_bind_bo(context_gl, buffer_gl->bo.binding, buffer_gl->bo.id); + const struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object); + + wined3d_context_gl_bind_bo(context_gl, bo_gl->binding, bo_gl->id); }
static GLenum wined3d_buffer_gl_binding_from_bind_flags(const struct wined3d_gl_info *gl_info, uint32_t bind_flags) @@ -225,7 +227,7 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf return FALSE; }
- list_add_head(&buffer_gl->bo.b.users, &buffer_gl->b.bo_user.entry); + 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);
@@ -1324,6 +1326,7 @@ static void wined3d_buffer_gl_upload_ranges(struct wined3d_buffer *buffer, struc const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_range *ranges) { struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer->buffer_object); struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(buffer); const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_range *range; @@ -1336,10 +1339,10 @@ static void wined3d_buffer_gl_upload_ranges(struct wined3d_buffer *buffer, struc while (range_count--) { range = &ranges[range_count]; - GL_EXTCALL(glBufferSubData(buffer_gl->bo.binding, + GL_EXTCALL(glBufferSubData(bo_gl->binding, range->offset, range->size, (BYTE *)data + range->offset - data_offset)); } - wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + wined3d_context_gl_reference_bo(context_gl, bo_gl); checkGLcall("buffer upload"); }
@@ -1348,6 +1351,7 @@ static void wined3d_buffer_gl_download_ranges(struct wined3d_buffer *buffer, str void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_range *ranges) { struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer->buffer_object); struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(buffer); const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_range *range; @@ -1360,7 +1364,7 @@ static void wined3d_buffer_gl_download_ranges(struct wined3d_buffer *buffer, str while (range_count--) { range = &ranges[range_count]; - GL_EXTCALL(glGetBufferSubData(buffer_gl->bo.binding, + GL_EXTCALL(glGetBufferSubData(bo_gl->binding, range->offset, range->size, (BYTE *)data + range->offset - data_offset)); } checkGLcall("buffer download"); diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 09c871efcd4..22e82302b9d 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3815,7 +3815,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
buffer_gl = wined3d_buffer_gl(state->cb[i][j].buffer); wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state); - wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b); if (!buffer_gl->b.bo_user.valid) device_invalidate_state(context_gl->c.device, STATE_CONSTANT_BUFFER(i)); } @@ -3831,7 +3831,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_ { buffer_gl = wined3d_buffer_gl(buffer_from_resource(view->resource)); wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state); - wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b);
srv_gl = wined3d_shader_resource_view_gl(view); if (!srv_gl->bo_user.valid) @@ -3869,7 +3869,7 @@ static void context_gl_load_unordered_access_resources(struct wined3d_context_gl buffer_gl = wined3d_buffer_gl(buffer_from_resource(view->resource)); wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER); wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER); - wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b);
uav_gl = wined3d_unordered_access_view_gl(view); if (!uav_gl->bo_user.valid) @@ -3901,7 +3901,7 @@ static void context_gl_load_stream_output_buffers(struct wined3d_context_gl *con buffer_gl = wined3d_buffer_gl(state->stream_output[i].buffer); 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); + wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b); if (!buffer_gl->b.bo_user.valid) device_invalidate_state(context_gl->c.device, STATE_STREAM_OUTPUT); } @@ -3977,7 +3977,7 @@ 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_context_gl_reference_bo(context_gl, &buffer_gl->bo); + wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b); }
if (indexed && state->index_buffer) @@ -3989,7 +3989,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, wined3d_buffer_load(&buffer_gl->b, context, state); if (!buffer_gl->b.bo_user.valid) device_invalidate_state(device, STATE_INDEXBUFFER); - wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b); } else { @@ -4338,11 +4338,12 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state { const struct wined3d_indirect_dispatch_parameters *indirect = ¶meters->u.indirect; struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(indirect->buffer); + struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
- GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer_gl->bo.id)); + GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, bo_gl->id)); GL_EXTCALL(glDispatchComputeIndirect((GLintptr)indirect->offset)); GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0)); - wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + wined3d_context_gl_reference_bo(context_gl, bo_gl); } else { @@ -4725,6 +4726,7 @@ static void wined3d_context_gl_draw_indirect(struct wined3d_context_gl *context_ { GLenum gl_primitive_type = gl_primitive_type_from_d3d(state->primitive_type); struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(parameters->buffer); + struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object); const struct wined3d_gl_info *gl_info = context_gl->gl_info; const void *offset;
@@ -4734,7 +4736,7 @@ static void wined3d_context_gl_draw_indirect(struct wined3d_context_gl *context_ return; }
- GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer_gl->bo.id)); + GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, bo_gl->id));
offset = (void *)(GLintptr)parameters->offset; if (idx_size) @@ -4750,7 +4752,7 @@ static void wined3d_context_gl_draw_indirect(struct wined3d_context_gl *context_ }
GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0)); - wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + wined3d_context_gl_reference_bo(context_gl, bo_gl);
checkGLcall("draw indirect"); } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 5e41f681c75..788ccb580dd 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -4466,6 +4466,7 @@ 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; struct wined3d_buffer_gl *buffer_gl; + const struct wined3d_bo_gl *bo_gl;
if (!state->index_buffer || !stream_info->all_vbo) { @@ -4474,8 +4475,15 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st }
buffer_gl = wined3d_buffer_gl(state->index_buffer); - GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_gl->bo.id)); - buffer_gl->b.bo_user.valid = true; + if ((bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object))) + { + GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo_gl->id)); + buffer_gl->b.bo_user.valid = true; + } + else + { + GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } }
static void depth_clip(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info) @@ -4569,6 +4577,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_gl *buffer_gl; + struct wined3d_bo_gl *bo_gl; unsigned int i, base, count;
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); @@ -4590,7 +4599,8 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state }
buffer_gl = wined3d_buffer_gl(buffer_state->buffer); - GL_EXTCALL(glBindBufferRange(GL_UNIFORM_BUFFER, base + i, buffer_gl->bo.id, + bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object); + GL_EXTCALL(glBindBufferRange(GL_UNIFORM_BUFFER, base + i, bo_gl->id, buffer_state->offset, buffer_state->size)); buffer_gl->b.bo_user.valid = true; } @@ -4644,6 +4654,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_buffer_gl *buffer_gl; unsigned int offset, size, i; + struct wined3d_bo_gl *bo_gl;
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
@@ -4658,6 +4669,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state }
buffer_gl = wined3d_buffer_gl(state->stream_output[i].buffer); + bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object); offset = state->stream_output[i].offset; if (offset == ~0u) { @@ -4665,7 +4677,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state offset = 0; } size = buffer_gl->b.resource.size - offset; - GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, buffer_gl->bo.id, offset, size)); + GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, bo_gl->id, offset, size)); buffer_gl->b.bo_user.valid = true; } checkGLcall("bind transform feedback buffers"); diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 8746d9168c2..77e98f27a75 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -249,6 +249,7 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c unsigned int offset, unsigned int size) { const struct wined3d_gl_info *gl_info = context_gl->gl_info; + const struct wined3d_bo_gl *bo_gl;
if (!gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT]) { @@ -264,6 +265,7 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c }
wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER); + bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
view->target = GL_TEXTURE_BUFFER; if (!view->name) @@ -272,13 +274,13 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_BUFFER, view->name); if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]) { - GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format_gl->internal, buffer_gl->bo.id, offset, size)); + GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format_gl->internal, bo_gl->id, offset, size)); } else { if (offset || size != buffer_gl->b.resource.size) FIXME("OpenGL implementation does not support ARB_texture_buffer_range.\n"); - GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format_gl->internal, buffer_gl->bo.id)); + GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format_gl->internal, bo_gl->id)); } checkGLcall("Create buffer texture");
@@ -972,11 +974,13 @@ static void wined3d_shader_resource_view_gl_cs_init(void *object) { struct wined3d_buffer *buffer = buffer_from_resource(resource); struct wined3d_context *context; + struct wined3d_bo *bo;
context = context_acquire(resource->device, NULL, 0); create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_format); + bo = (struct wined3d_bo *)buffer->buffer_object; view_gl->bo_user.valid = true; - list_add_head(&wined3d_buffer_gl(buffer)->bo.b.users, &view_gl->bo_user.entry); + list_add_head(&bo->users, &view_gl->bo_user.entry); context_release(context); } else @@ -1482,6 +1486,7 @@ void wined3d_unordered_access_view_gl_clear(struct wined3d_unordered_access_view const struct wined3d_format_gl *format_gl; struct wined3d_buffer_gl *buffer_gl; struct wined3d_resource *resource; + struct wined3d_bo_gl *bo_gl; unsigned int offset, size;
resource = view_gl->v.resource; @@ -1591,11 +1596,12 @@ void wined3d_unordered_access_view_gl_clear(struct wined3d_unordered_access_view wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER); wined3d_unordered_access_view_invalidate_location(&view_gl->v, ~WINED3D_LOCATION_BUFFER);
+ bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object); get_buffer_view_range(&buffer_gl->b, &view_gl->v.desc, &format_gl->f, &offset, &size); - wined3d_context_gl_bind_bo(context_gl, buffer_gl->bo.binding, buffer_gl->bo.id); - GL_EXTCALL(glClearBufferSubData(buffer_gl->bo.binding, format_gl->internal, + wined3d_context_gl_bind_bo(context_gl, bo_gl->binding, bo_gl->id); + GL_EXTCALL(glClearBufferSubData(bo_gl->binding, format_gl->internal, offset, size, format_gl->format, format_gl->type, clear_value)); - wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + wined3d_context_gl_reference_bo(context_gl, bo_gl); checkGLcall("clear unordered access view"); }
@@ -1658,11 +1664,13 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object) { struct wined3d_buffer *buffer = buffer_from_resource(resource); struct wined3d_context_gl *context_gl; + struct wined3d_bo *bo;
context_gl = wined3d_context_gl(context_acquire(resource->device, NULL, 0)); create_buffer_view(&view_gl->gl_view, &context_gl->c, desc, buffer, view_gl->v.format); + bo = (struct wined3d_bo *)buffer->buffer_object; view_gl->bo_user.valid = true; - list_add_head(&wined3d_buffer_gl(buffer)->bo.b.users, &view_gl->bo_user.entry); + list_add_head(&bo->users, &view_gl->bo_user.entry); if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND)) { struct wined3d_bo_gl *bo = &view_gl->counter_bo; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 63fea9da0e7..e04f2682c88 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1612,6 +1612,11 @@ struct wined3d_bo_gl uint64_t command_fence_id; };
+static inline struct wined3d_bo_gl *wined3d_bo_gl(struct wined3d_bo *bo) +{ + return CONTAINING_RECORD(bo, struct wined3d_bo_gl, b); +} + static inline GLuint wined3d_bo_gl_id(uintptr_t bo) { return bo ? ((struct wined3d_bo_gl *)bo)->id : 0; @@ -6579,6 +6584,12 @@ static inline void wined3d_context_gl_reference_bo(struct wined3d_context_gl *co bo_gl->command_fence_id = device_gl->current_fence_id; }
+static inline void wined3d_context_gl_reference_buffer(struct wined3d_context_gl *context_gl, + struct wined3d_buffer *buffer) +{ + wined3d_context_gl_reference_bo(context_gl, wined3d_bo_gl(buffer->buffer_object)); +} + static inline bool wined3d_map_persistent(void) { return sizeof(void *) >= sizeof(uint64_t);
On Mon, 8 Nov 2021 at 23:51, Zebediah Figura zfigura@codeweavers.com wrote:
@@ -4474,8 +4475,15 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st }
buffer_gl = wined3d_buffer_gl(state->index_buffer);
- GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_gl->bo.id));
- buffer_gl->b.bo_user.valid = true;
- if ((bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object)))
- {
GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo_gl->id));
buffer_gl->b.bo_user.valid = true;
- }
- else
- {
GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
- }
}
I'm not too bothered about this, but note that calling wined3d_bo_gl() on a potentially NULL "buffer_object" only works because "b" is the first field in the wined3d_bo_gl structure. The safer approach is to check for NULL first. (As wined3d_bo_gl_id() does, incidentally.)
@@ -972,11 +974,13 @@ static void wined3d_shader_resource_view_gl_cs_init(void *object) { struct wined3d_buffer *buffer = buffer_from_resource(resource); struct wined3d_context *context;
struct wined3d_bo *bo; context = context_acquire(resource->device, NULL, 0); create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_format);
bo = (struct wined3d_bo *)buffer->buffer_object;
That cast should be redundant now.
That is, no longer allocate a wined3d_bo_gl as part of the wined3d_buffer_gl structure.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/buffer.c | 10 ++++++++-- dlls/wined3d/wined3d_private.h | 2 -- 2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index a3004fcecff..0634dd93e2d 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -171,9 +171,11 @@ 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_bo_gl *bo_gl;
if (!buffer_gl->b.buffer_object) return; + bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
if (context_gl->c.transform_feedback_active && (resource->bind_flags & WINED3D_BIND_STREAM_OUTPUT) && wined3d_context_is_graphics_state_dirty(&context_gl->c, STATE_STREAM_OUTPUT)) @@ -191,7 +193,8 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu
buffer_gl->b.bo_user.valid = false; list_remove(&buffer_gl->b.bo_user.entry); - wined3d_context_gl_destroy_bo(context_gl, &buffer_gl->bo); + wined3d_context_gl_destroy_bo(context_gl, bo_gl); + heap_free(bo_gl); buffer_gl->b.buffer_object = NULL; }
@@ -210,6 +213,9 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf TRACE("Creating an OpenGL buffer object for wined3d buffer %p with usage %s.\n", buffer_gl, debug_d3dusage(buffer_gl->b.resource.usage));
+ if (!(bo = heap_alloc(sizeof(*bo)))) + return FALSE; + size = buffer_gl->b.resource.size; binding = wined3d_buffer_gl_binding_from_bind_flags(gl_info, buffer_gl->b.resource.bind_flags); if (buffer_gl->b.resource.usage & WINED3DUSAGE_DYNAMIC) @@ -218,12 +224,12 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf coherent = false; } gl_storage_flags = wined3d_resource_gl_storage_flags(&buffer_gl->b.resource); - bo = &buffer_gl->bo; if (!wined3d_context_gl_create_bo(context_gl, size, binding, usage, coherent, gl_storage_flags, bo)) { ERR("Failed to create OpenGL buffer object.\n"); buffer_gl->b.flags &= ~WINED3D_BUFFER_USE_BO; buffer_clear_dirty_areas(&buffer_gl->b); + heap_free(bo); return FALSE; }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index e04f2682c88..0b5165dbb5e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -5085,8 +5085,6 @@ HRESULT wined3d_buffer_no3d_init(struct wined3d_buffer *buffer_no3d, struct wine struct wined3d_buffer_gl { struct wined3d_buffer b; - - struct wined3d_bo_gl bo; };
static inline struct wined3d_buffer_gl *wined3d_buffer_gl(struct wined3d_buffer *buffer)
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/buffer.c | 9 +++++++++ dlls/wined3d/cs.c | 9 ++------- dlls/wined3d/wined3d_private.h | 2 ++ 3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 0634dd93e2d..fca8ab707f2 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -1101,6 +1101,15 @@ void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_off context_release(context); }
+void wined3d_buffer_update_sub_resource(struct wined3d_buffer *buffer, struct wined3d_context *context, + const struct upload_bo *upload_bo, unsigned int offset, unsigned int size) +{ + if (upload_bo->addr.buffer_object && upload_bo->addr.buffer_object == (uintptr_t)buffer->buffer_object) + wined3d_context_flush_bo_address(context, &upload_bo->addr, size); + else + wined3d_buffer_copy_bo_address(buffer, context, offset, &upload_bo->addr, size); +} + static void wined3d_buffer_init_data(struct wined3d_buffer *buffer, struct wined3d_device *device, const struct wined3d_sub_resource_data *data) { diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 3143865c469..1d909e0c706 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -2744,13 +2744,8 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi
if (resource->type == WINED3D_RTYPE_BUFFER) { - struct wined3d_buffer *buffer = buffer_from_resource(resource); - size_t size = box->right - box->left; - - if (op->bo.addr.buffer_object && op->bo.addr.buffer_object == (uintptr_t)buffer->buffer_object) - wined3d_context_flush_bo_address(context, &op->bo.addr, size); - else - wined3d_buffer_copy_bo_address(buffer, context, box->left, &op->bo.addr, size); + wined3d_buffer_update_sub_resource(buffer_from_resource(resource), + context, &op->bo, box->left, box->right - box->left); goto done; }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 0b5165dbb5e..fc950cda3c3 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -5077,6 +5077,8 @@ BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer, BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN; BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer, struct wined3d_context *context, unsigned int location) DECLSPEC_HIDDEN; +void wined3d_buffer_update_sub_resource(struct wined3d_buffer *buffer, struct wined3d_context *context, + const struct upload_bo *upload_bo, unsigned int offset, unsigned int size) DECLSPEC_HIDDEN;
HRESULT wined3d_buffer_no3d_init(struct wined3d_buffer *buffer_no3d, struct wined3d_device *device, const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/adapter_gl.c | 13 +++++++++ dlls/wined3d/adapter_vk.c | 50 ++++++++++++++++++++++++++++++++++ dlls/wined3d/buffer.c | 35 ++++++++++++++++++++++-- dlls/wined3d/cs.c | 13 ++++++++- dlls/wined3d/directx.c | 12 ++++++++ dlls/wined3d/wined3d_private.h | 11 ++++++++ 6 files changed, 131 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 7ec30cb4356..85b40b19896 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -4606,6 +4606,17 @@ static void adapter_gl_flush_bo_address(struct wined3d_context *context, wined3d_context_gl_flush_bo_address(wined3d_context_gl(context), data, size); }
+static bool adapter_gl_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource, + unsigned int sub_resource_idx, struct wined3d_bo_address *addr) +{ + return false; +} + +static void adapter_gl_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo) +{ + wined3d_context_gl_destroy_bo(wined3d_context_gl(context), wined3d_bo_gl(bo)); +} + static HRESULT adapter_gl_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) @@ -5059,6 +5070,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops = .adapter_unmap_bo_address = adapter_gl_unmap_bo_address, .adapter_copy_bo_address = adapter_gl_copy_bo_address, .adapter_flush_bo_address = adapter_gl_flush_bo_address, + .adapter_alloc_bo = adapter_gl_alloc_bo, + .adapter_destroy_bo = adapter_gl_destroy_bo, .adapter_create_swapchain = adapter_gl_create_swapchain, .adapter_destroy_swapchain = adapter_gl_destroy_swapchain, .adapter_create_buffer = adapter_gl_create_buffer, diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 62a9a342e9b..e83f0a012d6 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -23,6 +23,7 @@ #include "wine/vulkan_driver.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
static const struct wined3d_state_entry_template misc_state_template_vk[] = { @@ -1216,6 +1217,53 @@ static void adapter_vk_flush_bo_address(struct wined3d_context *context, flush_bo_range(context_vk, bo, (uintptr_t)data->addr, size); }
+static bool adapter_vk_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource, + unsigned int sub_resource_idx, struct wined3d_bo_address *addr) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(device); + struct wined3d_context_vk *context_vk = &device_vk->context_vk; + + wined3d_not_from_cs(device->cs); + assert(device->context_count); + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + struct wined3d_bo_vk *bo_vk; + + if (!(bo_vk = heap_alloc(sizeof(*bo_vk)))) + return false; + + if (!(wined3d_context_vk_create_bo(context_vk, resource->size, + vk_buffer_usage_from_bind_flags(resource->bind_flags), + vk_memory_type_from_access_flags(resource->access, resource->usage), bo_vk))) + { + WARN("Failed to create Vulkan buffer.\n"); + heap_free(bo_vk); + return false; + } + + if (!bo_vk->b.map_ptr) + { + WARN_(d3d_perf)("BO %p (chunk %p, slab %p) is not persistently mapped.\n", + bo_vk, bo_vk->memory ? bo_vk->memory->chunk : NULL, bo_vk->slab); + + if (!wined3d_bo_vk_map(bo_vk, context_vk)) + ERR("Failed to map bo.\n"); + } + + addr->buffer_object = (uintptr_t)bo_vk; + addr->addr = NULL; + return true; + } + + return false; +} + +static void adapter_vk_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo) +{ + wined3d_context_vk_destroy_bo(wined3d_context_vk(context), wined3d_bo_vk(bo)); +} + static HRESULT adapter_vk_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) @@ -1868,6 +1916,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops = .adapter_unmap_bo_address = adapter_vk_unmap_bo_address, .adapter_copy_bo_address = adapter_vk_copy_bo_address, .adapter_flush_bo_address = adapter_vk_flush_bo_address, + .adapter_alloc_bo = adapter_vk_alloc_bo, + .adapter_destroy_bo = adapter_vk_destroy_bo, .adapter_create_swapchain = adapter_vk_create_swapchain, .adapter_destroy_swapchain = adapter_vk_destroy_swapchain, .adapter_create_buffer = adapter_vk_create_buffer, diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index fca8ab707f2..82890cd8327 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -1069,6 +1069,34 @@ static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resou return WINED3D_OK; }
+static void wined3d_buffer_set_bo(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo *bo) +{ + struct wined3d_bo *prev_bo = buffer->buffer_object; + + TRACE("buffer %p, context %p, bo %p.\n", buffer, context, bo); + + if (prev_bo) + { + struct wined3d_bo_user *bo_user; + + LIST_FOR_EACH_ENTRY(bo_user, &prev_bo->users, struct wined3d_bo_user, entry) + bo_user->valid = false; + 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; + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER); + wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER); +} + void wined3d_buffer_copy_bo_address(struct wined3d_buffer *dst_buffer, struct wined3d_context *context, unsigned int dst_offset, const struct wined3d_const_bo_address *src_addr, unsigned int size) { @@ -1104,6 +1132,9 @@ void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_off void wined3d_buffer_update_sub_resource(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct upload_bo *upload_bo, unsigned int offset, unsigned int size) { + if (upload_bo->flags & UPLOAD_BO_RENAME_ON_UNMAP) + wined3d_buffer_set_bo(buffer, context, (struct wined3d_bo *)upload_bo->addr.buffer_object); + if (upload_bo->addr.buffer_object && upload_bo->addr.buffer_object == (uintptr_t)buffer->buffer_object) wined3d_context_flush_bo_address(context, &upload_bo->addr, size); else @@ -1418,7 +1449,7 @@ HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined return wined3d_buffer_init(&buffer_gl->b, device, desc, data, parent, parent_ops, &wined3d_buffer_gl_ops); }
-static VkBufferUsageFlags vk_buffer_usage_from_bind_flags(uint32_t bind_flags) +VkBufferUsageFlags vk_buffer_usage_from_bind_flags(uint32_t bind_flags) { VkBufferUsageFlags usage;
@@ -1442,7 +1473,7 @@ static VkBufferUsageFlags vk_buffer_usage_from_bind_flags(uint32_t bind_flags) return usage; }
-static VkMemoryPropertyFlags vk_memory_type_from_access_flags(uint32_t access, uint32_t usage) +VkMemoryPropertyFlags vk_memory_type_from_access_flags(uint32_t access, uint32_t usage) { VkMemoryPropertyFlags memory_type = 0;
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 1d909e0c706..262123b5d90 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -3116,12 +3116,20 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str { /* Limit NOOVERWRITE maps to buffers for now; there are too many ways that * a texture can be invalidated to even count. */ - if (wined3d_map_persistent() && resource->type == WINED3D_RTYPE_BUFFER && (flags & WINED3D_MAP_NOOVERWRITE)) + if (wined3d_map_persistent() && resource->type == WINED3D_RTYPE_BUFFER + && (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))) { struct wined3d_client_resource *client = &resource->client; + struct wined3d_device *device = context->device; const struct wined3d_bo *bo; uint8_t *map_ptr;
+ if (flags & WINED3D_MAP_DISCARD) + { + if (!device->adapter->adapter_ops->adapter_alloc_bo(device, resource, sub_resource_idx, &client->addr)) + return false; + } + bo = (const struct wined3d_bo *)client->addr.buffer_object; map_ptr = bo ? bo->map_ptr : NULL; map_ptr += (uintptr_t)client->addr.addr; @@ -3145,6 +3153,9 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str } map_desc->data = resource_offset_map_pointer(resource, sub_resource_idx, map_ptr, box);
+ if (flags & WINED3D_MAP_DISCARD) + client->mapped_upload.flags |= UPLOAD_BO_UPLOAD_ON_UNMAP | UPLOAD_BO_RENAME_ON_UNMAP; + client->mapped_box = *box;
TRACE("Returning bo %s, flags %#x.\n", debug_const_bo_address(&client->mapped_upload.addr), diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index c265bdc8c95..06387452b89 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2805,6 +2805,16 @@ static void adapter_no3d_flush_bo_address(struct wined3d_context *context, { }
+static bool adapter_no3d_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource, + unsigned int sub_resource_idx, struct wined3d_bo_address *addr) +{ + return false; +} + +static void adapter_no3d_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo) +{ +} + static HRESULT adapter_no3d_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) @@ -3075,6 +3085,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops = .adapter_unmap_bo_address = adapter_no3d_unmap_bo_address, .adapter_copy_bo_address = adapter_no3d_copy_bo_address, .adapter_flush_bo_address = adapter_no3d_flush_bo_address, + .adapter_alloc_bo = adapter_no3d_alloc_bo, + .adapter_destroy_bo = adapter_no3d_destroy_bo, .adapter_create_swapchain = adapter_no3d_create_swapchain, .adapter_destroy_swapchain = adapter_no3d_destroy_swapchain, .adapter_create_buffer = adapter_no3d_create_buffer, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fc950cda3c3..0c5f7dda228 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -331,6 +331,8 @@ VkPipelineStageFlags vk_pipeline_stage_mask_from_bind_flags(uint32_t bind_flags) VkShaderStageFlagBits vk_shader_stage_from_wined3d(enum wined3d_shader_type shader_type) DECLSPEC_HIDDEN; VkAccessFlags vk_access_mask_from_buffer_usage(VkBufferUsageFlags usage) DECLSPEC_HIDDEN; VkPipelineStageFlags vk_pipeline_stage_mask_from_buffer_usage(VkBufferUsageFlags usage) DECLSPEC_HIDDEN; +VkBufferUsageFlags vk_buffer_usage_from_bind_flags(uint32_t bind_flags) DECLSPEC_HIDDEN; +VkMemoryPropertyFlags vk_memory_type_from_access_flags(uint32_t access, uint32_t usage) DECLSPEC_HIDDEN;
static inline enum wined3d_cmp_func wined3d_sanitize_cmp_func(enum wined3d_cmp_func func) { @@ -3353,6 +3355,7 @@ bool wined3d_driver_info_init(struct wined3d_driver_info *driver_info, UINT64 vram_bytes, UINT64 sysmem_bytes) DECLSPEC_HIDDEN;
#define UPLOAD_BO_UPLOAD_ON_UNMAP 0x1 +#define UPLOAD_BO_RENAME_ON_UNMAP 0x2
struct upload_bo { @@ -3385,6 +3388,9 @@ struct wined3d_adapter_ops const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src, size_t size); void (*adapter_flush_bo_address)(struct wined3d_context *context, const struct wined3d_const_bo_address *data, size_t size); + bool (*adapter_alloc_bo)(struct wined3d_device *device, struct wined3d_resource *resource, + unsigned int sub_resource_idx, struct wined3d_bo_address *addr); + void (*adapter_destroy_bo)(struct wined3d_context *context, struct wined3d_bo *bo); HRESULT (*adapter_create_swapchain)(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent, void *parent, @@ -6307,6 +6313,11 @@ static inline void wined3d_context_flush_bo_address(struct wined3d_context *cont context->device->adapter->adapter_ops->adapter_flush_bo_address(context, data, size); }
+static inline void wined3d_context_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo) +{ + context->device->adapter->adapter_ops->adapter_destroy_bo(context, bo); +} + static inline void wined3d_context_vk_reference_bo(const struct wined3d_context_vk *context_vk, struct wined3d_bo_vk *bo) {
On Mon, 8 Nov 2021 at 23:50, Zebediah Figura zfigura@codeweavers.com wrote:
+static void wined3d_buffer_set_bo(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo *bo) +{
- struct wined3d_bo *prev_bo = buffer->buffer_object;
- TRACE("buffer %p, context %p, bo %p.\n", buffer, context, bo);
- if (prev_bo)
- {
struct wined3d_bo_user *bo_user;
LIST_FOR_EACH_ENTRY(bo_user, &prev_bo->users, struct wined3d_bo_user, entry)
bo_user->valid = false;
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;
- wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER);
- wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER);
+}
The location management could now be in wined3d_buffer_update_sub_resource().
On 11/9/21 10:44 AM, Henri Verbeet wrote:
On Mon, 8 Nov 2021 at 23:50, Zebediah Figura zfigura@codeweavers.com wrote:
+static void wined3d_buffer_set_bo(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo *bo) +{
- struct wined3d_bo *prev_bo = buffer->buffer_object;
- TRACE("buffer %p, context %p, bo %p.\n", buffer, context, bo);
- if (prev_bo)
- {
struct wined3d_bo_user *bo_user;
LIST_FOR_EACH_ENTRY(bo_user, &prev_bo->users, struct wined3d_bo_user, entry)
bo_user->valid = false;
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;
- wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER);
- wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER);
+}
The location management could now be in wined3d_buffer_update_sub_resource().
Right, meant to do that part and forgot about it >_<