1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 10:54:16 +01:00

Merge branch 'image-view-fixes'

This commit is contained in:
Philip Rebohle 2018-05-24 13:53:22 +02:00
commit 2f454e73f6
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
8 changed files with 107 additions and 95 deletions

View File

@ -413,9 +413,6 @@ namespace dxvk {
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:
@ -432,9 +429,6 @@ namespace dxvk {
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:
@ -624,9 +618,6 @@ namespace dxvk {
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:

View File

@ -828,7 +828,6 @@ namespace dxvk {
case DxbcResourceDim::Buffer: m_module.enableCapability(spv::CapabilityImageBuffer); break;
case DxbcResourceDim::Texture1D: m_module.enableCapability(spv::CapabilityImage1D); break;
case DxbcResourceDim::Texture1DArr: m_module.enableCapability(spv::CapabilityImage1D); break;
case DxbcResourceDim::TextureCube: m_module.enableCapability(spv::CapabilityImageCubeArray); break;
case DxbcResourceDim::TextureCubeArr: m_module.enableCapability(spv::CapabilityImageCubeArray); break;
case DxbcResourceDim::Texture2DMs: m_module.enableCapability(spv::CapabilityImageMSArray); break;
case DxbcResourceDim::Texture2DMsArr: m_module.enableCapability(spv::CapabilityImageMSArray); break;
@ -964,7 +963,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, VK_IMAGE_VIEW_TYPE_MAX_ENUM };
const DxbcImageInfo typeInfo = { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_MAX_ENUM };
// Declare the resource type
const uint32_t resTypeId = m_module.defImageType(sampledTypeId,
@ -4590,15 +4589,6 @@ namespace dxvk {
m_module.opLoad(info.typeId, info.varId));
}
if (info.image.array && !info.image.layered) {
const uint32_t index = result.type.ccount - 1;
const uint32_t zero = m_module.constu32(0);
result.id = m_module.opCompositeInsert(
getVectorTypeId(result.type),
zero, result.id, 1, &index);
}
return result;
}
@ -4643,22 +4633,6 @@ namespace dxvk {
coordVector, DxbcRegMask::firstN(dim));
}
if (imageInfo.array && !imageInfo.layered) {
const uint32_t index = dim - 1;
const uint32_t zero = [&] {
switch (coordVector.type.ctype) {
case DxbcScalarType::Sint32: return m_module.consti32(0);
case DxbcScalarType::Uint32: return m_module.constu32(0);
case DxbcScalarType::Float32: return m_module.constf32(0.0f);
default: throw DxvkError("Dxbc: Invalid tex coord type");
}
}();
coordVector.id = m_module.opCompositeInsert(
getVectorTypeId(coordVector.type),
zero, coordVector.id, 1, &index);
}
return coordVector;
}
@ -6276,25 +6250,20 @@ namespace dxvk {
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 };
case DxbcResourceDim::Buffer: return { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_MAX_ENUM };
case DxbcResourceDim::Texture1D: return { spv::Dim1D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_1D };
case DxbcResourceDim::Texture1DArr: return { spv::Dim1D, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_1D_ARRAY };
case DxbcResourceDim::Texture2D: return { spv::Dim2D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D };
case DxbcResourceDim::Texture2DArr: return { spv::Dim2D, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY };
case DxbcResourceDim::Texture2DMs: return { spv::Dim2D, 0, 1, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D };
case DxbcResourceDim::Texture2DMsArr: return { spv::Dim2D, 1, 1, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY };
case DxbcResourceDim::Texture3D: return { spv::Dim3D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_3D };
case DxbcResourceDim::TextureCube: return { spv::DimCube, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_CUBE };
case DxbcResourceDim::TextureCubeArr: return { spv::DimCube, 1, 0, isUav ? 2u : 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;
}

View File

@ -60,7 +60,6 @@ namespace dxvk {
uint32_t array = 0;
uint32_t ms = 0;
uint32_t sampled = 0;
uint32_t layered = 0;
VkImageViewType vtype = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
};

View File

