Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50123 Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Requery format properties after falling back to VK_FORMAT_D32_SFLOAT_S8_UINT.
dlls/wined3d/utils.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 9df51872d42..5b6056e5713 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4146,7 +4146,7 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, {WINED3DFMT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, }, {WINED3DFMT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, }, {WINED3DFMT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, }, - {WINED3DFMT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, }, + {WINED3DFMT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, }, }; VkFormat vk_format = VK_FORMAT_UNDEFINED; VkImageFormatProperties image_properties; @@ -4181,6 +4181,17 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, format->f.color_fixup = COLOR_FIXUP_IDENTITY;
VK_CALL(vkGetPhysicalDeviceFormatProperties(vk_physical_device, vk_format, &properties)); + if (vk_format == VK_FORMAT_D24_UNORM_S8_UINT) + { + if (~properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) + { + /* AMD doesn't support VK_FORMAT_D24_UNORM_S8_UINT. */ + WARN("Mapping VK_FORMAT_D24_UNORM_S8_UINT to VK_FORMAT_D32_SFLOAT_S8_UINT.\n"); + + format->vk_format = vk_format = VK_FORMAT_D32_SFLOAT_S8_UINT; + VK_CALL(vkGetPhysicalDeviceFormatProperties(vk_physical_device, vk_format, &properties)); + } + }
if (properties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) format->f.flags[WINED3D_GL_RES_TYPE_BUFFER] |= WINED3DFMT_FLAG_VERTEX_ATTRIBUTE;
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50119 Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Fix off-by-one (not sure how I convinced myself that right and bottom coordinates were inclusive, they clearly are not), also recreate swapchain on VK_SUBOPTIMAL_KHR, retry to present the image after swapchain recreation.
dlls/wined3d/swapchain.c | 37 ++++++++++++++++++++++++++++++++-- dlls/wined3d/wined3d_private.h | 1 + 2 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 72e17a6f833..90e21e476ff 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -998,6 +998,9 @@ static HRESULT wined3d_swapchain_vk_create_vulkan_swapchain(struct wined3d_swapc goto fail; }
+ swapchain_vk->width = width; + swapchain_vk->height = height; + return WINED3D_OK;
fail: @@ -1043,12 +1046,17 @@ static void wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain_vk, unsigned int present_idx; VkImageLayout vk_layout; uint32_t image_idx; + RECT dst_rect_tmp; VkImageBlit blit; + VkFilter filter; VkResult vr; HRESULT hr;
static const VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ TRACE("swapchain_vk %p, context_vk %p, src_rect %s, dst_rect %s, swap_interval %u.\n", + swapchain_vk, context_vk, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), swap_interval); + wined3d_swapchain_vk_set_swap_interval(swapchain_vk, swap_interval);
present_idx = swapchain_vk->current++ % swapchain_vk->image_count; @@ -1071,6 +1079,18 @@ static void wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain_vk, return; }
+ if (dst_rect->right > swapchain_vk->width || dst_rect->bottom > swapchain_vk->height) + { + dst_rect_tmp = *dst_rect; + if (dst_rect->right > swapchain_vk->width) + dst_rect_tmp.right = swapchain_vk->width; + if (dst_rect->bottom > swapchain_vk->height) + dst_rect_tmp.bottom = swapchain_vk->height; + dst_rect = &dst_rect_tmp; + } + filter = src_rect->right - src_rect->left != dst_rect->right - dst_rect->left + || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top + ? VK_FILTER_LINEAR : VK_FILTER_NEAREST; vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
wined3d_context_vk_end_current_render_pass(context_vk); @@ -1108,7 +1128,7 @@ static void wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain_vk, VK_CALL(vkCmdBlitImage(vk_command_buffer, back_buffer_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, swapchain_vk->vk_images[image_idx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, &blit, VK_FILTER_NEAREST)); + 1, &blit, filter));
wined3d_context_vk_reference_texture(context_vk, back_buffer_vk); wined3d_context_vk_image_barrier(context_vk, vk_command_buffer, @@ -1142,8 +1162,21 @@ static void wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain_vk, present_desc.pSwapchains = &swapchain_vk->vk_swapchain; present_desc.pImageIndices = &image_idx; present_desc.pResults = NULL; - if ((vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc)))) + vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc)); + if (vr == VK_ERROR_OUT_OF_DATE_KHR || vr == VK_SUBOPTIMAL_KHR) + { + if (FAILED(hr = wined3d_swapchain_vk_recreate(swapchain_vk))) + ERR("Failed to recreate swapchain, hr %#x.\n", hr); + if (vr == VK_ERROR_OUT_OF_DATE_KHR) + { + if ((vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc)))) + ERR("Present returned vr %s.\n", wined3d_debug_vkresult(vr)); + } + } + else if (vr) + { ERR("Present returned vr %s.\n", wined3d_debug_vkresult(vr)); + } }
static void wined3d_swapchain_vk_rotate(struct wined3d_swapchain *swapchain, struct wined3d_context_vk *context_vk) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 6fc743e74db..db21afd02b1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -5286,6 +5286,7 @@ struct wined3d_swapchain_vk uint64_t command_buffer_id; } *vk_semaphores; unsigned int current, image_count; + unsigned int width, height; };
static inline struct wined3d_swapchain_vk *wined3d_swapchain_vk(struct wined3d_swapchain *swapchain)
On Wed, 10 Mar 2021 at 20:50, Matteo Bruni mbruni@codeweavers.com wrote:
@@ -1142,8 +1162,21 @@ static void wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain_vk, present_desc.pSwapchains = &swapchain_vk->vk_swapchain; present_desc.pImageIndices = &image_idx; present_desc.pResults = NULL;
- if ((vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc))))
- vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc));
- if (vr == VK_ERROR_OUT_OF_DATE_KHR || vr == VK_SUBOPTIMAL_KHR)
- {
if (FAILED(hr = wined3d_swapchain_vk_recreate(swapchain_vk)))
ERR("Failed to recreate swapchain, hr %#x.\n", hr);
if (vr == VK_ERROR_OUT_OF_DATE_KHR)
{
if ((vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc))))
ERR("Present returned vr %s.\n", wined3d_debug_vkresult(vr));
Does that work? I'd expect swapchain image content to be undefined after recreating the swapchain. (For reference, what I had in mind was to return a VkResult from wined3d_swapchain_vk_blit(), either from vkAcquireNextImageKHR() or vkQueuePresentKHR(), and then recreate the swapchain and redo the blit in the caller.)
On Thu, Mar 11, 2021 at 12:53 PM Henri Verbeet hverbeet@gmail.com wrote:
On Wed, 10 Mar 2021 at 20:50, Matteo Bruni mbruni@codeweavers.com wrote:
@@ -1142,8 +1162,21 @@ static void wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain_vk, present_desc.pSwapchains = &swapchain_vk->vk_swapchain; present_desc.pImageIndices = &image_idx; present_desc.pResults = NULL;
- if ((vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc))))
- vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc));
- if (vr == VK_ERROR_OUT_OF_DATE_KHR || vr == VK_SUBOPTIMAL_KHR)
- {
if (FAILED(hr = wined3d_swapchain_vk_recreate(swapchain_vk)))
ERR("Failed to recreate swapchain, hr %#x.\n", hr);
if (vr == VK_ERROR_OUT_OF_DATE_KHR)
{
if ((vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc))))
ERR("Present returned vr %s.\n", wined3d_debug_vkresult(vr));
Does that work? I'd expect swapchain image content to be undefined after recreating the swapchain. (For reference, what I had in mind was to return a VkResult from wined3d_swapchain_vk_blit(), either from vkAcquireNextImageKHR() or vkQueuePresentKHR(), and then recreate the swapchain and redo the blit in the caller.)
That makes a lot more sense than what I did here...
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- Mostly to make sure that ok() prints values that actually don't match (I was confused by the message for a second...).
dlls/d3d11/tests/d3d11.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 6cdac34c0cd..1e69d827977 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -16013,7 +16013,10 @@ static void test_clear_buffer_unordered_access_view(void) const struct uvec4 broken_result = {uvec4.x, uvec4.x, uvec4.x, uvec4.x}; /* Intel */ data = get_readback_uvec4(&rb, x, 0); if (!(compare_uvec4(data, &uvec4) || broken(compare_uvec4(data, &broken_result)))) + { all_match = FALSE; + break; + } } ok(all_match, "Got {%#x, %#x, %#x, %#x}, expected {%#x, %#x, %#x, %#x} at %u.\n", data->x, data->y, data->z, data->w, uvec4.x, uvec4.y, uvec4.z, uvec4.w, x); @@ -16028,7 +16031,10 @@ static void test_clear_buffer_unordered_access_view(void) uvec4 = U(uav_desc).Buffer.FirstElement <= x ? fe_uvec4 : uvec4_data[i]; broken_result.x = broken_result.y = broken_result.z = broken_result.w = uvec4.x; if (!(compare_uvec4(data, &uvec4) || broken(compare_uvec4(data, &broken_result)))) + { all_match = FALSE; + break; + } } ok(all_match, "Got {%#x, %#x, %#x, %#x}, expected {%#x, %#x, %#x, %#x} at %u.\n", data->x, data->y, data->z, data->w, uvec4.x, uvec4.y, uvec4.z, uvec4.w, x);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/buffer.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 9ea62a81d0b..8fca81ec19c 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -193,7 +193,6 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf return FALSE; }
- list_init(&buffer_gl->bo_user.entry); list_add_head(&buffer_gl->bo.users, &buffer_gl->bo_user.entry); buffer_gl->b.buffer_object = (uintptr_t)bo; buffer_invalidate_bo_range(&buffer_gl->b, 0, 0);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/glsl_shader.c | 8 ++++---- dlls/wined3d/utils.c | 7 +++---- dlls/wined3d/wined3d_private.h | 5 +++-- 3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 9ba024ed3c7..970d7c331bd 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -10209,6 +10209,7 @@ static void set_glsl_compute_shader_program(const struct wined3d_context_gl *con static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data) { + const struct wined3d_stream_info *stream_info = &context_gl->c.stream_info; const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_shader *pre_rasterization_shader; @@ -10244,7 +10245,7 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl,
vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
- find_vs_compile_args(state, vshader, context_gl->c.stream_info.swizzle_map, &vs_compile_args, &context_gl->c); + find_vs_compile_args(state, vshader, stream_info->swizzle_map, &vs_compile_args, &context_gl->c); vs_id = find_glsl_vertex_shader(context_gl, priv, vshader, &vs_compile_args); vs_list = &vshader->linked_programs; } @@ -10253,7 +10254,7 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, struct glsl_ffp_vertex_shader *ffp_shader; struct wined3d_ffp_vs_settings settings;
- wined3d_ffp_get_vs_settings(&context_gl->c, state, &settings); + wined3d_ffp_get_vs_settings(stream_info, d3d_info, state, &settings); ffp_shader = shader_glsl_find_ffp_vertex_shader(priv, gl_info, &settings); vs_id = ffp_shader->id; vs_list = &ffp_shader->linked_programs; @@ -10309,8 +10310,7 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, { struct ps_compile_args ps_compile_args; pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - find_ps_compile_args(state, pshader, context_gl->c.stream_info.position_transformed, - &ps_compile_args, &context_gl->c); + find_ps_compile_args(state, pshader, stream_info->position_transformed, &ps_compile_args, &context_gl->c); ps_id = find_glsl_fragment_shader(context_gl, &priv->shader_buffer, &priv->string_buffers, pshader, &ps_compile_args, &np2fixup_info); ps_list = &pshader->linked_programs; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 5b6056e5713..fcee986d217 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6501,12 +6501,11 @@ int wined3d_ffp_frag_program_key_compare(const void *key, const struct wine_rb_e return memcmp(ka, kb, sizeof(*ka)); }
-void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, - const struct wined3d_state *state, struct wined3d_ffp_vs_settings *settings) +void wined3d_ffp_get_vs_settings(const struct wined3d_stream_info *si, + const struct wined3d_d3d_info *d3d_info, const struct wined3d_state *state, + struct wined3d_ffp_vs_settings *settings) { enum wined3d_material_color_source diffuse_source, emissive_source, ambient_source, specular_source; - const struct wined3d_stream_info *si = &context->stream_info; - const struct wined3d_d3d_info *d3d_info = context->d3d_info; unsigned int coord_idx, i;
memset(settings, 0, sizeof(*settings)); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index db21afd02b1..36b2fe9926b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3571,8 +3571,9 @@ struct wined3d_ffp_vs_desc struct wined3d_ffp_vs_settings settings; };
-void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, - const struct wined3d_state *state, struct wined3d_ffp_vs_settings *settings) DECLSPEC_HIDDEN; +void wined3d_ffp_get_vs_settings(const struct wined3d_stream_info *si, + const struct wined3d_d3d_info *d3d_info, const struct wined3d_state *state, + struct wined3d_ffp_vs_settings *settings) DECLSPEC_HIDDEN;
struct wined3d {
On Wed, 10 Mar 2021 at 20:50, Matteo Bruni mbruni@codeweavers.com wrote:
-void wined3d_ffp_get_vs_settings(const struct wined3d_context *context,
const struct wined3d_state *state, struct wined3d_ffp_vs_settings *settings)
+void wined3d_ffp_get_vs_settings(const struct wined3d_stream_info *si,
const struct wined3d_d3d_info *d3d_info, const struct wined3d_state *state,
struct wined3d_ffp_vs_settings *settings)
{ enum wined3d_material_color_source diffuse_source, emissive_source, ambient_source, specular_source;
- const struct wined3d_stream_info *si = &context->stream_info;
- const struct wined3d_d3d_info *d3d_info = context->d3d_info; unsigned int coord_idx, i;
I suppose that's fine, but I don't think it's quite obvious why we care, or why it's an improvement.
On Thu, Mar 11, 2021 at 12:52 PM Henri Verbeet hverbeet@gmail.com wrote:
On Wed, 10 Mar 2021 at 20:50, Matteo Bruni mbruni@codeweavers.com wrote:
-void wined3d_ffp_get_vs_settings(const struct wined3d_context *context,
const struct wined3d_state *state, struct wined3d_ffp_vs_settings *settings)
+void wined3d_ffp_get_vs_settings(const struct wined3d_stream_info *si,
const struct wined3d_d3d_info *d3d_info, const struct wined3d_state *state,
struct wined3d_ffp_vs_settings *settings)
{ enum wined3d_material_color_source diffuse_source, emissive_source, ambient_source, specular_source;
- const struct wined3d_stream_info *si = &context->stream_info;
- const struct wined3d_d3d_info *d3d_info = context->d3d_info; unsigned int coord_idx, i;
I suppose that's fine, but I don't think it's quite obvious why we care, or why it's an improvement.
It doesn't matter anymore. I originally wrote this patch before the struct wined3d_context -> struct wined3d_context{_gl,_vk} split, as part of an effort to get rid of accesses to GL-specific stuff from wined3d FFP and shader key generation functions. That's now moot I think, I can throw those patches away.