From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/d3d11/tests/d3d11.c | 3 +-- dlls/wined3d/texture.c | 3 ++- dlls/wined3d/utils.c | 53 ++++++++++++++++++++++++++++++++-------- 3 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 4adad271fc8..27378cc6e01 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -36300,7 +36300,7 @@ static void test_nv12(void) device_context = test_context.immediate_context;
hr = ID3D11Device_CheckFormatSupport(device, DXGI_FORMAT_NV12, &support); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine_if (!damavand) ok(hr == S_OK, "Got hr %#lx.\n", hr);
if (!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D)) { @@ -36398,7 +36398,6 @@ static void test_nv12(void)
expected_hr = (width & 1 || height & 1) ? E_INVALIDARG : S_OK; hr = ID3D11Device_CreateTexture2D(device, &desc, &subresource_data, &texture); - todo_wine_if(SUCCEEDED(expected_hr)) ok(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
if (FAILED(hr)) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 14c3aa419a8..d12cadd71fc 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -5380,7 +5380,8 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk, format_vk = wined3d_format_vk(resource->format);
if (wined3d_format_is_typeless(&format_vk->f) || texture_vk->t.swapchain - || (texture_vk->t.resource.bind_flags & WINED3D_BIND_UNORDERED_ACCESS)) + || (texture_vk->t.resource.bind_flags & WINED3D_BIND_UNORDERED_ACCESS) + || (format_vk->f.attrs & WINED3D_FORMAT_ATTR_PLANAR)) { /* For UAVs, we need this in case a clear necessitates creation of a new view * with a different format. */ diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 58ca1fcca5e..c75516aac5a 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4243,7 +4243,7 @@ fail: return FALSE; }
-static void init_vulkan_format_info(struct wined3d_format_vk *format, +static void init_vulkan_format_info(struct wined3d_adapter *adapter, struct wined3d_format_vk *format, const struct wined3d_vk_info *vk_info, VkPhysicalDevice vk_physical_device) { static const struct @@ -4330,6 +4330,7 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, {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_D24_UNORM_S8_UINT, }, + {WINED3DFMT_NV12_PLANAR, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,}, }; VkFormat vk_format = VK_FORMAT_UNDEFINED; VkImageFormatProperties image_properties; @@ -4357,6 +4358,10 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, return; }
+ if ((format->f.attrs & WINED3D_FORMAT_ATTR_PLANAR) && !vk_info->supported[WINED3D_VK_KHR_SAMPLER_YCBCR_CONVERSION] + && vk_info->api_version < VK_API_VERSION_1_1) + return; + format->vk_format = vk_format; if (fixup) format->f.color_fixup = create_color_fixup_desc_from_string(fixup); @@ -4376,13 +4381,45 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, } }
+ caps = 0; + texture_flags = properties.linearTilingFeatures | properties.optimalTilingFeatures; + if ((texture_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) + && (texture_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) + caps |= WINED3D_FORMAT_CAP_BLIT; + + if (format->f.attrs & WINED3D_FORMAT_ATTR_PLANAR) + { + /* Direct3D only does planar views, without YCbCr conversion. + * In order to query whether this is supported on the Vulkan side, + * we need to ignore the feature flags for the planar image, + * and instead combine the feature flags for the corresponding format + * for each plane. + * + * Somewhat oddly, Vulkan doesn't distinguish "R8_UNORM (e.g.) views of + * a planar image are supported" from "R8_UNORM views are supported in + * general", which means that we don't really know through querying if + * a given YUV format is supported. Fortunately we need blit support + * anyway, and it seems fair to assume that if blit is supported for a + * format, then we can also create planar views. */ + if (!caps) + { + TRACE("Unsupported format %s (no blit support).\n", debug_d3dformat(format->f.id)); + return; + } + + caps = ~0u; + for (unsigned int i = 0; i < 2; ++i) + caps &= get_format_internal(adapter, format->f.plane_formats[i])->caps[WINED3D_GL_RES_TYPE_TEX_2D]; + format->f.caps[WINED3D_GL_RES_TYPE_TEX_2D] |= caps; + TRACE("Caps %#08x are supported for format %s.\n", caps, debug_d3dformat(format->f.id)); + return; + } + if (properties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) format->f.caps[WINED3D_GL_RES_TYPE_BUFFER] |= WINED3D_FORMAT_CAP_VERTEX_ATTRIBUTE; if (properties.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) format->f.caps[WINED3D_GL_RES_TYPE_BUFFER] |= WINED3D_FORMAT_CAP_TEXTURE;
- caps = 0; - texture_flags = properties.linearTilingFeatures | properties.optimalTilingFeatures; if (texture_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) { caps |= WINED3D_FORMAT_CAP_TEXTURE | WINED3D_FORMAT_CAP_VTF; @@ -4407,15 +4444,11 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, { caps |= WINED3D_FORMAT_CAP_UNORDERED_ACCESS; } - if ((texture_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) - && (texture_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) - { - caps |= WINED3D_FORMAT_CAP_BLIT; - } - if (!(~caps & (WINED3D_FORMAT_CAP_RENDERTARGET | WINED3D_FORMAT_CAP_FILTERING))) caps |= WINED3D_FORMAT_CAP_GEN_MIPMAP;
+ TRACE("Caps %#08x are supported for format %s.\n", caps, debug_d3dformat(format->f.id)); + format->f.caps[WINED3D_GL_RES_TYPE_TEX_1D] |= caps; format->f.caps[WINED3D_GL_RES_TYPE_TEX_2D] |= caps; format->f.caps[WINED3D_GL_RES_TYPE_TEX_3D] |= caps; @@ -4460,7 +4493,7 @@ BOOL wined3d_adapter_vk_init_format_info(struct wined3d_adapter_vk *adapter_vk, format = wined3d_format_vk_mutable(get_format_by_idx(adapter, i));
if (format->f.id) - init_vulkan_format_info(format, vk_info, vk_physical_device); + init_vulkan_format_info(adapter, format, vk_info, vk_physical_device); }
if (!init_typeless_formats(adapter)) goto fail;