@ -5,8 +5,7 @@
namespace dxvk {
const static std::unordered_map<std::string, DxbcOptions> g_dxbcAppOptions = {{
{ "Dishonored2.exe", DxbcOptions(DxbcOption::ForceTex2DArray) },
{ "ManiaPlanet.exe", DxbcOptions(DxbcOption::ForceTex2DArray) },
}};

View File

@ -17,11 +17,6 @@ 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<DxbcOption>;

View File

@ -1822,11 +1822,11 @@ namespace dxvk {
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
if (res.imageView != nullptr && res.imageView->type() == binding.view) {
if (res.imageView != nullptr && res.imageView->handle(binding.view) != VK_NULL_HANDLE) {
updatePipelineState |= bindingState.setBound(i);
m_descInfos[i].image.sampler = VK_NULL_HANDLE;
m_descInfos[i].image.imageView = res.imageView->handle();
m_descInfos[i].image.imageView = res.imageView->handle(binding.view);
m_descInfos[i].image.imageLayout = res.imageView->imageInfo().layout;
if (depthAttachment.view != nullptr

View File

@ -87,25 +87,75 @@ namespace dxvk {
const Rc<DxvkImage>& image,
const DxvkImageViewCreateInfo& info)
: m_vkd(vkd), m_image(image), m_info(info) {
// Since applications tend to bind views
for (uint32_t i = 0; i < ViewCount; i++)
m_views[i] = VK_NULL_HANDLE;
switch (info.type) {
case VK_IMAGE_VIEW_TYPE_1D:
case VK_IMAGE_VIEW_TYPE_1D_ARRAY: {
this->createView(VK_IMAGE_VIEW_TYPE_1D, 1);
this->createView(VK_IMAGE_VIEW_TYPE_1D_ARRAY, info.numLayers);
} break;
case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
case VK_IMAGE_VIEW_TYPE_CUBE:
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: {
this->createView(VK_IMAGE_VIEW_TYPE_2D, 1);
this->createView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, info.numLayers);
if (m_image->info().flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) {
uint32_t cubeCount = info.numLayers / 6;
if (cubeCount > 0) {
this->createView(VK_IMAGE_VIEW_TYPE_CUBE, 6);
this->createView(VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, 6 * cubeCount);
}
}
} break;
case VK_IMAGE_VIEW_TYPE_3D: {
this->createView(VK_IMAGE_VIEW_TYPE_3D, 1);
if (m_image->info().flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR) {
this->createView(VK_IMAGE_VIEW_TYPE_2D, 1);
this->createView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, m_image->info().extent.depth);
}
} break;
default:
throw DxvkError(str::format("DxvkImageView: Invalid view type: ", info.type));
}
}
DxvkImageView::~DxvkImageView() {
for (uint32_t i = 0; i < ViewCount; i++)
m_vkd->vkDestroyImageView(m_vkd->device(), m_views[i], nullptr);
}
void DxvkImageView::createView(VkImageViewType type, uint32_t numLayers) {
VkImageSubresourceRange subresourceRange;
subresourceRange.aspectMask = info.aspect;
subresourceRange.baseMipLevel = info.minLevel;
subresourceRange.levelCount = info.numLevels;
subresourceRange.baseArrayLayer = info.minLayer;
subresourceRange.layerCount = info.numLayers;
subresourceRange.aspectMask = m_info.aspect;
subresourceRange.baseMipLevel = m_info.minLevel;
subresourceRange.levelCount = m_info.numLevels;
subresourceRange.baseArrayLayer = m_info.minLayer;
subresourceRange.layerCount = numLayers;
VkImageViewCreateInfo viewInfo;
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.pNext = nullptr;
viewInfo.flags = 0;
viewInfo.image = image->handle();
viewInfo.viewType = info.type;
viewInfo.format = info.format;
viewInfo.components = info.swizzle;
viewInfo.image = m_image->handle();
viewInfo.viewType = type;
viewInfo.format = m_info.format;
viewInfo.components = m_info.swizzle;
viewInfo.subresourceRange = subresourceRange;
if (m_vkd->vkCreateImageView(m_vkd->device(),
&viewInfo, nullptr, &m_view) != VK_SUCCESS) {
&viewInfo, nullptr, &m_views[type]) != VK_SUCCESS) {
throw DxvkError(str::format(
"DxvkImageView: Failed to create image view:"
"\n View type: ", viewInfo.viewType,
@ -117,23 +167,17 @@ namespace dxvk {
"\n Array layers: ", viewInfo.subresourceRange.baseArrayLayer, " - ",
viewInfo.subresourceRange.layerCount,
"\n Image properties:",
"\n Type: ", image->info().type,
"\n Format: ", image->info().format,
"\n Extent: ", "(", image->info().extent.width,
",", image->info().extent.height,
",", image->info().extent.depth, ")",
"\n Mip levels: ", image->info().mipLevels,
"\n Array layers: ", image->info().numLayers,
"\n Samples: ", image->info().sampleCount,
"\n Usage: ", std::hex, image->info().usage,
"\n Tiling: ", image->info().tiling));
"\n Type: ", m_image->info().type,
"\n Format: ", m_image->info().format,
"\n Extent: ", "(", m_image->info().extent.width,
",", m_image->info().extent.height,
",", m_image->info().extent.depth, ")",
"\n Mip levels: ", m_image->info().mipLevels,
"\n Array layers: ", m_image->info().numLayers,
"\n Samples: ", m_image->info().sampleCount,
"\n Usage: ", std::hex, m_image->info().usage,
"\n Tiling: ", m_image->info().tiling));
}
}
DxvkImageView::~DxvkImageView() {
m_vkd->vkDestroyImageView(
m_vkd->device(), m_view, nullptr);
}
}

View File

@ -232,7 +232,7 @@ namespace dxvk {
* \brief DXVK image view
*/
class DxvkImageView : public DxvkResource {
constexpr static uint32_t ViewCount = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY + 1;
public:
DxvkImageView(
@ -243,21 +243,34 @@ namespace dxvk {
~DxvkImageView();
/**
* \brief Image view handle
* \brief Image view handle for the default type
*
* Internal use only.
* The default view type is guaranteed to be
* supported by the image view, and should be
* preferred over picking a different type.
* \returns Image view handle
*/
VkImageView handle() const {
return m_view;
return handle(m_info.type);
}
/**
* \brief Image view handle for a given view type
*
* If the view does not support the requested image
* view type, \c VK_NULL_HANDLE will be returned.
* \param [in] viewType The requested view type
* \returns The image view handle
*/
VkImageView handle(VkImageViewType viewType) const {
return m_views[viewType];
}
/**
* \brief Image view type
*
* Convenience method to query the
* view type in order to check for
* resource compatibility.
* Convenience method to query the view type
* in order to check for resource compatibility.
* \returns Image view type
*/
VkImageViewType type() const {
@ -336,7 +349,9 @@ namespace dxvk {
Rc<DxvkImage> m_image;
DxvkImageViewCreateInfo m_info;
VkImageView m_view;
VkImageView m_views[ViewCount];
void createView(VkImageViewType type, uint32_t numLayers);
};