diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 38ffbc31..f5b53b70 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -150,6 +150,9 @@ namespace dxvk { return E_INVALIDARG; } else { desc = *pDesc; + + if (FAILED(SetShaderResourceViewDescUnspecValues(pResource, &desc))) + return E_INVALIDARG; } if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { @@ -310,9 +313,6 @@ namespace dxvk { return E_INVALIDARG; } - if (viewInfo.numLevels == 0xFFFFFFFF) - viewInfo.numLevels = textureInfo->image->info().mipLevels - viewInfo.minLevel; - if (ppSRView == nullptr) return S_FALSE; @@ -1522,6 +1522,19 @@ namespace dxvk { pResource->GetType(&resourceDim); switch (resourceDim) { + case D3D11_RESOURCE_DIMENSION_BUFFER: { + D3D11_BUFFER_DESC bufferDesc; + static_cast(pResource)->GetDesc(&bufferDesc); + + if (bufferDesc.MiscFlags == D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) { + pDesc->Format = DXGI_FORMAT_UNKNOWN; + pDesc->ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + pDesc->Buffer.FirstElement = 0; + pDesc->Buffer.NumElements = bufferDesc.ByteWidth / bufferDesc.StructureByteStride; + return S_OK; + } + } return E_INVALIDARG; + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: { D3D11_TEXTURE1D_DESC resourceDesc; static_cast(pResource)->GetDesc(&resourceDesc); @@ -1597,6 +1610,142 @@ namespace dxvk { } + HRESULT D3D11Device::SetShaderResourceViewDescUnspecValues( + ID3D11Resource* pResource, + D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc) { + D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + pResource->GetType(&resourceDim); + + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + uint32_t mipLevels = 0; + uint32_t numLayers = 0; + + switch (resourceDim) { + case D3D11_RESOURCE_DIMENSION_BUFFER: { + if (pDesc->ViewDimension != D3D11_SRV_DIMENSION_BUFFER + && pDesc->ViewDimension != D3D11_SRV_DIMENSION_BUFFEREX) { + Logger::err("D3D11: Incompatible view dimension for Buffer"); + return E_INVALIDARG; + } + } break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: { + D3D11_TEXTURE1D_DESC resourceDesc; + static_cast(pResource)->GetDesc(&resourceDesc); + + if (pDesc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE1D + && pDesc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE1DARRAY) { + Logger::err("D3D11: Incompatible view dimension for Texture1D"); + return E_INVALIDARG; + } + + format = resourceDesc.Format; + mipLevels = resourceDesc.MipLevels; + numLayers = resourceDesc.ArraySize; + } break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: { + D3D11_TEXTURE2D_DESC resourceDesc; + static_cast(pResource)->GetDesc(&resourceDesc); + + if (pDesc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2D + && pDesc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DARRAY + && pDesc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DMS + && pDesc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY + && pDesc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURECUBE + && pDesc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURECUBEARRAY) { + Logger::err("D3D11: Incompatible view dimension for Texture2D"); + return E_INVALIDARG; + } + + format = resourceDesc.Format; + mipLevels = resourceDesc.MipLevels; + numLayers = resourceDesc.ArraySize; + } break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: { + D3D11_TEXTURE3D_DESC resourceDesc; + static_cast(pResource)->GetDesc(&resourceDesc); + + if (pDesc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE3D) { + Logger::err("D3D11: Incompatible view dimension for Texture3D"); + return E_INVALIDARG; + } + + format = resourceDesc.Format; + mipLevels = resourceDesc.MipLevels; + numLayers = 1; + } break; + + default: + return E_INVALIDARG; + } + + if (pDesc->Format == DXGI_FORMAT_UNKNOWN) + pDesc->Format = format; + + switch (pDesc->ViewDimension) { + case D3D11_SRV_DIMENSION_BUFFER: + case D3D11_SRV_DIMENSION_BUFFEREX: + break; + + case D3D11_SRV_DIMENSION_TEXTURE1D: + if (pDesc->Texture1D.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + pDesc->Texture1D.MipLevels = mipLevels - pDesc->Texture1D.MostDetailedMip; + break; + + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: + if (pDesc->Texture1DArray.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + pDesc->Texture1DArray.MipLevels = mipLevels - pDesc->Texture1DArray.MostDetailedMip; + if (pDesc->Texture1DArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + pDesc->Texture1DArray.ArraySize = numLayers - pDesc->Texture1DArray.FirstArraySlice; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2D: + if (pDesc->Texture2D.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + pDesc->Texture2D.MipLevels = mipLevels - pDesc->Texture2D.MostDetailedMip; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + if (pDesc->Texture2DArray.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + pDesc->Texture2DArray.MipLevels = mipLevels - pDesc->Texture2DArray.MostDetailedMip; + if (pDesc->Texture2DArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + pDesc->Texture2DArray.ArraySize = numLayers - pDesc->Texture2DArray.FirstArraySlice; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DMS: + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: + if (pDesc->Texture2DMSArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + pDesc->Texture2DMSArray.ArraySize = numLayers - pDesc->Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_SRV_DIMENSION_TEXTURECUBE: + if (pDesc->TextureCube.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + pDesc->TextureCube.MipLevels = mipLevels - pDesc->TextureCube.MostDetailedMip; + break; + + case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: + if (pDesc->TextureCubeArray.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + pDesc->TextureCubeArray.MipLevels = mipLevels - pDesc->TextureCubeArray.MostDetailedMip; + if (pDesc->TextureCubeArray.NumCubes == D3D11_DXVK_USE_REMAINING_LAYERS) + pDesc->TextureCubeArray.NumCubes = (mipLevels - pDesc->TextureCubeArray.First2DArrayFace / 6); + break; + + case D3D11_SRV_DIMENSION_TEXTURE3D: + if (pDesc->Texture3D.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + pDesc->Texture3D.MipLevels = mipLevels - pDesc->Texture3D.MostDetailedMip; + break; + + default: + break; + } + + return S_OK; + } + + HRESULT D3D11Device::GetRenderTargetViewDescFromResource( ID3D11Resource* pResource, D3D11_RENDER_TARGET_VIEW_DESC* pDesc) { diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 42275bf2..f570a1f4 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -313,6 +313,10 @@ namespace dxvk { ID3D11Resource* pResource, D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc); + HRESULT SetShaderResourceViewDescUnspecValues( + ID3D11Resource* pResource, + D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc); + VkSamplerAddressMode DecodeAddressMode( D3D11_TEXTURE_ADDRESS_MODE mode) const; diff --git a/src/d3d11/d3d11_include.h b/src/d3d11/d3d11_include.h index 30163c14..54d3a1d2 100644 --- a/src/d3d11/d3d11_include.h +++ b/src/d3d11/d3d11_include.h @@ -17,6 +17,9 @@ #define D3D11_KEEP_UNORDERED_ACCESS_VIEWS 0xFFFFFFFF #endif +#define D3D11_DXVK_USE_REMAINING_LAYERS 0xFFFFFFFF +#define D3D11_DXVK_USE_REMAINING_LEVELS 0xFFFFFFFF + // Most of these were copied from d3d11.h // For some strange reason, we cannot use the structures // directly, although others from the same header work.