diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 248b2c33f..f82992585 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -370,7 +370,7 @@ namespace dxvk { switch (desc.ViewDimension) { case D3D11_SRV_DIMENSION_TEXTURE1D: - viewInfo.type = VK_IMAGE_VIEW_TYPE_1D_ARRAY; + viewInfo.type = VK_IMAGE_VIEW_TYPE_1D; viewInfo.minLevel = desc.Texture1D.MostDetailedMip; viewInfo.numLevels = desc.Texture1D.MipLevels; viewInfo.minLayer = 0; @@ -386,11 +386,14 @@ namespace dxvk { break; case D3D11_SRV_DIMENSION_TEXTURE2D: - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; viewInfo.minLevel = desc.Texture2D.MostDetailedMip; viewInfo.numLevels = desc.Texture2D.MipLevels; viewInfo.minLayer = 0; viewInfo.numLayers = 1; + + if (m_dxbcOptions.test(DxbcOption::ForceTex2DArray)) + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; break; case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: @@ -402,11 +405,14 @@ namespace dxvk { break; case D3D11_SRV_DIMENSION_TEXTURE2DMS: - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; viewInfo.minLevel = 0; viewInfo.numLevels = 1; viewInfo.minLayer = 0; viewInfo.numLayers = 1; + + if (m_dxbcOptions.test(DxbcOption::ForceTex2DArray)) + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; break; case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: @@ -567,7 +573,7 @@ namespace dxvk { switch (desc.ViewDimension) { case D3D11_UAV_DIMENSION_TEXTURE1D: - viewInfo.type = VK_IMAGE_VIEW_TYPE_1D_ARRAY; + viewInfo.type = VK_IMAGE_VIEW_TYPE_1D; viewInfo.minLevel = desc.Texture1D.MipSlice; viewInfo.numLevels = 1; viewInfo.minLayer = 0; @@ -583,11 +589,14 @@ namespace dxvk { break; case D3D11_UAV_DIMENSION_TEXTURE2D: - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; viewInfo.minLevel = desc.Texture2D.MipSlice; viewInfo.numLevels = 1; viewInfo.minLayer = 0; viewInfo.numLayers = 1; + + if (m_dxbcOptions.test(DxbcOption::ForceTex2DArray)) + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; break; case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index fda78d9f4..b1d44c8a1 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -807,24 +807,9 @@ namespace dxvk { } }(); - const uint32_t sampledTypeId = getScalarTypeId(sampledType); - // Declare the resource type - const DxbcImageInfo typeInfo = [resourceType, isUav] () -> DxbcImageInfo { - switch (resourceType) { - case DxbcResourceDim::Buffer: return { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, 0u }; - case DxbcResourceDim::Texture1D: return { spv::Dim1D, 1, 0, isUav ? 2u : 1u, 0u }; - case DxbcResourceDim::Texture1DArr: return { spv::Dim1D, 1, 0, isUav ? 2u : 1u, 1u }; - case DxbcResourceDim::Texture2D: return { spv::Dim2D, 1, 0, isUav ? 2u : 1u, 0u }; - case DxbcResourceDim::Texture2DArr: return { spv::Dim2D, 1, 0, isUav ? 2u : 1u, 1u }; - case DxbcResourceDim::Texture2DMs: return { spv::Dim2D, 1, 1, isUav ? 2u : 1u, 0u }; - case DxbcResourceDim::Texture2DMsArr: return { spv::Dim2D, 1, 1, isUav ? 2u : 1u, 1u }; - case DxbcResourceDim::Texture3D: return { spv::Dim3D, 0, 0, isUav ? 2u : 1u, 0u }; - case DxbcResourceDim::TextureCube: return { spv::DimCube, 1, 0, isUav ? 2u : 1u, 0u }; - case DxbcResourceDim::TextureCubeArr: return { spv::DimCube, 1, 0, isUav ? 2u : 1u, 1u }; - default: throw DxvkError(str::format("DxbcCompiler: Unsupported resource type: ", resourceType)); - } - }(); + const uint32_t sampledTypeId = getScalarTypeId(sampledType); + const DxbcImageInfo typeInfo = getResourceType(resourceType, isUav); // Declare additional capabilities if necessary switch (resourceType) { @@ -930,7 +915,7 @@ namespace dxvk { // Store descriptor info for the shader interface DxvkResourceSlot resource; resource.slot = bindingId; - resource.view = getViewType(resourceType); + resource.view = typeInfo.vtype; if (isUav) { resource.type = resourceType == DxbcResourceDim::Buffer @@ -967,7 +952,7 @@ namespace dxvk { const DxbcScalarType sampledType = DxbcScalarType::Uint32; const uint32_t sampledTypeId = getScalarTypeId(sampledType); - const DxbcImageInfo typeInfo = { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, 0u }; + const DxbcImageInfo typeInfo = { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_MAX_ENUM }; // Declare the resource type const uint32_t resTypeId = m_module.defImageType(sampledTypeId, @@ -6240,23 +6225,31 @@ namespace dxvk { } - VkImageViewType DxbcCompiler::getViewType(DxbcResourceDim dim) const { - switch (dim) { - default: - case DxbcResourceDim::Unknown: - case DxbcResourceDim::Buffer: - case DxbcResourceDim::RawBuffer: - case DxbcResourceDim::StructuredBuffer: return VK_IMAGE_VIEW_TYPE_MAX_ENUM; - case DxbcResourceDim::Texture1D: return VK_IMAGE_VIEW_TYPE_1D_ARRAY; - case DxbcResourceDim::Texture1DArr: return VK_IMAGE_VIEW_TYPE_1D_ARRAY; - case DxbcResourceDim::Texture2D: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; - case DxbcResourceDim::Texture2DMs: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; - case DxbcResourceDim::Texture2DArr: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; - case DxbcResourceDim::Texture2DMsArr: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; - case DxbcResourceDim::TextureCube: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; - case DxbcResourceDim::TextureCubeArr: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; - case DxbcResourceDim::Texture3D: return VK_IMAGE_VIEW_TYPE_3D; + DxbcImageInfo DxbcCompiler::getResourceType( + DxbcResourceDim resourceType, + bool isUav) const { + DxbcImageInfo typeInfo = [resourceType, isUav] () -> DxbcImageInfo { + switch (resourceType) { + case DxbcResourceDim::Buffer: return { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_MAX_ENUM }; + case DxbcResourceDim::Texture1D: return { spv::Dim1D, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_1D }; + case DxbcResourceDim::Texture1DArr: return { spv::Dim1D, 1, 0, isUav ? 2u : 1u, 1u, VK_IMAGE_VIEW_TYPE_1D_ARRAY }; + case DxbcResourceDim::Texture2D: return { spv::Dim2D, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_2D }; + case DxbcResourceDim::Texture2DArr: return { spv::Dim2D, 1, 0, isUav ? 2u : 1u, 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; + case DxbcResourceDim::Texture2DMs: return { spv::Dim2D, 0, 1, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_2D }; + case DxbcResourceDim::Texture2DMsArr: return { spv::Dim2D, 1, 1, isUav ? 2u : 1u, 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; + case DxbcResourceDim::Texture3D: return { spv::Dim3D, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_3D }; + case DxbcResourceDim::TextureCube: return { spv::DimCube, 1, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY }; + case DxbcResourceDim::TextureCubeArr: return { spv::DimCube, 1, 0, isUav ? 2u : 1u, 1u, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY }; + default: throw DxvkError(str::format("DxbcCompiler: Unsupported resource type: ", resourceType)); + } + }(); + + if (typeInfo.dim == spv::Dim2D && m_options.test(DxbcOption::ForceTex2DArray)) { + typeInfo.array = 1; + typeInfo.vtype = VK_IMAGE_VIEW_TYPE_2D_ARRAY; } + + return typeInfo; } diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 607d6b49c..c3f18e67c 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -1015,8 +1015,9 @@ namespace dxvk { DxbcVectorType getOutputRegType( uint32_t regIdx) const; - VkImageViewType getViewType( - DxbcResourceDim dim) const; + DxbcImageInfo getResourceType( + DxbcResourceDim resourceType, + bool isUav) const; spv::ImageFormat getScalarImageFormat( DxbcScalarType type) const; diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index 9f147f97a..e0b15e4d2 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -56,11 +56,12 @@ namespace dxvk { * \brief Image type information */ struct DxbcImageInfo { - spv::Dim dim = spv::Dim1D; - uint32_t array = 0; - uint32_t ms = 0; - uint32_t sampled = 0; - uint32_t layered = 0; + spv::Dim dim = spv::Dim1D; + uint32_t array = 0; + uint32_t ms = 0; + uint32_t sampled = 0; + uint32_t layered = 0; + VkImageViewType vtype = VK_IMAGE_VIEW_TYPE_MAX_ENUM; }; diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 6ccfd5656..76ec2eefe 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -5,7 +5,7 @@ namespace dxvk { const static std::unordered_map g_dxbcAppOptions = {{ - + { "ManiaPlanet.exe", DxbcOption::ForceTex2DArray }, }}; diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index 1a8e575c6..abe295217 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -17,6 +17,11 @@ namespace dxvk { /// Use FMin/FMax/FClamp instead of NMin/NMax/NClamp. /// Workaround for bugs in older Nvidia drivers. UseSimpleMinMaxClamp, + + /// Enforces the use of array views even when dealing + /// with non-array texture types. Some games do not + /// bind the correct texture type to the pipeline. + ForceTex2DArray, }; using DxbcOptions = Flags;