diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index b3f330d1..ea8fde98 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -397,13 +397,26 @@ namespace dxvk { const D3D11TextureInfo* dstTextureInfo = GetCommonTextureInfo(pDstResource); const D3D11TextureInfo* srcTextureInfo = GetCommonTextureInfo(pSrcResource); + const DxvkFormatInfo* dstFormatInfo = imageFormatInfo(dstTextureInfo->image->info().format); + const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcTextureInfo->image->info().format); + + const VkImageSubresource dstSubresource = + GetSubresourceFromIndex( + dstFormatInfo->aspectMask & srcFormatInfo->aspectMask, + dstTextureInfo->image->info().mipLevels, DstSubresource); + + const VkImageSubresource srcSubresource = + GetSubresourceFromIndex( + dstFormatInfo->aspectMask & srcFormatInfo->aspectMask, + srcTextureInfo->image->info().mipLevels, SrcSubresource); + VkOffset3D srcOffset = { 0, 0, 0 }; VkOffset3D dstOffset = { static_cast(DstX), static_cast(DstY), static_cast(DstZ) }; - VkExtent3D extent = srcTextureInfo->image->info().extent; + VkExtent3D extent = srcTextureInfo->image->mipLevelExtent(srcSubresource.mipLevel); if (pSrcBox != nullptr) { if (pSrcBox->left >= pSrcBox->right @@ -420,19 +433,6 @@ namespace dxvk { extent.depth = pSrcBox->back - pSrcBox->front; } - const DxvkFormatInfo* dstFormatInfo = imageFormatInfo(dstTextureInfo->image->info().format); - const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcTextureInfo->image->info().format); - - const VkImageSubresource dstSubresource = - GetSubresourceFromIndex( - dstFormatInfo->aspectMask & srcFormatInfo->aspectMask, - dstTextureInfo->image->info().mipLevels, DstSubresource); - - const VkImageSubresource srcSubresource = - GetSubresourceFromIndex( - dstFormatInfo->aspectMask & srcFormatInfo->aspectMask, - srcTextureInfo->image->info().mipLevels, SrcSubresource); - const VkImageSubresourceLayers dstLayers = { dstSubresource.aspectMask, dstSubresource.mipLevel, @@ -529,8 +529,8 @@ namespace dxvk { VkClearRect clearRect; clearRect.rect.offset.x = 0; clearRect.rect.offset.y = 0; - clearRect.rect.extent.width = dxvkView->imageInfo().extent.width; - clearRect.rect.extent.height = dxvkView->imageInfo().extent.height; + clearRect.rect.extent.width = dxvkView->mipLevelExtent(0).width; + clearRect.rect.extent.height = dxvkView->mipLevelExtent(0).height; clearRect.baseArrayLayer = 0; clearRect.layerCount = dxvkView->imageInfo().numLayers; @@ -591,8 +591,8 @@ namespace dxvk { VkClearRect clearRect; clearRect.rect.offset.x = 0; clearRect.rect.offset.y = 0; - clearRect.rect.extent.width = dxvkView->imageInfo().extent.width; - clearRect.rect.extent.height = dxvkView->imageInfo().extent.height; + clearRect.rect.extent.width = dxvkView->mipLevelExtent(0).width; + clearRect.rect.extent.height = dxvkView->mipLevelExtent(0).height; clearRect.baseArrayLayer = 0; clearRect.layerCount = dxvkView->imageInfo().numLayers; @@ -651,8 +651,12 @@ namespace dxvk { const D3D11TextureInfo* textureInfo = GetCommonTextureInfo(pDstResource); + const VkImageSubresource subresource = + GetSubresourceFromIndex(VK_IMAGE_ASPECT_COLOR_BIT, + textureInfo->image->info().mipLevels, DstSubresource); + VkOffset3D offset = { 0, 0, 0 }; - VkExtent3D extent = textureInfo->image->info().extent; + VkExtent3D extent = textureInfo->image->mipLevelExtent(subresource.mipLevel); if (pDstBox != nullptr) { if (pDstBox->left >= pDstBox->right @@ -669,15 +673,10 @@ namespace dxvk { extent.depth = pDstBox->back - pDstBox->front; } - const VkImageSubresource imageSubresource = - GetSubresourceFromIndex(VK_IMAGE_ASPECT_COLOR_BIT, - textureInfo->image->info().mipLevels, DstSubresource); - - VkImageSubresourceLayers layers; - layers.aspectMask = imageSubresource.aspectMask; - layers.mipLevel = imageSubresource.mipLevel; - layers.baseArrayLayer = imageSubresource.arrayLayer; - layers.layerCount = 1; + const VkImageSubresourceLayers layers = { + subresource.aspectMask, + subresource.mipLevel, + subresource.arrayLayer, 1 }; m_context->updateImage( textureInfo->image, layers, diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 93d4496b..e814918b 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -304,7 +304,7 @@ namespace dxvk { return E_INVALIDARG; } - if (viewInfo.numLevels == 0 || viewInfo.numLevels == 0xFFFFFFFF) + if (viewInfo.numLevels == 0xFFFFFFFF) viewInfo.numLevels = textureInfo->image->info().mipLevels - viewInfo.minLevel; if (ppSRView == nullptr) @@ -445,7 +445,7 @@ namespace dxvk { default: Logger::err(str::format( - "D3D11: View dimension not supported for SRV: ", + "D3D11: View dimension not supported for UAV: ", desc.ViewDimension)); return E_INVALIDARG; } diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 8ae3912d..7e041fd6 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -149,9 +149,6 @@ namespace dxvk { if (MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) pImageInfo->flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; - if (pImageInfo->mipLevels == 0) - pImageInfo->mipLevels = util::computeMipLevelCount(pImageInfo->extent); - if (pImageInfo->tiling == VK_IMAGE_TILING_OPTIMAL) pImageInfo->layout = OptimizeLayout(pImageInfo->usage); } @@ -164,18 +161,23 @@ namespace dxvk { m_desc (*pDesc) { const DxgiFormatMode formatMode - = GetFormatModeFromBindFlags(pDesc->BindFlags); + = GetFormatModeFromBindFlags(m_desc.BindFlags); + + if (m_desc.MipLevels == 0) { + m_desc.MipLevels = util::computeMipLevelCount( + { m_desc.Width, 1u, 1u }); + } DxvkImageCreateInfo info; info.type = VK_IMAGE_TYPE_1D; - info.format = pDevice->LookupFormat(pDesc->Format, formatMode).format; + info.format = pDevice->LookupFormat(m_desc.Format, formatMode).format; info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; info.sampleCount = VK_SAMPLE_COUNT_1_BIT; - info.extent.width = pDesc->Width; + info.extent.width = m_desc.Width; info.extent.height = 1; info.extent.depth = 1; - info.numLayers = pDesc->ArraySize; - info.mipLevels = pDesc->MipLevels; + info.numLayers = m_desc.ArraySize; + info.mipLevels = m_desc.MipLevels; info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; @@ -186,16 +188,16 @@ namespace dxvk { GetImageStagesAndAccessFlags( pDevice, - pDesc->BindFlags, - pDesc->CPUAccessFlags, - pDesc->MiscFlags, + m_desc.BindFlags, + m_desc.CPUAccessFlags, + m_desc.MiscFlags, &info); // Create the image and, if necessary, the image buffer m_texInfo.formatMode = formatMode; m_texInfo.image = pDevice->GetDXVKDevice()->createImage( info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - m_texInfo.imageBuffer = pDesc->CPUAccessFlags != 0 + m_texInfo.imageBuffer = m_desc.CPUAccessFlags != 0 ? CreateImageBuffer(pDevice->GetDXVKDevice(), info.format, info.extent) : nullptr; } @@ -253,18 +255,23 @@ namespace dxvk { m_desc (*pDesc) { const DxgiFormatMode formatMode - = GetFormatModeFromBindFlags(pDesc->BindFlags); + = GetFormatModeFromBindFlags(m_desc.BindFlags); + + if (m_desc.MipLevels == 0) { + m_desc.MipLevels = util::computeMipLevelCount( + { m_desc.Width, m_desc.Height, 1u }); + } DxvkImageCreateInfo info; info.type = VK_IMAGE_TYPE_2D; - info.format = pDevice->LookupFormat(pDesc->Format, formatMode).format; + info.format = pDevice->LookupFormat(m_desc.Format, formatMode).format; info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; info.sampleCount = VK_SAMPLE_COUNT_1_BIT; - info.extent.width = pDesc->Width; - info.extent.height = pDesc->Height; + info.extent.width = m_desc.Width; + info.extent.height = m_desc.Height; info.extent.depth = 1; - info.numLayers = pDesc->ArraySize; - info.mipLevels = pDesc->MipLevels; + info.numLayers = m_desc.ArraySize; + info.mipLevels = m_desc.MipLevels; info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; @@ -273,21 +280,21 @@ namespace dxvk { info.tiling = VK_IMAGE_TILING_OPTIMAL; info.layout = VK_IMAGE_LAYOUT_GENERAL; - if (FAILED(GetSampleCount(pDesc->SampleDesc.Count, &info.sampleCount))) - throw DxvkError(str::format("D3D11: Invalid sample count: ", pDesc->SampleDesc.Count)); + if (FAILED(GetSampleCount(m_desc.SampleDesc.Count, &info.sampleCount))) + throw DxvkError(str::format("D3D11: Invalid sample count: ", m_desc.SampleDesc.Count)); GetImageStagesAndAccessFlags( pDevice, - pDesc->BindFlags, - pDesc->CPUAccessFlags, - pDesc->MiscFlags, + m_desc.BindFlags, + m_desc.CPUAccessFlags, + m_desc.MiscFlags, &info); // Create the image and, if necessary, the image buffer m_texInfo.formatMode = formatMode; m_texInfo.image = pDevice->GetDXVKDevice()->createImage( info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - m_texInfo.imageBuffer = pDesc->CPUAccessFlags != 0 + m_texInfo.imageBuffer = m_desc.CPUAccessFlags != 0 ? CreateImageBuffer(pDevice->GetDXVKDevice(), info.format, info.extent) : nullptr; } @@ -344,19 +351,24 @@ namespace dxvk { m_desc (*pDesc) { const DxgiFormatMode formatMode - = GetFormatModeFromBindFlags(pDesc->BindFlags); + = GetFormatModeFromBindFlags(m_desc.BindFlags); + + if (m_desc.MipLevels == 0) { + m_desc.MipLevels = util::computeMipLevelCount( + { m_desc.Width, m_desc.Height, m_desc.Depth }); + } DxvkImageCreateInfo info; info.type = VK_IMAGE_TYPE_3D; - info.format = pDevice->LookupFormat(pDesc->Format, formatMode).format; + info.format = pDevice->LookupFormat(m_desc.Format, formatMode).format; info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR; info.sampleCount = VK_SAMPLE_COUNT_1_BIT; - info.extent.width = pDesc->Width; - info.extent.height = pDesc->Height; - info.extent.depth = pDesc->Depth; + info.extent.width = m_desc.Width; + info.extent.height = m_desc.Height; + info.extent.depth = m_desc.Depth; info.numLayers = 1; - info.mipLevels = pDesc->MipLevels; + info.mipLevels = m_desc.MipLevels; info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; @@ -367,16 +379,16 @@ namespace dxvk { GetImageStagesAndAccessFlags( pDevice, - pDesc->BindFlags, - pDesc->CPUAccessFlags, - pDesc->MiscFlags, + m_desc.BindFlags, + m_desc.CPUAccessFlags, + m_desc.MiscFlags, &info); // Create the image and, if necessary, the image buffer m_texInfo.formatMode = formatMode; m_texInfo.image = pDevice->GetDXVKDevice()->createImage( info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - m_texInfo.imageBuffer = pDesc->CPUAccessFlags != 0 + m_texInfo.imageBuffer = m_desc.CPUAccessFlags != 0 ? CreateImageBuffer(pDevice->GetDXVKDevice(), info.format, info.extent) : nullptr; } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index c0b7abac..0b55758d 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -304,7 +304,7 @@ namespace dxvk { m_barriers.accessImage( dstImage, dstSubresourceRange, - dstImage->info().extent == dstExtent + dstImage->mipLevelExtent(dstSubresource.mipLevel) == dstExtent ? VK_IMAGE_LAYOUT_UNDEFINED : dstImage->info().layout, dstImage->info().stages, @@ -367,7 +367,7 @@ namespace dxvk { m_barriers.accessImage( dstImage, dstSubresourceRange, - dstImage->info().extent == extent + dstImage->mipLevelExtent(dstSubresource.mipLevel) == extent ? VK_IMAGE_LAYOUT_UNDEFINED : dstImage->info().layout, dstImage->info().stages, diff --git a/src/dxvk/dxvk_framebuffer.cpp b/src/dxvk/dxvk_framebuffer.cpp index 1521edd9..73053082 100644 --- a/src/dxvk/dxvk_framebuffer.cpp +++ b/src/dxvk/dxvk_framebuffer.cpp @@ -65,7 +65,7 @@ namespace dxvk { DxvkFramebufferSize DxvkRenderTargets::renderTargetSize( const Rc& renderTarget) const { - auto extent = renderTarget->image()->info().extent; + auto extent = renderTarget->mipLevelExtent(0); auto layers = renderTarget->info().numLayers; return DxvkFramebufferSize { extent.width, extent.height, layers }; } diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index ab4b3a28..185bc13b 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -243,6 +243,18 @@ namespace dxvk { return m_image; } + /** + * \brief Mip level size + * + * Computes the mip level size relative to + * the first mip level that the view includes. + * \param [in] level Mip level + * \returns Size of that level + */ + VkExtent3D mipLevelExtent(uint32_t level) const { + return m_image->mipLevelExtent(level + m_info.minLevel); + } + /** * \brief Subresource range * \returns Subresource range