diff --git a/src/d3d11/d3d11_initializer.cpp b/src/d3d11/d3d11_initializer.cpp index 6a6cf53d..09dda455 100644 --- a/src/d3d11/d3d11_initializer.cpp +++ b/src/d3d11/d3d11_initializer.cpp @@ -122,89 +122,94 @@ namespace dxvk { Rc image = pTexture->GetImage(); - VkFormat packedFormat = m_parent->LookupPackedFormat( - pTexture->Desc()->Format, pTexture->GetFormatMode()).Format; - - auto formatInfo = imageFormatInfo(image->info().format); + auto mapMode = pTexture->GetMapMode(); + auto desc = pTexture->Desc(); + + VkFormat packedFormat = m_parent->LookupPackedFormat(desc->Format, pTexture->GetFormatMode()).Format; + auto formatInfo = imageFormatInfo(packedFormat); if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) { // pInitialData is an array that stores an entry for // every single subresource. Since we will define all // subresources, this counts as initialization. - for (uint32_t layer = 0; layer < image->info().numLayers; layer++) { - for (uint32_t level = 0; level < image->info().mipLevels; level++) { - VkImageSubresourceLayers subresourceLayers; - subresourceLayers.aspectMask = formatInfo->aspectMask; - subresourceLayers.mipLevel = level; - subresourceLayers.baseArrayLayer = layer; - subresourceLayers.layerCount = 1; - + for (uint32_t layer = 0; layer < desc->ArraySize; layer++) { + for (uint32_t level = 0; level < desc->MipLevels; level++) { const uint32_t id = D3D11CalcSubresource( - level, layer, image->info().mipLevels); + level, layer, desc->MipLevels); VkOffset3D mipLevelOffset = { 0, 0, 0 }; - VkExtent3D mipLevelExtent = image->mipLevelExtent(level); + VkExtent3D mipLevelExtent = pTexture->MipLevelExtent(level); - m_transferCommands += 1; - m_transferMemory += pTexture->GetSubresourceLayout(formatInfo->aspectMask, id).Size; - - if (formatInfo->aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { - m_context->uploadImage( - image, subresourceLayers, - pInitialData[id].pSysMem, - pInitialData[id].SysMemPitch, - pInitialData[id].SysMemSlicePitch); - } else { - m_context->updateDepthStencilImage( - image, subresourceLayers, - VkOffset2D { mipLevelOffset.x, mipLevelOffset.y }, - VkExtent2D { mipLevelExtent.width, mipLevelExtent.height }, - pInitialData[id].pSysMem, - pInitialData[id].SysMemPitch, - pInitialData[id].SysMemSlicePitch, - packedFormat); + if (mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING) { + m_transferCommands += 1; + m_transferMemory += pTexture->GetSubresourceLayout(formatInfo->aspectMask, id).Size; + + VkImageSubresourceLayers subresourceLayers; + subresourceLayers.aspectMask = formatInfo->aspectMask; + subresourceLayers.mipLevel = level; + subresourceLayers.baseArrayLayer = layer; + subresourceLayers.layerCount = 1; + + if (formatInfo->aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + m_context->uploadImage( + image, subresourceLayers, + pInitialData[id].pSysMem, + pInitialData[id].SysMemPitch, + pInitialData[id].SysMemSlicePitch); + } else { + m_context->updateDepthStencilImage( + image, subresourceLayers, + VkOffset2D { mipLevelOffset.x, mipLevelOffset.y }, + VkExtent2D { mipLevelExtent.width, mipLevelExtent.height }, + pInitialData[id].pSysMem, + pInitialData[id].SysMemPitch, + pInitialData[id].SysMemSlicePitch, + packedFormat); + } } - if (pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) { + if (mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) { util::packImageData(pTexture->GetMappedBuffer(id)->mapPtr(0), pInitialData[id].pSysMem, pInitialData[id].SysMemPitch, pInitialData[id].SysMemSlicePitch, - image->info().type, mipLevelExtent, 1, formatInfo, formatInfo->aspectMask); + pTexture->GetVkImageType(), mipLevelExtent, 1, formatInfo, formatInfo->aspectMask); } } } } else { - m_transferCommands += 1; - - // While the Microsoft docs state that resource contents are - // undefined if no initial data is provided, some applications - // expect a resource to be pre-cleared. We can only do that - // for non-compressed images, but that should be fine. - VkImageSubresourceRange subresources; - subresources.aspectMask = formatInfo->aspectMask; - subresources.baseMipLevel = 0; - subresources.levelCount = image->info().mipLevels; - subresources.baseArrayLayer = 0; - subresources.layerCount = image->info().numLayers; + if (mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING) { + m_transferCommands += 1; + + // While the Microsoft docs state that resource contents are + // undefined if no initial data is provided, some applications + // expect a resource to be pre-cleared. We can only do that + // for non-compressed images, but that should be fine. + VkImageSubresourceRange subresources; + subresources.aspectMask = formatInfo->aspectMask; + subresources.baseMipLevel = 0; + subresources.levelCount = desc->MipLevels; + subresources.baseArrayLayer = 0; + subresources.layerCount = desc->ArraySize; - if (formatInfo->flags.any(DxvkFormatFlag::BlockCompressed, DxvkFormatFlag::MultiPlane)) { - m_context->clearCompressedColorImage(image, subresources); - } else { - if (subresources.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) { - VkClearColorValue value = { }; - - m_context->clearColorImage( - image, value, subresources); + if (formatInfo->flags.any(DxvkFormatFlag::BlockCompressed, DxvkFormatFlag::MultiPlane)) { + m_context->clearCompressedColorImage(image, subresources); } else { - VkClearDepthStencilValue value; - value.depth = 0.0f; - value.stencil = 0; - - m_context->clearDepthStencilImage( - image, value, subresources); + if (subresources.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) { + VkClearColorValue value = { }; + + m_context->clearColorImage( + image, value, subresources); + } else { + VkClearDepthStencilValue value; + value.depth = 0.0f; + value.stencil = 0; + + m_context->clearDepthStencilImage( + image, value, subresources); + } } } - if (pTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) { + if (mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) { for (uint32_t i = 0; i < pTexture->CountSubresources(); i++) { auto buffer = pTexture->GetMappedBuffer(i); std::memset(buffer->mapPtr(0), 0, buffer->info().size); diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index bef3640c..c61a0f69 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -18,7 +18,7 @@ namespace dxvk { m_packedFormat = formatPacked.Format; DxvkImageCreateInfo imageInfo; - imageInfo.type = GetImageTypeFromResourceDim(Dimension); + imageInfo.type = GetVkImageType(); imageInfo.format = formatInfo.Format; imageInfo.flags = 0; imageInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT; diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index 395c8c40..beba7a6a 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -91,6 +91,17 @@ namespace dxvk { return &m_desc; } + /** + * \brief Retrieves Vulkan image type + * + * Returns the image type based on the D3D11 resource + * dimension. Also works if there is no actual image. + * \returns Vulkan image type + */ + VkImageType GetVkImageType() const { + return GetImageTypeFromResourceDim(m_dimension); + } + /** * \brief Computes extent of a given mip level *