From 8e3c14d8ab4d2cbcfe63bcc594e8b161cc4b9766 Mon Sep 17 00:00:00 2001 From: Philip Rebohle <philip.rebohle@tu-dortmund.de> Date: Sat, 9 Dec 2017 19:36:38 +0100 Subject: [PATCH] [d3d11] Cleaned up view creation a bit --- src/d3d11/d3d11_device.cpp | 353 ++++++++++++++++++------------------- 1 file changed, 171 insertions(+), 182 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 0dcfc937f..5ac8c7092 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -244,11 +244,11 @@ namespace dxvk { ID3D11Resource* pResource, const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc, ID3D11ShaderResourceView** ppSRView) { - // Shader resource views can access pretty much anything D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pResource->GetType(&resourceDim); - // Retrieve a usable resource view description + // The description is optional. If omitted, we'll create + // a view that covers all subresources of the image. D3D11_SHADER_RESOURCE_VIEW_DESC desc; if (pDesc == nullptr) { @@ -262,84 +262,92 @@ namespace dxvk { Logger::err("D3D11: Shader resource views for buffers not yet supported"); return E_INVALIDARG; } else { - // Create an image view. View type and accessed subresources - // are determined by the view dimension field in the shader - // resource view description. - DxvkImageViewCreateInfo info; - info.format = m_dxgiAdapter->LookupFormat(desc.Format).actual; - info.aspect = imageFormatInfo(info.format)->aspectMask; + // Retrieve the image that we are going to create a view for + Com<IDXGIImageResourcePrivate> imageResource; + + if (FAILED(pResource->QueryInterface( + __uuidof(IDXGIImageResourcePrivate), + reinterpret_cast<void**>(&imageResource)))) + return E_INVALIDARG; + + // Fill in the view info. The view type depends solely + // on the view dimension field in the view description, + // not on the resource type. + DxvkImageViewCreateInfo viewInfo; + viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format).actual; + viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; switch (desc.ViewDimension) { case D3D11_SRV_DIMENSION_TEXTURE1D: - info.type = VK_IMAGE_VIEW_TYPE_1D; - info.minLevel = desc.Texture1D.MostDetailedMip; - info.numLevels = desc.Texture1D.MipLevels; - info.minLayer = 0; - info.numLayers = 1; + 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: - info.type = VK_IMAGE_VIEW_TYPE_1D_ARRAY; - info.minLevel = desc.Texture1DArray.MostDetailedMip; - info.numLevels = desc.Texture1DArray.MipLevels; - info.minLayer = desc.Texture1DArray.FirstArraySlice; - info.numLayers = desc.Texture1DArray.ArraySize; + 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: - info.type = VK_IMAGE_VIEW_TYPE_2D; - info.minLevel = desc.Texture2D.MostDetailedMip; - info.numLevels = desc.Texture2D.MipLevels; - info.minLayer = 0; - info.numLayers = 1; + 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: - info.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - info.minLevel = desc.Texture2DArray.MostDetailedMip; - info.numLevels = desc.Texture2DArray.MipLevels; - info.minLayer = desc.Texture2DArray.FirstArraySlice; - info.numLayers = desc.Texture2DArray.ArraySize; + 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: - info.type = VK_IMAGE_VIEW_TYPE_2D; - info.minLevel = 0; - info.numLevels = 1; - info.minLayer = 0; - info.numLayers = 1; + 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: - info.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - info.minLevel = 0; - info.numLevels = 1; - info.minLayer = desc.Texture2DMSArray.FirstArraySlice; - info.numLayers = desc.Texture2DMSArray.ArraySize; + 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: - info.type = VK_IMAGE_VIEW_TYPE_3D; - info.minLevel = desc.Texture3D.MostDetailedMip; - info.numLevels = desc.Texture3D.MipLevels; - info.minLayer = 0; - info.numLayers = 1; + 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: - info.type = VK_IMAGE_VIEW_TYPE_CUBE; - info.minLevel = desc.TextureCube.MostDetailedMip; - info.numLevels = desc.TextureCube.MipLevels; - info.minLayer = 0; - info.numLayers = 6; + viewInfo.type = VK_IMAGE_VIEW_TYPE_CUBE; + viewInfo.minLevel = desc.TextureCube.MostDetailedMip; + viewInfo.numLevels = desc.TextureCube.MipLevels; + viewInfo.minLayer = 0; + viewInfo.numLayers = 6; break; case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: - info.type = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; - info.minLevel = desc.TextureCubeArray.MostDetailedMip; - info.numLevels = desc.TextureCubeArray.MipLevels; - info.minLayer = desc.TextureCubeArray.First2DArrayFace; - info.numLayers = desc.TextureCubeArray.NumCubes * 6; + 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: @@ -349,24 +357,15 @@ namespace dxvk { return E_INVALIDARG; } - Com<IDXGIImageResourcePrivate> imageResource; - - if (FAILED(pResource->QueryInterface( - __uuidof(IDXGIImageResourcePrivate), - reinterpret_cast<void**>(&imageResource)))) { - Logger::err("D3D11: Invalid image for SRV"); - return E_INVALIDARG; - } + if (ppSRView == nullptr) + return S_OK; try { - if (ppSRView != nullptr) { - *ppSRView = ref(new D3D11ShaderResourceView( - this, pResource, desc, nullptr, - m_dxvkDevice->createImageView( - imageResource->GetDXVKImage(), - info))); - } - + *ppSRView = ref(new D3D11ShaderResourceView( + this, pResource, desc, nullptr, + m_dxvkDevice->createImageView( + imageResource->GetDXVKImage(), + viewInfo))); return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); @@ -398,66 +397,25 @@ namespace dxvk { return E_INVALIDARG; } - // Retrieve the image that we are going to create the view for - auto texture = static_cast<D3D11Texture2D*>(pResource); - const Rc<DxvkImage> image = texture->GetDXVKImage(); - // The view description is optional. If not defined, it // will use the resource's format and all array layers. D3D11_RENDER_TARGET_VIEW_DESC desc; - if (pDesc != nullptr) { - desc = *pDesc; + if (pDesc == nullptr) { + if (FAILED(GetRenderTargetViewDescFromResource(pResource, &desc))) + return E_INVALIDARG; } else { - D3D11_TEXTURE2D_DESC texDesc; - texture->GetDesc(&texDesc); - - // Select the view dimension based on the - // texture's array size and sample count. - const std::array<D3D11_RTV_DIMENSION, 4> viewDims = { - D3D11_RTV_DIMENSION_TEXTURE2D, - D3D11_RTV_DIMENSION_TEXTURE2DARRAY, - D3D11_RTV_DIMENSION_TEXTURE2DMS, - D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY, - }; - - uint32_t viewDimIndex = 0; - - if (texDesc.ArraySize > 1) - viewDimIndex |= 0x1; - - if (texDesc.SampleDesc.Count > 1) - viewDimIndex |= 0x2; - - // Fill the correct union member - desc.ViewDimension = viewDims.at(viewDimIndex); - desc.Format = texDesc.Format; - - switch (desc.ViewDimension) { - case D3D11_RTV_DIMENSION_TEXTURE2D: - desc.Texture2D.MipSlice = 0; - break; - - case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: - desc.Texture2DArray.MipSlice = 0; - desc.Texture2DArray.FirstArraySlice = 0; - desc.Texture2DArray.ArraySize = texDesc.ArraySize; - break; - - case D3D11_RTV_DIMENSION_TEXTURE2DMS: - break; - - case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: - desc.Texture2DMSArray.FirstArraySlice = 0; - desc.Texture2DMSArray.ArraySize = texDesc.ArraySize; - break; - - default: - Logger::err("D3D11Device::CreateRenderTargetView: Internal error"); - return DXGI_ERROR_DRIVER_INTERNAL_ERROR; - } + desc = *pDesc; } + // Retrieve the image that we are going to create the view for + Com<IDXGIImageResourcePrivate> imageResource; + + if (FAILED(pResource->QueryInterface( + __uuidof(IDXGIImageResourcePrivate), + reinterpret_cast<void**>(&imageResource)))) + return E_INVALIDARG; + // Fill in Vulkan image view info DxvkImageViewCreateInfo viewInfo; viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format).actual; @@ -508,9 +466,11 @@ namespace dxvk { return S_OK; try { - Rc<DxvkImageView> view = m_dxvkDevice->createImageView(image, viewInfo); *ppRTView = ref(new D3D11RenderTargetView( - this, pResource, desc, nullptr, view)); + this, pResource, desc, nullptr, + m_dxvkDevice->createImageView( + imageResource->GetDXVKImage(), + viewInfo))); return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); @@ -532,66 +492,25 @@ namespace dxvk { return E_INVALIDARG; } - // Retrieve the image that we are going to create the view for - auto texture = static_cast<D3D11Texture2D*>(pResource); - const Rc<DxvkImage> image = texture->GetDXVKImage(); - // The view description is optional. If not defined, it // will use the resource's format and all array layers. D3D11_DEPTH_STENCIL_VIEW_DESC desc; - if (pDesc != nullptr) { - desc = *pDesc; + if (pDesc == nullptr) { + if (FAILED(GetDepthStencilViewDescFromResource(pResource, &desc))) + return E_INVALIDARG; } else { - D3D11_TEXTURE2D_DESC texDesc; - texture->GetDesc(&texDesc); - - // Select the view dimension based on the - // texture's array size and sample count. - const std::array<D3D11_DSV_DIMENSION, 4> viewDims = { - D3D11_DSV_DIMENSION_TEXTURE2D, - D3D11_DSV_DIMENSION_TEXTURE2DARRAY, - D3D11_DSV_DIMENSION_TEXTURE2DMS, - D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY, - }; - - uint32_t viewDimIndex = 0; - - if (texDesc.ArraySize > 1) - viewDimIndex |= 0x1; - - if (texDesc.SampleDesc.Count > 1) - viewDimIndex |= 0x2; - - // Fill the correct union member - desc.ViewDimension = viewDims.at(viewDimIndex); - desc.Format = texDesc.Format; - - switch (desc.ViewDimension) { - case D3D11_DSV_DIMENSION_TEXTURE2D: - desc.Texture2D.MipSlice = 0; - break; - - case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: - desc.Texture2DArray.MipSlice = 0; - desc.Texture2DArray.FirstArraySlice = 0; - desc.Texture2DArray.ArraySize = texDesc.ArraySize; - break; - - case D3D11_DSV_DIMENSION_TEXTURE2DMS: - break; - - case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: - desc.Texture2DMSArray.FirstArraySlice = 0; - desc.Texture2DMSArray.ArraySize = texDesc.ArraySize; - break; - - default: - Logger::err("D3D11Device::CreateDepthStencilView: Internal error"); - return DXGI_ERROR_DRIVER_INTERNAL_ERROR; - } + desc = *pDesc; } + // Retrieve the image that we are going to create the view for + Com<IDXGIImageResourcePrivate> imageResource; + + if (FAILED(pResource->QueryInterface( + __uuidof(IDXGIImageResourcePrivate), + reinterpret_cast<void**>(&imageResource)))) + return E_INVALIDARG; + // Fill in Vulkan image view info DxvkImageViewCreateInfo viewInfo; viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format).actual; @@ -642,9 +561,11 @@ namespace dxvk { return S_OK; try { - Rc<DxvkImageView> view = m_dxvkDevice->createImageView(image, viewInfo); *ppDepthStencilView = ref(new D3D11DepthStencilView( - this, pResource, desc, nullptr, view)); + this, pResource, desc, nullptr, + m_dxvkDevice->createImageView( + imageResource->GetDXVKImage(), + viewInfo))); return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); @@ -1251,9 +1172,7 @@ namespace dxvk { HRESULT D3D11Device::GetUnorderedAccessViewDescFromResource( ID3D11Resource* pResource, D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc) { - D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - pResource->GetType(&resourceDim); - + return E_NOTIMPL; } @@ -1263,6 +1182,41 @@ namespace dxvk { D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pResource->GetType(&resourceDim); + switch (resourceDim) { + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: { + D3D11_TEXTURE2D_DESC resourceDesc; + static_cast<D3D11Texture2D*>(pResource)->GetDesc(&resourceDesc); + + pDesc->Format = resourceDesc.Format; + + if (resourceDesc.SampleDesc.Count == 1) { + if (resourceDesc.ArraySize == 1) { + pDesc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + pDesc->Texture2D.MipSlice = 0; + } else { + pDesc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + pDesc->Texture2DArray.MipSlice = 0; + pDesc->Texture2DArray.FirstArraySlice = 0; + pDesc->Texture2DArray.ArraySize = resourceDesc.ArraySize; + } + } else { + if (resourceDesc.ArraySize == 1) { + pDesc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + } else { + pDesc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; + pDesc->Texture2DMSArray.FirstArraySlice = 0; + pDesc->Texture2DMSArray.ArraySize = resourceDesc.ArraySize; + } + } + } return S_OK; + + default: + Logger::err(str::format( + "D3D11: Unsupported dimension for render target view: ", + resourceDim)); + return E_INVALIDARG; + } } @@ -1272,6 +1226,41 @@ namespace dxvk { D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pResource->GetType(&resourceDim); + switch (resourceDim) { + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: { + D3D11_TEXTURE2D_DESC resourceDesc; + static_cast<D3D11Texture2D*>(pResource)->GetDesc(&resourceDesc); + + pDesc->Format = resourceDesc.Format; + + if (resourceDesc.SampleDesc.Count == 1) { + if (resourceDesc.ArraySize == 1) { + pDesc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + pDesc->Texture2D.MipSlice = 0; + } else { + pDesc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + pDesc->Texture2DArray.MipSlice = 0; + pDesc->Texture2DArray.FirstArraySlice = 0; + pDesc->Texture2DArray.ArraySize = resourceDesc.ArraySize; + } + } else { + if (resourceDesc.ArraySize == 1) { + pDesc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + } else { + pDesc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; + pDesc->Texture2DMSArray.FirstArraySlice = 0; + pDesc->Texture2DMSArray.ArraySize = resourceDesc.ArraySize; + } + } + } return S_OK; + + default: + Logger::err(str::format( + "D3D11: Unsupported dimension for depth stencil view: ", + resourceDim)); + return E_INVALIDARG; + } }