diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index e70a109f..299d0c43 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -271,9 +271,6 @@ namespace dxvk { ID3D11ShaderResourceView** ppSRView) { InitReturnPtr(ppSRView); - D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - pResource->GetType(&resourceDim); - // The description is optional. If omitted, we'll create // a view that covers all subresources of the image. D3D11_SHADER_RESOURCE_VIEW_DESC desc; @@ -300,184 +297,16 @@ namespace dxvk { return E_INVALIDARG; } - if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { - auto resource = static_cast(pResource); - - D3D11_BUFFER_DESC resourceDesc; - resource->GetDesc(&resourceDesc); - - DxvkBufferViewCreateInfo viewInfo; - - D3D11_BUFFEREX_SRV bufInfo; - - if (desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX) { - bufInfo.FirstElement = desc.BufferEx.FirstElement; - bufInfo.NumElements = desc.BufferEx.NumElements; - bufInfo.Flags = desc.BufferEx.Flags; - } else if (desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFER) { - bufInfo.FirstElement = desc.Buffer.FirstElement; - bufInfo.NumElements = desc.Buffer.NumElements; - bufInfo.Flags = 0; - } else { - Logger::err("D3D11Device: Invalid buffer view dimension"); - return E_INVALIDARG; - } - - if (bufInfo.Flags & D3D11_BUFFEREX_SRV_FLAG_RAW) { - // Raw buffer view. We'll represent this as a - // uniform texel buffer with UINT32 elements. - viewInfo.format = VK_FORMAT_R32_UINT; - viewInfo.rangeOffset = sizeof(uint32_t) * bufInfo.FirstElement; - viewInfo.rangeLength = sizeof(uint32_t) * bufInfo.NumElements; - } else if (desc.Format == DXGI_FORMAT_UNKNOWN) { - // Structured buffer view - viewInfo.format = VK_FORMAT_R32_UINT; - viewInfo.rangeOffset = resourceDesc.StructureByteStride * bufInfo.FirstElement; - viewInfo.rangeLength = resourceDesc.StructureByteStride * bufInfo.NumElements; - } else { - // Typed buffer view - must use an uncompressed color format - viewInfo.format = m_dxgiAdapter->LookupFormat( - desc.Format, DXGI_VK_FORMAT_MODE_COLOR).Format; - - const DxvkFormatInfo* formatInfo = imageFormatInfo(viewInfo.format); - viewInfo.rangeOffset = formatInfo->elementSize * bufInfo.FirstElement; - viewInfo.rangeLength = formatInfo->elementSize * bufInfo.NumElements; - - if (formatInfo->flags.test(DxvkFormatFlag::BlockCompressed)) { - Logger::err("D3D11Device: Compressed formats for buffer views not supported"); - return E_INVALIDARG; - } - } - - if (ppSRView == nullptr) - return S_FALSE; - - try { - *ppSRView = ref(new D3D11ShaderResourceView( - this, pResource, desc, - m_dxvkDevice->createBufferView( - resource->GetBufferSlice().buffer(), viewInfo))); - return S_OK; - } catch (const DxvkError& e) { - Logger::err(e.message()); - return E_FAIL; - } - } else { - const D3D11CommonTexture* textureInfo = GetCommonTexture(pResource); - - // Fill in the view info. The view type depends solely - // on the view dimension field in the view description, - // not on the resource type. - const DXGI_VK_FORMAT_INFO formatInfo = m_dxgiAdapter - ->LookupFormat(desc.Format, textureInfo->GetFormatMode()); - - DxvkImageViewCreateInfo viewInfo; - viewInfo.format = formatInfo.Format; - viewInfo.aspect = formatInfo.Aspect; - viewInfo.swizzle = formatInfo.Swizzle; - viewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; - - // Shaders expect the stencil value in the G component - if (viewInfo.aspect == VK_IMAGE_ASPECT_STENCIL_BIT) { - viewInfo.swizzle = VkComponentMapping { - VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_R, - VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO }; - } - - switch (desc.ViewDimension) { - case D3D11_SRV_DIMENSION_TEXTURE1D: - viewInfo.type = VK_IMAGE_VIEW_TYPE_1D; - viewInfo.minLevel = desc.Texture1D.MostDetailedMip; - viewInfo.numLevels = desc.Texture1D.MipLevels; - viewInfo.minLayer = 0; - viewInfo.numLayers = 1; - break; - - case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: - viewInfo.type = VK_IMAGE_VIEW_TYPE_1D_ARRAY; - viewInfo.minLevel = desc.Texture1DArray.MostDetailedMip; - viewInfo.numLevels = desc.Texture1DArray.MipLevels; - viewInfo.minLayer = desc.Texture1DArray.FirstArraySlice; - viewInfo.numLayers = desc.Texture1DArray.ArraySize; - break; - - case D3D11_SRV_DIMENSION_TEXTURE2D: - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; - viewInfo.minLevel = desc.Texture2D.MostDetailedMip; - viewInfo.numLevels = desc.Texture2D.MipLevels; - viewInfo.minLayer = 0; - viewInfo.numLayers = 1; - break; - - case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - viewInfo.minLevel = desc.Texture2DArray.MostDetailedMip; - viewInfo.numLevels = desc.Texture2DArray.MipLevels; - viewInfo.minLayer = desc.Texture2DArray.FirstArraySlice; - viewInfo.numLayers = desc.Texture2DArray.ArraySize; - break; - - case D3D11_SRV_DIMENSION_TEXTURE2DMS: - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; - viewInfo.minLevel = 0; - viewInfo.numLevels = 1; - viewInfo.minLayer = 0; - viewInfo.numLayers = 1; - break; - - case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - viewInfo.minLevel = 0; - viewInfo.numLevels = 1; - viewInfo.minLayer = desc.Texture2DMSArray.FirstArraySlice; - viewInfo.numLayers = desc.Texture2DMSArray.ArraySize; - break; - - case D3D11_SRV_DIMENSION_TEXTURE3D: - viewInfo.type = VK_IMAGE_VIEW_TYPE_3D; - viewInfo.minLevel = desc.Texture3D.MostDetailedMip; - viewInfo.numLevels = desc.Texture3D.MipLevels; - viewInfo.minLayer = 0; - viewInfo.numLayers = 1; - break; - - case D3D11_SRV_DIMENSION_TEXTURECUBE: - viewInfo.type = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; - viewInfo.minLevel = desc.TextureCube.MostDetailedMip; - viewInfo.numLevels = desc.TextureCube.MipLevels; - viewInfo.minLayer = 0; - viewInfo.numLayers = 6; - break; - - case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: - viewInfo.type = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; - viewInfo.minLevel = desc.TextureCubeArray.MostDetailedMip; - viewInfo.numLevels = desc.TextureCubeArray.MipLevels; - viewInfo.minLayer = desc.TextureCubeArray.First2DArrayFace; - viewInfo.numLayers = desc.TextureCubeArray.NumCubes * 6; - break; - - default: - Logger::err(str::format( - "D3D11: View dimension not supported for SRV: ", - desc.ViewDimension)); - return E_INVALIDARG; - } - - if (ppSRView == nullptr) - return S_FALSE; - - try { - *ppSRView = ref(new D3D11ShaderResourceView( - this, pResource, desc, - m_dxvkDevice->createImageView( - textureInfo->GetImage(), - viewInfo))); - return S_OK; - } catch (const DxvkError& e) { - Logger::err(e.message()); - return E_FAIL; - } + // Create the actual view if requested + if (ppSRView == nullptr) + return S_FALSE; + + try { + *ppSRView = ref(new D3D11ShaderResourceView(this, pResource, &desc)); + return S_OK; + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_FAIL; } } diff --git a/src/d3d11/d3d11_view_srv.cpp b/src/d3d11/d3d11_view_srv.cpp index bf028777..fd3fa1e5 100644 --- a/src/d3d11/d3d11_view_srv.cpp +++ b/src/d3d11/d3d11_view_srv.cpp @@ -6,21 +6,156 @@ namespace dxvk { D3D11ShaderResourceView::D3D11ShaderResourceView( - D3D11Device* device, - ID3D11Resource* resource, - const D3D11_SHADER_RESOURCE_VIEW_DESC& desc, - const Rc& bufferView) - : m_device(device), m_resource(resource), - m_desc(desc), m_bufferView(bufferView) { } - - - D3D11ShaderResourceView::D3D11ShaderResourceView( - D3D11Device* device, - ID3D11Resource* resource, - const D3D11_SHADER_RESOURCE_VIEW_DESC& desc, - const Rc& imageView) - : m_device(device), m_resource(resource), - m_desc(desc), m_imageView(imageView) { } + D3D11Device* pDevice, + ID3D11Resource* pResource, + const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc) + : m_device(pDevice), m_resource(pResource), m_desc(*pDesc) { + D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + pResource->GetType(&resourceDim); + + if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { + auto buffer = static_cast(pResource); + + // Move buffer description to a common struct to + // avoid having to handle the two cases separately + D3D11_BUFFEREX_SRV bufInfo; + + if (pDesc->ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX) { + bufInfo.FirstElement = pDesc->BufferEx.FirstElement; + bufInfo.NumElements = pDesc->BufferEx.NumElements; + bufInfo.Flags = pDesc->BufferEx.Flags; + } else if (pDesc->ViewDimension == D3D11_SRV_DIMENSION_BUFFER) { + bufInfo.FirstElement = pDesc->Buffer.FirstElement; + bufInfo.NumElements = pDesc->Buffer.NumElements; + bufInfo.Flags = 0; + } else { + throw DxvkError("D3D11: Invalid view dimension for buffer SRV"); + } + + // Fill in buffer view info + DxvkBufferViewCreateInfo viewInfo; + + if (bufInfo.Flags & D3D11_BUFFEREX_SRV_FLAG_RAW) { + // Raw buffer view. We'll represent this as a + // uniform texel buffer with UINT32 elements. + viewInfo.format = VK_FORMAT_R32_UINT; + viewInfo.rangeOffset = sizeof(uint32_t) * bufInfo.FirstElement; + viewInfo.rangeLength = sizeof(uint32_t) * bufInfo.NumElements; + } else if (pDesc->Format == DXGI_FORMAT_UNKNOWN) { + // Structured buffer view + viewInfo.format = VK_FORMAT_R32_UINT; + viewInfo.rangeOffset = buffer->Desc()->StructureByteStride * bufInfo.FirstElement; + viewInfo.rangeLength = buffer->Desc()->StructureByteStride * bufInfo.NumElements; + } else { + viewInfo.format = pDevice->LookupFormat(pDesc->Format, DXGI_VK_FORMAT_MODE_COLOR).Format; + + const DxvkFormatInfo* formatInfo = imageFormatInfo(viewInfo.format); + viewInfo.rangeOffset = formatInfo->elementSize * bufInfo.FirstElement; + viewInfo.rangeLength = formatInfo->elementSize * bufInfo.NumElements; + } + + // Create underlying buffer view object + m_bufferView = pDevice->GetDXVKDevice()->createBufferView( + buffer->GetBuffer(), viewInfo); + } else { + const DXGI_VK_FORMAT_INFO formatInfo = pDevice->LookupFormat( + pDesc->Format, GetCommonTexture(pResource)->GetFormatMode()); + + DxvkImageViewCreateInfo viewInfo; + viewInfo.format = formatInfo.Format; + viewInfo.aspect = formatInfo.Aspect; + viewInfo.swizzle = formatInfo.Swizzle; + viewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + + // Shaders expect the stencil value in the G component + if (viewInfo.aspect == VK_IMAGE_ASPECT_STENCIL_BIT) { + viewInfo.swizzle = VkComponentMapping { + VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_R, + VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO }; + } + + switch (pDesc->ViewDimension) { + case D3D11_SRV_DIMENSION_TEXTURE1D: + viewInfo.type = VK_IMAGE_VIEW_TYPE_1D; + viewInfo.minLevel = pDesc->Texture1D.MostDetailedMip; + viewInfo.numLevels = pDesc->Texture1D.MipLevels; + viewInfo.minLayer = 0; + viewInfo.numLayers = 1; + break; + + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: + viewInfo.type = VK_IMAGE_VIEW_TYPE_1D_ARRAY; + viewInfo.minLevel = pDesc->Texture1DArray.MostDetailedMip; + viewInfo.numLevels = pDesc->Texture1DArray.MipLevels; + viewInfo.minLayer = pDesc->Texture1DArray.FirstArraySlice; + viewInfo.numLayers = pDesc->Texture1DArray.ArraySize; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2D: + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.minLevel = pDesc->Texture2D.MostDetailedMip; + viewInfo.numLevels = pDesc->Texture2D.MipLevels; + viewInfo.minLayer = 0; + viewInfo.numLayers = 1; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + viewInfo.minLevel = pDesc->Texture2DArray.MostDetailedMip; + viewInfo.numLevels = pDesc->Texture2DArray.MipLevels; + viewInfo.minLayer = pDesc->Texture2DArray.FirstArraySlice; + viewInfo.numLayers = pDesc->Texture2DArray.ArraySize; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DMS: + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.minLevel = 0; + viewInfo.numLevels = 1; + viewInfo.minLayer = 0; + viewInfo.numLayers = 1; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + viewInfo.minLevel = 0; + viewInfo.numLevels = 1; + viewInfo.minLayer = pDesc->Texture2DMSArray.FirstArraySlice; + viewInfo.numLayers = pDesc->Texture2DMSArray.ArraySize; + break; + + case D3D11_SRV_DIMENSION_TEXTURE3D: + viewInfo.type = VK_IMAGE_VIEW_TYPE_3D; + viewInfo.minLevel = pDesc->Texture3D.MostDetailedMip; + viewInfo.numLevels = pDesc->Texture3D.MipLevels; + viewInfo.minLayer = 0; + viewInfo.numLayers = 1; + break; + + case D3D11_SRV_DIMENSION_TEXTURECUBE: + viewInfo.type = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; + viewInfo.minLevel = pDesc->TextureCube.MostDetailedMip; + viewInfo.numLevels = pDesc->TextureCube.MipLevels; + viewInfo.minLayer = 0; + viewInfo.numLayers = 6; + break; + + case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: + viewInfo.type = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; + viewInfo.minLevel = pDesc->TextureCubeArray.MostDetailedMip; + viewInfo.numLevels = pDesc->TextureCubeArray.MipLevels; + viewInfo.minLayer = pDesc->TextureCubeArray.First2DArrayFace; + viewInfo.numLayers = pDesc->TextureCubeArray.NumCubes * 6; + break; + + default: + throw DxvkError("D3D11: Invalid view dimension for image SRV"); + } + + // Create the underlying image view object + m_imageView = pDevice->GetDXVKDevice()->createImageView( + GetCommonTexture(pResource)->GetImage(), viewInfo); + } + } D3D11ShaderResourceView::~D3D11ShaderResourceView() { diff --git a/src/d3d11/d3d11_view_srv.h b/src/d3d11/d3d11_view_srv.h index 82e0b9db..3829d203 100644 --- a/src/d3d11/d3d11_view_srv.h +++ b/src/d3d11/d3d11_view_srv.h @@ -16,16 +16,9 @@ namespace dxvk { public: D3D11ShaderResourceView( - D3D11Device* device, - ID3D11Resource* resource, - const D3D11_SHADER_RESOURCE_VIEW_DESC& desc, - const Rc& bufferView); - - D3D11ShaderResourceView( - D3D11Device* device, - ID3D11Resource* resource, - const D3D11_SHADER_RESOURCE_VIEW_DESC& desc, - const Rc& imageView); + D3D11Device* pDevice, + ID3D11Resource* pResource, + const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc); ~D3D11ShaderResourceView();