[d3d11] Validate image view bind flags

Since the bind flags of the texture may not always match the
image usage flags of the underlying Vulkan image, we should
use the latter to check whether a view can be created.
This commit is contained in:
Philip Rebohle 2018-08-09 21:58:58 +02:00
parent cdc85a1238
commit b06eb4fe2a
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
5 changed files with 25 additions and 77 deletions

View File

@ -288,19 +288,9 @@ namespace dxvk {
return E_INVALIDARG;
}
// Check whether SRVs are supported for the resource at all
if (!CheckResourceBindFlags(pResource, D3D11_BIND_SHADER_RESOURCE)) {
Logger::err("D3D11: Trying to create SRV for texture without D3D11_BIND_SHADER_RESOURCE");
if (!CheckResourceViewCompatibility(pResource, D3D11_BIND_SHADER_RESOURCE, desc.Format))
return E_INVALIDARG;
}
// Check whether we can use the requested format for the view
if (!CheckResourceViewFormatCompatibility(pResource, desc.Format)) {
Logger::err(str::format("D3D11: Incompatible SRV format: ", desc.Format));
return E_INVALIDARG;
}
// Create the actual view if requested
if (ppSRView == nullptr)
return S_FALSE;
@ -337,19 +327,9 @@ namespace dxvk {
return E_INVALIDARG;
}
// Check whether UAVs are supported for the resource at all
if (!CheckResourceBindFlags(pResource, D3D11_BIND_UNORDERED_ACCESS)) {
Logger::err("D3D11: Trying to create UAV for texture without D3D11_BIND_UNORDERED_ACCESS");
if (!CheckResourceViewCompatibility(pResource, D3D11_BIND_UNORDERED_ACCESS, desc.Format))
return E_INVALIDARG;
}
// Check whether we can use the requested format for the view
if (!CheckResourceViewFormatCompatibility(pResource, desc.Format)) {
Logger::err(str::format("D3D11: Incompatible UAV format: ", desc.Format));
return E_INVALIDARG;
}
// Create the view if requested
if (ppUAView == nullptr)
return S_FALSE;
@ -392,19 +372,9 @@ namespace dxvk {
return E_INVALIDARG;
}
// Check whether UAVs are supported for the resource at all
if (!CheckResourceBindFlags(pResource, D3D11_BIND_RENDER_TARGET)) {
Logger::err("D3D11: Trying to create RTV for texture without D3D11_BIND_RENDER_TARGET");
if (!CheckResourceViewCompatibility(pResource, D3D11_BIND_RENDER_TARGET, desc.Format))
return E_INVALIDARG;
}
// Check whether we can use the requested format for the view
if (!CheckResourceViewFormatCompatibility(pResource, desc.Format)) {
Logger::err(str::format("D3D11: Incompatible RTV format: ", desc.Format));
return E_INVALIDARG;
}
// Create the actual image view if requested
if (ppRTView == nullptr)
return S_FALSE;
@ -438,19 +408,9 @@ namespace dxvk {
return E_INVALIDARG;
}
// Check whether DSVs are supported for the resource at all
if (!CheckResourceBindFlags(pResource, D3D11_BIND_DEPTH_STENCIL)) {
Logger::warn("D3D11: Trying to create DSV for texture without D3D11_BIND_DEPTH_STENCIL");
if (!CheckResourceViewCompatibility(pResource, D3D11_BIND_DEPTH_STENCIL, desc.Format))
return E_INVALIDARG;
}
// Check whether we can use the requested format for the view
if (!CheckResourceViewFormatCompatibility(pResource, desc.Format)) {
Logger::err(str::format("D3D11: Incompatible DSV format: ", desc.Format));
return E_INVALIDARG;
}
// Create the actual image view if requested
if (ppDepthStencilView == nullptr)
return S_FALSE;

View File

@ -30,23 +30,14 @@ namespace dxvk {
}
BOOL CheckResourceBindFlags(
ID3D11Resource* pResource,
UINT BindFlags) {
D3D11_COMMON_RESOURCE_DESC desc;
GetCommonResourceDesc(pResource, &desc);
return (desc.BindFlags & BindFlags) == BindFlags;
}
BOOL CheckResourceViewFormatCompatibility(
BOOL CheckResourceViewCompatibility(
ID3D11Resource* pResource,
UINT BindFlags,
DXGI_FORMAT Format) {
auto texture = GetCommonTexture(pResource);
return texture != nullptr
? texture->CheckViewFormatCompatibility(Format)
? texture->CheckViewCompatibility(BindFlags, Format)
: true; /* for buffers */
}

View File

@ -31,21 +31,6 @@ namespace dxvk {
ID3D11Resource* pResource,
D3D11_COMMON_RESOURCE_DESC* pDesc);
/**
* \brief Checks whether a resource has the given bind flags
*
* Convenience method that checks whether a resource
* was created with \c all the specified bind flags
* set. Can be used to check whether a specific type
* of view can be created for this resource.
* \param [in] pResource The resource to check
* \param [in] BindFlags Bind flags to check
* \returns \c true if the resource supports the flags
*/
BOOL CheckResourceBindFlags(
ID3D11Resource* pResource,
UINT BindFlags);
/**
* \brief Checks whether a format can be used to view a resource
*
@ -56,8 +41,9 @@ namespace dxvk {
* \param [in] Format The desired view format
* \returns \c true if the format is compatible
*/
BOOL CheckResourceViewFormatCompatibility(
BOOL CheckResourceViewCompatibility(
ID3D11Resource* pResource,
UINT BindFlags,
DXGI_FORMAT Format);
/**

View File

@ -204,10 +204,17 @@ namespace dxvk {
}
bool D3D11CommonTexture::CheckViewFormatCompatibility(DXGI_FORMAT Format) const {
bool D3D11CommonTexture::CheckViewCompatibility(UINT BindFlags, DXGI_FORMAT Format) const {
// Check whether the given bind flags are supported
VkImageUsageFlags usage = GetImageUsageFlags(BindFlags);
if ((m_image->info().usage & usage) != usage)
return false;
// Check whether the view format is compatible
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);
// Identical formats always pass this test
if (baseFormat.Format == viewFormat.Format)

View File

@ -149,15 +149,19 @@ namespace dxvk {
void GetDevice(ID3D11Device** ppDevice) const;
/**
* \brief Checks whether a format can be used to view this textue
* \brief Checks whether a view can be created for this textue
*
* View formats are only compatible if they are either identical
* or from the same family of typeless formats, where the resource
* format must be typeless and the view format must be typed.
* format must be typeless and the view format must be typed. This
* will also check whether the required bind flags are supported.
* \param [in] BindFlags Bind flags for the view
* \param [in] Format The desired view format
* \returns \c true if the format is compatible
*/
bool CheckViewFormatCompatibility(DXGI_FORMAT Format) const;
bool CheckViewCompatibility(
UINT BindFlags,
DXGI_FORMAT Format) const;
/**
* \brief Normalizes and validates texture description