Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v3: Avoid calling wined3d_context_map_bo_address() with a NULL context.
dlls/wined3d/texture.c | 55 +++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 20 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index eaa7cdf3ea5..dd1b0c88830 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -799,23 +799,6 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, return TRUE; }
- if (current & WINED3D_LOCATION_CLEARED) - { - struct wined3d_bo_address addr; - - /* FIXME: Clear textures on the GPU if possible. */ - - if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM)) - return FALSE; - wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); - memset(addr.addr, 0, texture->sub_resources[sub_resource_idx].size); - wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); - current |= WINED3D_LOCATION_SYSMEM; - - if (current & location) - return TRUE; - } - if (!current) { ERR("Sub-resource %u of texture %p does not have any up to date location.\n", @@ -824,22 +807,54 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, return wined3d_texture_load_location(texture, sub_resource_idx, context, location); }
- if ((location & wined3d_texture_sysmem_locations) && (current & wined3d_texture_sysmem_locations)) + if ((location & wined3d_texture_sysmem_locations) + && (current & (wined3d_texture_sysmem_locations | WINED3D_LOCATION_CLEARED))) { struct wined3d_bo_address source, destination; struct wined3d_range range; + void *map_ptr;
if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) return FALSE; - wined3d_texture_get_bo_address(texture, sub_resource_idx, &source, (current & wined3d_texture_sysmem_locations)); wined3d_texture_get_bo_address(texture, sub_resource_idx, &destination, location); range.offset = 0; range.size = texture->sub_resources[sub_resource_idx].size; - wined3d_context_copy_bo_address(context, &destination, &source, 1, &range); + if (current & WINED3D_LOCATION_CLEARED) + { + if (destination.buffer_object) + map_ptr = wined3d_context_map_bo_address(context, &destination, range.size, + WINED3D_MAP_WRITE | WINED3D_MAP_DISCARD); + else + map_ptr = destination.addr; + memset(map_ptr, 0, range.size); + if (destination.buffer_object) + wined3d_context_unmap_bo_address(context, &destination, 1, &range); + } + else + { + wined3d_texture_get_bo_address(texture, sub_resource_idx, + &source, (current & wined3d_texture_sysmem_locations)); + wined3d_context_copy_bo_address(context, &destination, &source, 1, &range); + } ret = TRUE; } else + { + if (current & WINED3D_LOCATION_CLEARED) + { + struct wined3d_bo_address addr; + + /* FIXME: Clear textures on the GPU if possible. */ + + if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM)) + return FALSE; + wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); + memset(addr.addr, 0, texture->sub_resources[sub_resource_idx].size); + wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); + } + ret = texture->texture_ops->texture_load_location(texture, sub_resource_idx, context, location); + }
if (ret) wined3d_texture_validate_location(texture, sub_resource_idx, location);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/texture.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index dd1b0c88830..ddb1ffcde49 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -840,19 +840,6 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, } else { - if (current & WINED3D_LOCATION_CLEARED) - { - struct wined3d_bo_address addr; - - /* FIXME: Clear textures on the GPU if possible. */ - - if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM)) - return FALSE; - wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); - memset(addr.addr, 0, texture->sub_resources[sub_resource_idx].size); - wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); - } - ret = texture->texture_ops->texture_load_location(texture, sub_resource_idx, context, location); }
@@ -3345,12 +3332,26 @@ static BOOL wined3d_texture_gl_prepare_location(struct wined3d_texture *texture, static BOOL wined3d_texture_gl_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) { + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture); struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", texture, sub_resource_idx, context, wined3d_debug_location(location));
+ if (sub_resource->locations & WINED3D_LOCATION_CLEARED) + { + struct wined3d_bo_address addr; + + /* FIXME: Clear textures on the GPU if possible. */ + + if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM)) + return FALSE; + wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); + memset(addr.addr, 0, sub_resource->size); + wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); + } + if (!wined3d_texture_gl_prepare_location(texture, sub_resource_idx, context, location)) return FALSE;
@@ -5181,6 +5182,20 @@ static BOOL wined3d_texture_vk_load_texture(struct wined3d_texture_vk *texture_v struct wined3d_box src_box;
sub_resource = &texture_vk->t.sub_resources[sub_resource_idx]; + + if (sub_resource->locations & WINED3D_LOCATION_CLEARED) + { + struct wined3d_bo_address addr; + + /* FIXME: Clear textures on the GPU if possible. */ + + if (!wined3d_texture_prepare_location(&texture_vk->t, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM)) + return FALSE; + wined3d_texture_get_bo_address(&texture_vk->t, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); + memset(addr.addr, 0, sub_resource->size); + wined3d_texture_validate_location(&texture_vk->t, sub_resource_idx, WINED3D_LOCATION_SYSMEM); + } + if (!(sub_resource->locations & wined3d_texture_sysmem_locations)) { ERR("Unimplemented load from %s.\n", wined3d_debug_location(sub_resource->locations));
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/texture.c | 61 +++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index ddb1ffcde49..e2a75282a48 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -5173,6 +5173,56 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context, } }
+static void wined3d_texture_vk_clear(struct wined3d_texture_vk *texture_vk, + unsigned int sub_resource_idx, struct wined3d_context *context) +{ + struct wined3d_context_vk *context_vk = wined3d_context_vk(context); + const struct wined3d_format *format = texture_vk->t.resource.format; + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + static const VkClearDepthStencilValue depth_value; + static const VkClearColorValue colour_value; + VkCommandBuffer vk_command_buffer; + VkImageSubresourceRange vk_range; + VkImageAspectFlags aspect_mask; + VkImage vk_image; + + vk_image = texture_vk->image.vk_image; + + if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk))) + { + ERR("Failed to get command buffer.\n"); + return; + } + + aspect_mask = vk_aspect_mask_from_format(format); + + vk_range.aspectMask = aspect_mask; + vk_range.baseMipLevel = sub_resource_idx % texture_vk->t.level_count; + vk_range.levelCount = 1; + vk_range.baseArrayLayer = sub_resource_idx / texture_vk->t.level_count; + vk_range.layerCount = 1; + + wined3d_context_vk_end_current_render_pass(context_vk); + + wined3d_context_vk_image_barrier(context_vk, vk_command_buffer, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + vk_access_mask_from_bind_flags(texture_vk->t.resource.bind_flags), VK_ACCESS_TRANSFER_WRITE_BIT, + texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk_image, &vk_range); + + if (format->depth_size || format->stencil_size) + VK_CALL(vkCmdClearDepthStencilImage(vk_command_buffer, vk_image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depth_value, 1, &vk_range)); + else + VK_CALL(vkCmdClearColorImage(vk_command_buffer, vk_image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &colour_value, 1, &vk_range)); + + wined3d_context_vk_image_barrier(context_vk, vk_command_buffer, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, vk_access_mask_from_bind_flags(texture_vk->t.resource.bind_flags), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texture_vk->layout, vk_image, &vk_range); + wined3d_context_vk_reference_texture(context_vk, texture_vk); +} + static BOOL wined3d_texture_vk_load_texture(struct wined3d_texture_vk *texture_vk, unsigned int sub_resource_idx, struct wined3d_context *context) { @@ -5185,15 +5235,8 @@ static BOOL wined3d_texture_vk_load_texture(struct wined3d_texture_vk *texture_v
if (sub_resource->locations & WINED3D_LOCATION_CLEARED) { - struct wined3d_bo_address addr; - - /* FIXME: Clear textures on the GPU if possible. */ - - if (!wined3d_texture_prepare_location(&texture_vk->t, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM)) - return FALSE; - wined3d_texture_get_bo_address(&texture_vk->t, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); - memset(addr.addr, 0, sub_resource->size); - wined3d_texture_validate_location(&texture_vk->t, sub_resource_idx, WINED3D_LOCATION_SYSMEM); + wined3d_texture_vk_clear(texture_vk, sub_resource_idx, context); + return TRUE; }
if (!(sub_resource->locations & wined3d_texture_sysmem_locations))
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/texture.c | 106 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index e2a75282a48..18a60ecbf52 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -3328,6 +3328,90 @@ static BOOL wined3d_texture_gl_prepare_location(struct wined3d_texture *texture, } }
+static bool use_ffp_clear(const struct wined3d_texture *texture, unsigned int location) +{ + if (location == WINED3D_LOCATION_DRAWABLE) + return true; + + /* If we are not using FBOs (and not rendering to the drawable), always + * upload. The upload should always succeed in this case; we cannot have + * ARB_texture_multisample without ARB_framebuffer_object. */ + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) + return false; + + if (location == WINED3D_LOCATION_TEXTURE_RGB + && !(texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)) + return false; + if (location == WINED3D_LOCATION_TEXTURE_SRGB + && !(texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)) + return false; + + return location & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED + | WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB); +} + +static bool wined3d_texture_gl_clear(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context_gl *context_gl, unsigned int location) +{ + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; + const struct wined3d_format *format = texture->resource.format; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_bo_address addr; + + if (use_ffp_clear(texture, location)) + { + GLbitfield clear_mask = 0; + + context_gl_apply_texture_draw_state(context_gl, texture, sub_resource_idx, location); + + gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); + context_invalidate_state(&context_gl->c, STATE_RASTERIZER); + + if (format->depth_size) + { + gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE); + context_invalidate_state(&context_gl->c, STATE_DEPTH_STENCIL); + + if (gl_info->supported[ARB_ES2_COMPATIBILITY]) + GL_EXTCALL(glClearDepthf(0.0f)); + else + gl_info->gl_ops.gl.p_glClearDepth(0.0); + clear_mask |= GL_DEPTH_BUFFER_BIT; + } + + if (format->stencil_size) + { + if (gl_info->supported[EXT_STENCIL_TWO_SIDE]) + gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); + gl_info->gl_ops.gl.p_glStencilMask(~0u); + context_invalidate_state(&context_gl->c, STATE_DEPTH_STENCIL); + gl_info->gl_ops.gl.p_glClearStencil(0); + clear_mask |= GL_STENCIL_BUFFER_BIT; + } + + if (!format->depth_size && !format->stencil_size) + { + gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + context_invalidate_state(&context_gl->c, STATE_BLEND); + gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + clear_mask |= GL_COLOR_BUFFER_BIT; + } + + gl_info->gl_ops.gl.p_glClear(clear_mask); + checkGLcall("clear texture"); + + wined3d_texture_validate_location(texture, sub_resource_idx, location); + return true; + } + + if (!wined3d_texture_prepare_location(texture, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_SYSMEM)) + return false; + wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); + memset(addr.addr, 0, sub_resource->size); + wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); + return true; +} + /* Context activation is done by the caller. */ static BOOL wined3d_texture_gl_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) @@ -3339,22 +3423,18 @@ static BOOL wined3d_texture_gl_load_location(struct wined3d_texture *texture, TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", texture, sub_resource_idx, context, wined3d_debug_location(location));
- if (sub_resource->locations & WINED3D_LOCATION_CLEARED) - { - struct wined3d_bo_address addr; - - /* FIXME: Clear textures on the GPU if possible. */ - - if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM)) - return FALSE; - wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); - memset(addr.addr, 0, sub_resource->size); - wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); - } - if (!wined3d_texture_gl_prepare_location(texture, sub_resource_idx, context, location)) return FALSE;
+ if (sub_resource->locations & WINED3D_LOCATION_CLEARED) + { + if (!wined3d_texture_gl_clear(texture, sub_resource_idx, context_gl, location)) + return FALSE; + + if (sub_resource->locations & location) + return TRUE; + } + switch (location) { case WINED3D_LOCATION_SYSMEM:
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
When blitting from a staging texture in SYSMEM to an as-yet uninitialized GPU texture, we want to avoid ever loading the source texture into TEXTURE_RGB, or loading the destination texture into SYSMEM.
This isn't really a proper fix for the relevant tests; it just manages to avoid the problematic code path.
This manages to fix test_yv12_overlay because it causes those blits to use the upload path (whereas currently they go through the raw blitter, and before 1632b8e7a4 they would go through the CPU blitter), and wined3d_texture_gl_upload_data() is one of the only functions to correctly handle planar YUV formats.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52684 Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3d8/tests/visual.c | 2 +- dlls/d3d9/tests/visual.c | 2 +- dlls/ddraw/tests/ddraw1.c | 4 ++-- dlls/ddraw/tests/ddraw2.c | 4 ++-- dlls/ddraw/tests/ddraw4.c | 4 ++-- dlls/ddraw/tests/ddraw7.c | 4 ++-- dlls/wined3d/surface.c | 22 ++++++++++++++++------ 7 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c index 3f302c8adf1..93acd3ebcae 100644 --- a/dlls/d3d8/tests/visual.c +++ b/dlls/d3d8/tests/visual.c @@ -5925,7 +5925,7 @@ static void add_dirty_rect_test(void) ok(hr == D3D_OK, "Failed to copy rects, hr %#x.\n", hr); add_dirty_rect_test_draw(device); color = getPixelColor(device, 320, 240); - todo_wine ok(color_match(color, 0x00ff0000, 1), "Got unexpected colour 0x%08x.\n", color); + ok(color_match(color, 0x00ff0000, 1), "Got unexpected colour 0x%08x.\n", color); hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL); ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 09c94816d3b..1cba75641c1 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -19779,7 +19779,7 @@ static void add_dirty_rect_test(void) ok(hr == D3D_OK, "Failed to copy rects, hr %#x.\n", hr); add_dirty_rect_test_draw(device); color = getPixelColor(device, 320, 240); - todo_wine ok(color_match(color, 0x00ff0000, 1), "Got unexpected colour 0x%08x.\n", color); + ok(color_match(color, 0x00ff0000, 1), "Got unexpected colour 0x%08x.\n", color); hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 84bdda82978..13ca2023cd6 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -10100,9 +10100,9 @@ static void test_yv12_overlay(void) base = desc.lpSurface; ok(base[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base[0]); base += desc.dwHeight * U1(desc).lPitch; - todo_wine ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]); + ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]); base += desc.dwHeight / 4 * U1(desc).lPitch; - todo_wine ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]); + ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]);
hr = IDirectDrawSurface_Unlock(dst_surface, NULL); ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index f67aae9db5b..9d05de1e892 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -10933,9 +10933,9 @@ static void test_yv12_overlay(void) base = desc.lpSurface; ok(base[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base[0]); base += desc.dwHeight * U1(desc).lPitch; - todo_wine ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]); + ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]); base += desc.dwHeight / 4 * U1(desc).lPitch; - todo_wine ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]); + ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]);
hr = IDirectDrawSurface_Unlock(dst_surface, NULL); ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 8f85c5bc01b..849814529a7 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -12892,9 +12892,9 @@ static void test_yv12_overlay(void) base = desc.lpSurface; ok(base[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base[0]); base += desc.dwHeight * U1(desc).lPitch; - todo_wine ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]); + ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]); base += desc.dwHeight / 4 * U1(desc).lPitch; - todo_wine ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]); + ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]);
hr = IDirectDrawSurface4_Unlock(dst_surface, NULL); ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 3dfd590c42c..e8d2aa8ab7b 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -12885,9 +12885,9 @@ static void test_yv12_overlay(void) base = desc.lpSurface; ok(base[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base[0]); base += desc.dwHeight * U1(desc).lPitch; - todo_wine ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]); + ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]); base += desc.dwHeight / 4 * U1(desc).lPitch; - todo_wine ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]); + ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]);
hr = IDirectDrawSurface7_Unlock(dst_surface, NULL); ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 7dcc8679da5..3216439f32b 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -31,9 +31,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
-static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM - | WINED3D_LOCATION_BUFFER | WINED3D_LOCATION_CLEARED; - /* Works correctly only for <= 4 bpp formats. */ static void get_color_masks(const struct wined3d_format *format, uint32_t *masks) { @@ -1481,6 +1478,19 @@ static bool wined3d_is_colour_blit(enum wined3d_blit_op blit_op) } }
+static bool sub_resource_is_on_cpu(const struct wined3d_texture *texture, unsigned int sub_resource_idx) +{ + DWORD locations = texture->sub_resources[sub_resource_idx].locations; + + if (locations & (WINED3D_LOCATION_BUFFER | WINED3D_LOCATION_SYSMEM)) + return true; + + if (!(texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU) && (locations & WINED3D_LOCATION_CLEARED)) + return true; + + return false; +} + HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags, const struct wined3d_blt_fx *fx, @@ -1641,8 +1651,8 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ { blit_op = WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST; } - else if ((src_sub_resource->locations & surface_simple_locations) - && !(dst_sub_resource->locations & surface_simple_locations) + else if (sub_resource_is_on_cpu(src_texture, src_sub_resource_idx) + && !sub_resource_is_on_cpu(dst_texture, dst_sub_resource_idx) && (dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) { /* Upload */ @@ -1666,7 +1676,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ return WINED3D_OK; } } - else if (!(src_sub_resource->locations & surface_simple_locations) + else if (!sub_resource_is_on_cpu(src_texture, src_sub_resource_idx) && (dst_sub_resource->locations & dst_texture->resource.map_binding) && !(dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) {
On Fri, 22 Apr 2022 at 22:59, Zebediah Figura zfigura@codeweavers.com wrote:
dlls/d3d8/tests/visual.c | 2 +- dlls/d3d9/tests/visual.c | 2 +- dlls/ddraw/tests/ddraw1.c | 4 ++-- dlls/ddraw/tests/ddraw2.c | 4 ++-- dlls/ddraw/tests/ddraw4.c | 4 ++-- dlls/ddraw/tests/ddraw7.c | 4 ++-- dlls/wined3d/surface.c | 22 ++++++++++++++++------ 7 files changed, 26 insertions(+), 16 deletions(-)
This doesn't quite apply here.