1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-06 04:46:17 +01:00

[d3d11] Validate image view format compatibility correctly

Prevents the application from creating illegal image views.
This commit is contained in:
Philip Rebohle 2018-08-09 23:34:03 +02:00
parent 7e0a2a9165
commit 9373bab3e3
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 38 additions and 20 deletions

View File

@ -205,35 +205,53 @@ namespace dxvk {
bool D3D11CommonTexture::CheckViewCompatibility(UINT BindFlags, DXGI_FORMAT Format) const { bool D3D11CommonTexture::CheckViewCompatibility(UINT BindFlags, DXGI_FORMAT Format) const {
const DxvkImageCreateInfo& imageInfo = m_image->info();
// Check whether the given bind flags are supported // Check whether the given bind flags are supported
VkImageUsageFlags usage = GetImageUsageFlags(BindFlags); VkImageUsageFlags usage = GetImageUsageFlags(BindFlags);
if ((m_image->info().usage & usage) != usage) if ((imageInfo.usage & usage) != usage)
return false; return false;
// Check whether the view format is compatible // Check whether the view format is compatible
DXGI_VK_FORMAT_MODE formatMode = GetFormatMode(); DXGI_VK_FORMAT_MODE formatMode = GetFormatMode();
DXGI_VK_FORMAT_INFO baseFormat = m_device->LookupFormat(m_desc.Format, formatMode);
DXGI_VK_FORMAT_INFO viewFormat = m_device->LookupFormat(Format, formatMode); DXGI_VK_FORMAT_INFO viewFormat = m_device->LookupFormat(Format, formatMode);
DXGI_VK_FORMAT_INFO baseFormat = m_device->LookupFormat(m_desc.Format, formatMode);
// Identical formats always pass this test if (imageInfo.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
if (baseFormat.Format == viewFormat.Format) // Check whether the given combination of image
// view type and view format is actually supported
VkFormatFeatureFlags features = GetImageFormatFeatures(BindFlags);
if (!CheckFormatFeatureSupport(viewFormat.Format, features))
return false;
// Using the image format itself is always legal
if (viewFormat.Format == baseFormat.Format)
return true; return true;
// The available image aspects must match // If there is a list of compatible formats, the
// view format must be included in that list.
for (size_t i = 0; i < imageInfo.viewFormatCount; i++) {
if (imageInfo.viewFormats[i] == viewFormat.Format)
return true;
}
// Otherwise, all bit-compatible formats can be used.
if (imageInfo.viewFormatCount == 0) {
auto baseFormatInfo = imageFormatInfo(baseFormat.Format); auto baseFormatInfo = imageFormatInfo(baseFormat.Format);
auto viewFormatInfo = imageFormatInfo(viewFormat.Format); auto viewFormatInfo = imageFormatInfo(viewFormat.Format);
if (baseFormatInfo->aspectMask != viewFormatInfo->aspectMask) return baseFormatInfo->aspectMask == viewFormatInfo->aspectMask
return false; && baseFormatInfo->elementSize == viewFormatInfo->elementSize;
}
// Color formats can be reinterpreted. This is not restricted
// to typeless formats, we we can create SRGB views for UNORM
// textures as well etc. as long as they are bit-compatible.
if (baseFormatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT)
return baseFormatInfo->elementSize == viewFormatInfo->elementSize;
return false; return false;
} else {
// For non-mutable images, the view format
// must be identical to the image format.
return viewFormat.Format == baseFormat.Format;
}
} }

View File

@ -195,7 +195,7 @@ namespace dxvk {
BOOL CheckFormatFeatureSupport( BOOL CheckFormatFeatureSupport(
VkFormat Format, VkFormat Format,
VkImageUsageFlags Features) const; VkFormatFeatureFlags Features) const;
D3D11_COMMON_TEXTURE_MAP_MODE DetermineMapMode( D3D11_COMMON_TEXTURE_MAP_MODE DetermineMapMode(
const DxvkImageCreateInfo* pImageInfo) const; const DxvkImageCreateInfo* pImageInfo) const;