-- v2: wined3d: Provide a null counter BO for slots with no corresponding XFB buffer bound. wined3d: Create the XFB counter BO in wined3d_context_vk_bind_stream_output_buffers(). d3d8: Pass NOOVERWRITE to redundantly discarded maps.
From: Zebediah Figura zfigura@codeweavers.com
If DISCARD maps are accelerated, passing empty map flags won't return the same accelerated BO.
Tested with Port Royale 2 and Rayman 3.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55770 --- dlls/d3d8/buffer.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/dlls/d3d8/buffer.c b/dlls/d3d8/buffer.c index 866292e43c0..f49f6f9f847 100644 --- a/dlls/d3d8/buffer.c +++ b/dlls/d3d8/buffer.c @@ -193,7 +193,10 @@ static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface, UINT iface, offset, size, data, flags);
if (buffer->discarded) - flags &= ~D3DLOCK_DISCARD; + { + WARN("Filtering out redundant discard of %p.\n", buffer); + flags = (flags & ~D3DLOCK_DISCARD) | D3DLOCK_NOOVERWRITE; + } if (flags & D3DLOCK_DISCARD) buffer->discarded = true;
@@ -514,7 +517,10 @@ static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface, UINT o iface, offset, size, data, flags);
if (buffer->discarded) - flags &= ~D3DLOCK_DISCARD; + { + WARN("Filtering out redundant discard of %p.\n", buffer); + flags = (flags & ~D3DLOCK_DISCARD) | D3DLOCK_NOOVERWRITE; + } if (flags & D3DLOCK_DISCARD) buffer->discarded = true;
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/adapter_vk.c | 15 --------------- dlls/wined3d/context_vk.c | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 73807d827e6..96eeeb3472a 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -1724,7 +1724,6 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device, struct wined3d_context_vk *context_vk; VkCommandBuffer vk_command_buffer; uint32_t instance_count; - unsigned int i;
TRACE("device %p, state %p, parameters %p.\n", device, state, parameters);
@@ -1744,20 +1743,6 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device,
if (context_vk->c.transform_feedback_active) { - if (!context_vk->vk_so_counter_bo.vk_buffer) - { - struct wined3d_bo_vk *bo = &context_vk->vk_so_counter_bo; - - if (!wined3d_context_vk_create_bo(context_vk, ARRAY_SIZE(context_vk->vk_so_counters) * sizeof(uint32_t) * 2, - VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bo)) - ERR("Failed to create counter BO.\n"); - for (i = 0; i < ARRAY_SIZE(context_vk->vk_so_counters); ++i) - { - context_vk->vk_so_counters[i] = bo->vk_buffer; - context_vk->vk_so_offsets[i] = bo->b.buffer_offset + i * sizeof(uint32_t) * 2; - } - } - wined3d_context_vk_reference_bo(context_vk, &context_vk->vk_so_counter_bo); if (context_vk->c.transform_feedback_paused) VK_CALL(vkCmdBeginTransformFeedbackEXT(vk_command_buffer, 0, ARRAY_SIZE(context_vk->vk_so_counters), diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 75f0e68395c..fcdaaa17966 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2813,6 +2813,20 @@ static void wined3d_context_vk_bind_stream_output_buffers(struct wined3d_context struct wined3d_buffer *buffer; unsigned int i, first, count;
+ if (!context_vk->vk_so_counter_bo.vk_buffer) + { + struct wined3d_bo_vk *bo = &context_vk->vk_so_counter_bo; + + if (!wined3d_context_vk_create_bo(context_vk, ARRAY_SIZE(context_vk->vk_so_counters) * sizeof(uint32_t) * 2, + VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bo)) + ERR("Failed to create counter BO.\n"); + for (i = 0; i < ARRAY_SIZE(context_vk->vk_so_counters); ++i) + { + context_vk->vk_so_counters[i] = bo->vk_buffer; + context_vk->vk_so_offsets[i] = bo->b.buffer_offset + i * sizeof(uint32_t) * 2; + } + } + first = 0; count = 0; for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i)
From: Zebediah Figura zfigura@codeweavers.com
The Vulkan specification does not currently mandate this. However, an (unfortunately internal) Khronos discussion determined that this is an oversight, and that many drivers likely expect that no counter buffer will be bound if no XFB buffer is bound. Accordingly the specification will probably mandate this in the future.
lavapipe is such a driver. This fixes a crash with llvmpipe in test_index_buffer_offset(). --- dlls/wined3d/context_vk.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index fcdaaa17966..29a4a4998d4 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2820,13 +2820,12 @@ static void wined3d_context_vk_bind_stream_output_buffers(struct wined3d_context if (!wined3d_context_vk_create_bo(context_vk, ARRAY_SIZE(context_vk->vk_so_counters) * sizeof(uint32_t) * 2, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bo)) ERR("Failed to create counter BO.\n"); + for (i = 0; i < ARRAY_SIZE(context_vk->vk_so_counters); ++i) - { - context_vk->vk_so_counters[i] = bo->vk_buffer; context_vk->vk_so_offsets[i] = bo->b.buffer_offset + i * sizeof(uint32_t) * 2; - } }
+ memset(context_vk->vk_so_counters, 0, sizeof(context_vk->vk_so_counters)); first = 0; count = 0; for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i) @@ -2835,6 +2834,8 @@ static void wined3d_context_vk_bind_stream_output_buffers(struct wined3d_context
if ((buffer = stream->buffer)) { + context_vk->vk_so_counters[i] = context_vk->vk_so_counter_bo.vk_buffer; + buffer_vk = wined3d_buffer_vk(buffer); buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk); wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer->buffer_object));
Sorry about that, I forgot I already sent those patches...
This merge request was approved by Jan Sikorski.