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/d3d9/tests/visual.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 0ac6b58cb36..51848cecbf6 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -19507,6 +19507,7 @@ static void add_dirty_rect_test(void) ULONG refcount; DWORD *texel; HWND window; + HDC dc; D3DLOCKED_RECT locked_rect; static const RECT part_rect = {96, 96, 160, 160}; static const RECT oob_rect[] = @@ -19748,6 +19749,21 @@ static void add_dirty_rect_test(void) hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
+ /* GetDC() records a dirty rect. */ + fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE); + hr = IDirect3DSurface9_GetDC(surface_src_green, &dc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IDirect3DSurface9_ReleaseDC(surface_src_green, dc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green, + (IDirect3DBaseTexture9 *)tex_dst2); + ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr); + add_dirty_rect_test_draw(device); + color = getPixelColor(device, 320, 240); + todo_wine ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr); + fill_surface(surface_src_red, 0x00ff0000, 0); fill_surface(surface_src_green, 0x0000ff00, 0);
@@ -19873,6 +19889,18 @@ static void add_dirty_rect_test(void) hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
+ /* So does GetDC(). */ + fill_surface(surface_managed0, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE); + hr = IDirect3DSurface9_GetDC(surface_managed0, &dc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IDirect3DSurface9_ReleaseDC(surface_managed0, dc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + add_dirty_rect_test_draw(device); + color = getPixelColor(device, 320, 240); + todo_wine ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr); + /* Tests with dynamic textures */ fill_surface(surface_dynamic, 0x0000ffff, 0); hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dynamic);
From: Zebediah Figura zfigura@codeweavers.com
This fixes a regression in BeebEm.
Fixes: 5f1cbb1b85e7d92b6c783a32ae85ca2902296481 --- dlls/d3d9/tests/visual.c | 4 +-- dlls/wined3d/texture.c | 66 +++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 33 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 51848cecbf6..bb8381cde3d 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -19760,7 +19760,7 @@ static void add_dirty_rect_test(void) ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr); add_dirty_rect_test_draw(device); color = getPixelColor(device, 320, 240); - todo_wine ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color); + ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color); hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
@@ -19897,7 +19897,7 @@ static void add_dirty_rect_test(void) ok(hr == S_OK, "Got hr %#lx.\n", hr); add_dirty_rect_test_draw(device); color = getPixelColor(device, 320, 240); - todo_wine ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color); + ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color); hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index a89fad97ed8..1f4c4b80d3c 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1088,6 +1088,37 @@ static void wined3d_texture_gl_allocate_immutable_storage(struct wined3d_texture checkGLcall("allocate immutable storage"); }
+static void wined3d_texture_dirty_region_add(struct wined3d_texture *texture, + unsigned int layer, const struct wined3d_box *box) +{ + struct wined3d_dirty_regions *regions; + unsigned int count; + + if (!texture->dirty_regions) + return; + + regions = &texture->dirty_regions[layer]; + count = regions->box_count + 1; + if (count >= WINED3D_MAX_DIRTY_REGION_COUNT || !box + || (!box->left && !box->top && !box->front + && box->right == texture->resource.width + && box->bottom == texture->resource.height + && box->back == texture->resource.depth)) + { + regions->box_count = WINED3D_MAX_DIRTY_REGION_COUNT; + return; + } + + if (!wined3d_array_reserve((void **)®ions->boxes, ®ions->boxes_size, count, sizeof(*regions->boxes))) + { + ERR("Failed to grow boxes array, marking entire texture dirty.\n"); + regions->box_count = WINED3D_MAX_DIRTY_REGION_COUNT; + return; + } + + regions->boxes[regions->box_count++] = *box; +} + void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture) { unsigned int sub_count = texture->level_count * texture->layer_count; @@ -1150,6 +1181,10 @@ static void wined3d_texture_create_dc(void *object) context = context_acquire(device, NULL, 0); wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); } + + if (texture->dirty_regions) + wined3d_texture_dirty_region_add(texture, sub_resource_idx / texture->level_count, NULL); + wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding); wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch); wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, texture->resource.map_binding); @@ -2123,37 +2158,6 @@ static struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(str return &texture->sub_resources[sub_resource_idx]; }
-static void wined3d_texture_dirty_region_add(struct wined3d_texture *texture, - unsigned int layer, const struct wined3d_box *box) -{ - struct wined3d_dirty_regions *regions; - unsigned int count; - - if (!texture->dirty_regions) - return; - - regions = &texture->dirty_regions[layer]; - count = regions->box_count + 1; - if (count >= WINED3D_MAX_DIRTY_REGION_COUNT || !box - || (!box->left && !box->top && !box->front - && box->right == texture->resource.width - && box->bottom == texture->resource.height - && box->back == texture->resource.depth)) - { - regions->box_count = WINED3D_MAX_DIRTY_REGION_COUNT; - return; - } - - if (!wined3d_array_reserve((void **)®ions->boxes, ®ions->boxes_size, count, sizeof(*regions->boxes))) - { - WARN("Failed to grow boxes array, marking entire texture dirty.\n"); - regions->box_count = WINED3D_MAX_DIRTY_REGION_COUNT; - return; - } - - regions->boxes[regions->box_count++] = *box; -} - HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture, UINT layer, const struct wined3d_box *dirty_region) {
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));
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=139757
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/d3d9/tests/visual.c:19507 error: patch failed: dlls/d3d9/tests/visual.c:19760 error: patch failed: dlls/wined3d/texture.c:1088 Task: Patch failed to apply
=== debian11 (build log) ===
error: patch failed: dlls/d3d9/tests/visual.c:19507 error: patch failed: dlls/d3d9/tests/visual.c:19760 error: patch failed: dlls/wined3d/texture.c:1088 Task: Patch failed to apply
=== debian11b (build log) ===
error: patch failed: dlls/d3d9/tests/visual.c:19507 error: patch failed: dlls/d3d9/tests/visual.c:19760 error: patch failed: dlls/wined3d/texture.c:1088 Task: Patch failed to apply