mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-18 13:54:16 +01:00
[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:
parent
cdc85a1238
commit
b06eb4fe2a
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user