From 67d1285b084cc003f418263153dd7feb15745edf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 28 Sep 2024 19:19:23 +0200 Subject: [PATCH] [dxvk] Refactor meta blits --- src/d3d9/d3d9_device.cpp | 37 +++-- src/d3d9/d3d9_swapchain.cpp | 36 +++-- src/dxvk/dxvk_context.cpp | 279 +++++++++++++++++++----------------- src/dxvk/dxvk_context.h | 35 +++-- src/dxvk/dxvk_meta_blit.cpp | 105 -------------- src/dxvk/dxvk_meta_blit.h | 44 ------ 6 files changed, 221 insertions(+), 315 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 49a447435..4a629acc2 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -1330,20 +1330,37 @@ namespace dxvk { srcImage = resolveSrc; } + DxvkImageViewKey dstViewInfo; + dstViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + dstViewInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; + dstViewInfo.format = dstImage->info().format; + dstViewInfo.aspects = blitInfo.dstSubresource.aspectMask; + dstViewInfo.mipIndex = blitInfo.dstSubresource.mipLevel; + dstViewInfo.mipCount = 1; + dstViewInfo.layerIndex = blitInfo.dstSubresource.baseArrayLayer; + dstViewInfo.layerCount = blitInfo.dstSubresource.layerCount; + dstViewInfo.packedSwizzle = DxvkImageViewKey::packSwizzle(dstTextureInfo->GetMapping().Swizzle); + + DxvkImageViewKey srcViewInfo; + srcViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + srcViewInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + srcViewInfo.format = srcImage->info().format; + srcViewInfo.aspects = blitInfo.srcSubresource.aspectMask; + srcViewInfo.mipIndex = blitInfo.srcSubresource.mipLevel; + srcViewInfo.mipCount = 1; + srcViewInfo.layerIndex = blitInfo.srcSubresource.baseArrayLayer; + srcViewInfo.layerCount = blitInfo.srcSubresource.layerCount; + srcViewInfo.packedSwizzle = DxvkImageViewKey::packSwizzle(srcTextureInfo->GetMapping().Swizzle); + EmitCs([ - cDstImage = dstImage, - cDstMap = dstTextureInfo->GetMapping().Swizzle, - cSrcImage = srcImage, - cSrcMap = srcTextureInfo->GetMapping().Swizzle, + cDstView = dstImage->createView(dstViewInfo), + cSrcView = srcImage->createView(srcViewInfo), cBlitInfo = blitInfo, cFilter = stretch ? DecodeFilter(Filter) : VK_FILTER_NEAREST ] (DxvkContext* ctx) { - ctx->blitImage( - cDstImage, - cDstMap, - cSrcImage, - cSrcMap, - cBlitInfo, + ctx->blitImageView( + cDstView, cBlitInfo.dstOffsets, + cSrcView, cBlitInfo.srcOffsets, cFilter); }); } diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 8a97caf25..9e2c7d3aa 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -414,17 +414,37 @@ namespace dxvk { } #endif + DxvkImageViewKey dstViewInfo; + dstViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + dstViewInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; + dstViewInfo.format = blittedSrc->info().format; + dstViewInfo.aspects = blitInfo.dstSubresource.aspectMask; + dstViewInfo.mipIndex = blitInfo.dstSubresource.mipLevel; + dstViewInfo.mipCount = 1; + dstViewInfo.layerIndex = blitInfo.dstSubresource.baseArrayLayer; + dstViewInfo.layerCount = blitInfo.dstSubresource.layerCount; + dstViewInfo.packedSwizzle = DxvkImageViewKey::packSwizzle(dstTexInfo->GetMapping().Swizzle); + + DxvkImageViewKey srcViewInfo; + srcViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + srcViewInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + srcViewInfo.format = srcImage->info().format; + srcViewInfo.aspects = blitInfo.srcSubresource.aspectMask; + srcViewInfo.mipIndex = blitInfo.srcSubresource.mipLevel; + srcViewInfo.mipCount = 1; + srcViewInfo.layerIndex = blitInfo.srcSubresource.baseArrayLayer; + srcViewInfo.layerCount = blitInfo.srcSubresource.layerCount; + srcViewInfo.packedSwizzle = DxvkImageViewKey::packSwizzle(srcTexInfo->GetMapping().Swizzle); + m_parent->EmitCs([ - cDstImage = blittedSrc, - cDstMap = dstTexInfo->GetMapping().Swizzle, - cSrcImage = srcImage, - cSrcMap = srcTexInfo->GetMapping().Swizzle, + cDstView = blittedSrc->createView(dstViewInfo), + cSrcView = srcImage->createView(srcViewInfo), cBlitInfo = blitInfo ] (DxvkContext* ctx) { - ctx->blitImage( - cDstImage, cDstMap, - cSrcImage, cSrcMap, - cBlitInfo, VK_FILTER_NEAREST); + ctx->blitImageView( + cDstView, cBlitInfo.dstOffsets, + cSrcView, cBlitInfo.srcOffsets, + VK_FILTER_NEAREST); }); srcImage = std::move(blittedSrc); diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index c896f7dd1..9774e1916 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -124,37 +124,47 @@ namespace dxvk { } - void DxvkContext::blitImage( - const Rc& dstImage, - const VkComponentMapping& dstMapping, - const Rc& srcImage, - const VkComponentMapping& srcMapping, - const VkImageBlit& region, + void DxvkContext::blitImageView( + const Rc& dstView, + const VkOffset3D* dstOffsets, + const Rc& srcView, + const VkOffset3D* srcOffsets, VkFilter filter) { this->spillRenderPass(true); - this->prepareImage(dstImage, vk::makeSubresourceRange(region.dstSubresource)); - this->prepareImage(srcImage, vk::makeSubresourceRange(region.srcSubresource)); + this->prepareImage(dstView->image(), dstView->imageSubresources()); + this->prepareImage(srcView->image(), srcView->imageSubresources()); - auto mapping = util::resolveSrcComponentMapping(dstMapping, srcMapping); + auto mapping = util::resolveSrcComponentMapping( + dstView->info().unpackSwizzle(), + srcView->info().unpackSwizzle()); - bool canUseFb = (srcImage->info().usage & VK_IMAGE_USAGE_SAMPLED_BIT) - && (dstImage->info().usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) - && ((dstImage->info().flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT) - || (dstImage->info().type != VK_IMAGE_TYPE_3D)); - - bool useFb = dstImage->info().sampleCount != VK_SAMPLE_COUNT_1_BIT + bool useFb = dstView->image()->info().sampleCount != VK_SAMPLE_COUNT_1_BIT + || dstView->image()->info().format != dstView->info().format + || srcView->image()->info().format != srcView->info().format || !util::isIdentityMapping(mapping); + // Use render pass path if we already have the correct usage flags anyway + useFb |= (dstView->info().usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) + && (srcView->info().usage & (VK_IMAGE_USAGE_SAMPLED_BIT)); + if (!useFb) { - this->blitImageHw( - dstImage, srcImage, - region, filter); - } else if (canUseFb) { - this->blitImageFb( - dstImage, srcImage, - region, mapping, filter); + // Otherwise, verify that the vkCmdBlit path is supported for the given formats + auto dstFeatures = m_device->adapter()->getFormatFeatures(dstView->info().format); + auto srcFeatures = m_device->adapter()->getFormatFeatures(srcView->info().format); + + auto dstBits = dstView->image()->info().tiling == VK_IMAGE_TILING_OPTIMAL ? dstFeatures.optimal : dstFeatures.linear; + auto srcBits = srcView->image()->info().tiling == VK_IMAGE_TILING_OPTIMAL ? srcFeatures.optimal : srcFeatures.linear; + + useFb |= !(dstBits & VK_FORMAT_FEATURE_2_BLIT_DST_BIT) + || !(srcBits & VK_FORMAT_FEATURE_2_BLIT_SRC_BIT); + } + + if (useFb) { + this->blitImageFb(dstView, dstOffsets, + srcView, srcOffsets, filter); } else { - Logger::err("DxvkContext: Unsupported blit operation"); + this->blitImageHw(dstView, dstOffsets, + srcView, srcOffsets, filter); } } @@ -3045,45 +3055,55 @@ namespace dxvk { void DxvkContext::blitImageFb( - const Rc& dstImage, - const Rc& srcImage, - const VkImageBlit& region, - const VkComponentMapping& mapping, + Rc dstView, + const VkOffset3D* dstOffsets, + Rc srcView, + const VkOffset3D* srcOffsets, VkFilter filter) { this->invalidateState(); - auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource); - auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource); + bool srcIsDepthStencil = srcView->info().aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + bool dstIsDepthStencil = dstView->info().aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); - if (m_execBarriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write) - || m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write)) + dstView = ensureImageViewCompatibility(dstView, dstIsDepthStencil + ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT + : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); + srcView = ensureImageViewCompatibility(srcView, VK_IMAGE_USAGE_SAMPLED_BIT); + + if (!dstView || !srcView) { + Logger::err(str::format("DxvkContext: blitImageFb: Resources not supported")); + return; + } + + if (m_execBarriers.isImageDirty(dstView->image(), dstView->imageSubresources(), DxvkAccess::Write) + || m_execBarriers.isImageDirty(srcView->image(), srcView->imageSubresources(), DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); - bool srcIsDepthStencil = region.srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); - - VkImageLayout srcLayout = srcImage->pickLayout(srcIsDepthStencil + VkImageLayout srcLayout = srcView->image()->pickLayout(srcIsDepthStencil ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - VkImageLayout dstLayout = dstImage->pickLayout( + VkImageLayout dstLayout = dstView->image()->pickLayout( VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - if (dstImage->info().layout != dstLayout) { + if (dstView->image()->info().layout != dstLayout) { m_execAcquires.accessImage( - dstImage, dstSubresourceRange, - dstImage->info().layout, - dstImage->info().stages, 0, + dstView->image(), + dstView->imageSubresources(), + dstView->image()->info().layout, + dstView->image()->info().stages, 0, dstLayout, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); } - if (srcImage->info().layout != srcLayout) { + if (srcView->image()->info().layout != srcLayout) { m_execAcquires.accessImage( - srcImage, srcSubresourceRange, - srcImage->info().layout, - srcImage->info().stages, 0, + srcView->image(), + srcView->imageSubresources(), + srcView->image()->info().layout, + srcView->image()->info().stages, 0, srcLayout, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); @@ -3093,37 +3113,34 @@ namespace dxvk { // Sort out image offsets so that dstOffset[0] points // to the top-left corner of the target area - VkOffset3D srcOffsets[2] = { region.srcOffsets[0], region.srcOffsets[1] }; - VkOffset3D dstOffsets[2] = { region.dstOffsets[0], region.dstOffsets[1] }; + std::array srcOffsetsAdjusted = { srcOffsets[0], srcOffsets[1] }; + std::array dstOffsetsAdjusted = { dstOffsets[0], dstOffsets[1] }; - if (dstOffsets[0].x > dstOffsets[1].x) { - std::swap(dstOffsets[0].x, dstOffsets[1].x); - std::swap(srcOffsets[0].x, srcOffsets[1].x); + if (dstOffsetsAdjusted[0].x > dstOffsetsAdjusted[1].x) { + std::swap(dstOffsetsAdjusted[0].x, dstOffsetsAdjusted[1].x); + std::swap(srcOffsetsAdjusted[0].x, srcOffsetsAdjusted[1].x); } - if (dstOffsets[0].y > dstOffsets[1].y) { - std::swap(dstOffsets[0].y, dstOffsets[1].y); - std::swap(srcOffsets[0].y, srcOffsets[1].y); + if (dstOffsetsAdjusted[0].y > dstOffsetsAdjusted[1].y) { + std::swap(dstOffsetsAdjusted[0].y, dstOffsetsAdjusted[1].y); + std::swap(srcOffsetsAdjusted[0].y, srcOffsetsAdjusted[1].y); } - if (dstOffsets[0].z > dstOffsets[1].z) { - std::swap(dstOffsets[0].z, dstOffsets[1].z); - std::swap(srcOffsets[0].z, srcOffsets[1].z); + if (dstOffsetsAdjusted[0].z > dstOffsetsAdjusted[1].z) { + std::swap(dstOffsetsAdjusted[0].z, dstOffsetsAdjusted[1].z); + std::swap(srcOffsetsAdjusted[0].z, srcOffsetsAdjusted[1].z); } VkExtent3D dstExtent = { - uint32_t(dstOffsets[1].x - dstOffsets[0].x), - uint32_t(dstOffsets[1].y - dstOffsets[0].y), - uint32_t(dstOffsets[1].z - dstOffsets[0].z) }; + uint32_t(dstOffsetsAdjusted[1].x - dstOffsetsAdjusted[0].x), + uint32_t(dstOffsetsAdjusted[1].y - dstOffsetsAdjusted[0].y), + uint32_t(dstOffsetsAdjusted[1].z - dstOffsetsAdjusted[0].z) }; // Begin render pass - Rc pass = new DxvkMetaBlitRenderPass( - m_device, dstImage, srcImage, region, mapping); - - VkExtent3D imageExtent = dstImage->mipLevelExtent(region.dstSubresource.mipLevel); + VkExtent3D imageExtent = dstView->mipLevelExtent(0); VkRenderingAttachmentInfo attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; - attachmentInfo.imageView = pass->getDstView(); + attachmentInfo.imageView = dstView->handle(); attachmentInfo.imageLayout = dstLayout; attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -3132,7 +3149,7 @@ namespace dxvk { renderingInfo.renderArea = VkRect2D { VkOffset2D { 0, 0 }, VkExtent2D { imageExtent.width, imageExtent.height } }; - renderingInfo.layerCount = pass->framebufferLayerCount(); + renderingInfo.layerCount = dstView->info().layerCount; renderingInfo.colorAttachmentCount = 1; renderingInfo.pColorAttachments = &attachmentInfo; @@ -3140,22 +3157,23 @@ namespace dxvk { // Bind pipeline DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline( - pass->viewType(), dstImage->info().format, dstImage->info().sampleCount); + dstView->info().viewType, dstView->info().format, + dstView->image()->info().sampleCount); m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle); // Set up viewport VkViewport viewport; - viewport.x = float(dstOffsets[0].x); - viewport.y = float(dstOffsets[0].y); - viewport.width = float(dstExtent.width); - viewport.height = float(dstExtent.height); - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; + viewport.x = float(dstOffsetsAdjusted[0].x); + viewport.y = float(dstOffsetsAdjusted[0].y); + viewport.width = float(dstExtent.width); + viewport.height = float(dstExtent.height); + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; VkRect2D scissor; - scissor.offset = { dstOffsets[0].x, dstOffsets[0].y }; - scissor.extent = { dstExtent.width, dstExtent.height }; + scissor.offset = { dstOffsetsAdjusted[0].x, dstOffsetsAdjusted[0].y }; + scissor.extent = { dstExtent.width, dstExtent.height }; m_cmd->cmdSetViewport(1, &viewport); m_cmd->cmdSetScissor(1, &scissor); @@ -3163,7 +3181,7 @@ namespace dxvk { // Bind source image view VkDescriptorImageInfo descriptorImage; descriptorImage.sampler = m_common->metaBlit().getSampler(filter); - descriptorImage.imageView = pass->getSrcView(); + descriptorImage.imageView = srcView->handle(); descriptorImage.imageLayout = srcLayout; VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; @@ -3179,18 +3197,18 @@ namespace dxvk { pipeInfo.pipeLayout, descriptorWrite.dstSet, 0, nullptr); // Compute shader parameters for the operation - VkExtent3D srcExtent = srcImage->mipLevelExtent(region.srcSubresource.mipLevel); + VkExtent3D srcExtent = srcView->mipLevelExtent(0); DxvkMetaBlitPushConstants pushConstants = { }; - pushConstants.srcCoord0 = { - float(srcOffsets[0].x) / float(srcExtent.width), - float(srcOffsets[0].y) / float(srcExtent.height), - float(srcOffsets[0].z) / float(srcExtent.depth) }; - pushConstants.srcCoord1 = { - float(srcOffsets[1].x) / float(srcExtent.width), - float(srcOffsets[1].y) / float(srcExtent.height), - float(srcOffsets[1].z) / float(srcExtent.depth) }; - pushConstants.layerCount = pass->framebufferLayerCount(); + pushConstants.srcCoord0 = { + float(srcOffsetsAdjusted[0].x) / float(srcExtent.width), + float(srcOffsetsAdjusted[0].y) / float(srcExtent.height), + float(srcOffsetsAdjusted[0].z) / float(srcExtent.depth) }; + pushConstants.srcCoord1 = { + float(srcOffsetsAdjusted[1].x) / float(srcExtent.width), + float(srcOffsetsAdjusted[1].y) / float(srcExtent.height), + float(srcOffsetsAdjusted[1].z) / float(srcExtent.depth) }; + pushConstants.layerCount = dstView->info().layerCount; m_cmd->cmdPushConstants( pipeInfo.pipeLayout, @@ -3202,60 +3220,59 @@ namespace dxvk { m_cmd->cmdEndRendering(); // Add barriers and track image objects - m_execBarriers.accessImage(dstImage, - vk::makeSubresourceRange(region.dstSubresource), - dstLayout, + m_execBarriers.accessImage( + dstView->image(), + dstView->imageSubresources(), dstLayout, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - dstImage->info().layout, - dstImage->info().stages, - dstImage->info().access); + dstView->image()->info().layout, + dstView->image()->info().stages, + dstView->image()->info().access); - m_execBarriers.accessImage(srcImage, - vk::makeSubresourceRange(region.srcSubresource), - srcLayout, + m_execBarriers.accessImage( + srcView->image(), + srcView->imageSubresources(), srcLayout, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT, - srcImage->info().layout, - srcImage->info().stages, - srcImage->info().access); + srcView->image()->info().layout, + srcView->image()->info().stages, + srcView->image()->info().access); - m_cmd->trackResource(dstImage); - m_cmd->trackResource(srcImage); - m_cmd->trackResource(pass); + m_cmd->trackResource(dstView->image()); + m_cmd->trackResource(srcView->image()); } void DxvkContext::blitImageHw( - const Rc& dstImage, - const Rc& srcImage, - const VkImageBlit& region, + const Rc& dstView, + const VkOffset3D* dstOffsets, + const Rc& srcView, + const VkOffset3D* srcOffsets, VkFilter filter) { - auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource); - auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource); - - if (m_execBarriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write) - || m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write)) + if (m_execBarriers.isImageDirty(dstView->image(), dstView->imageSubresources(), DxvkAccess::Write) + || m_execBarriers.isImageDirty(srcView->image(), srcView->imageSubresources(), DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); // Prepare the two images for transfer ops if necessary - auto dstLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - auto srcLayout = srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + auto dstLayout = dstView->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + auto srcLayout = srcView->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - if (dstImage->info().layout != dstLayout) { + if (dstView->image()->info().layout != dstLayout) { m_execAcquires.accessImage( - dstImage, dstSubresourceRange, - dstImage->info().layout, + dstView->image(), + dstView->imageSubresources(), + dstView->image()->info().layout, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, dstLayout, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT); } - if (srcImage->info().layout != srcLayout) { + if (srcView->image()->info().layout != srcLayout) { m_execAcquires.accessImage( - srcImage, srcSubresourceRange, - srcImage->info().layout, + srcView->image(), + srcView->imageSubresources(), + srcView->image()->info().layout, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, srcLayout, VK_PIPELINE_STAGE_TRANSFER_BIT, @@ -3266,18 +3283,18 @@ namespace dxvk { // Perform the blit operation VkImageBlit2 blitRegion = { VK_STRUCTURE_TYPE_IMAGE_BLIT_2 }; - blitRegion.srcSubresource = region.srcSubresource; - blitRegion.dstSubresource = region.dstSubresource; + blitRegion.srcSubresource = vk::pickSubresourceLayers(srcView->imageSubresources(), 0); + blitRegion.dstSubresource = vk::pickSubresourceLayers(dstView->imageSubresources(), 0); for (uint32_t i = 0; i < 2; i++) { - blitRegion.srcOffsets[i] = region.srcOffsets[i]; - blitRegion.dstOffsets[i] = region.dstOffsets[i]; + blitRegion.srcOffsets[i] = srcOffsets[i]; + blitRegion.dstOffsets[i] = dstOffsets[i]; } VkBlitImageInfo2 blitInfo = { VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 }; - blitInfo.srcImage = srcImage->handle(); + blitInfo.srcImage = srcView->image()->handle(); blitInfo.srcImageLayout = srcLayout; - blitInfo.dstImage = dstImage->handle(); + blitInfo.dstImage = dstView->image()->handle(); blitInfo.dstImageLayout = dstLayout; blitInfo.regionCount = 1; blitInfo.pRegions = &blitRegion; @@ -3286,23 +3303,25 @@ namespace dxvk { m_cmd->cmdBlitImage(&blitInfo); m_execBarriers.accessImage( - dstImage, dstSubresourceRange, dstLayout, + dstView->image(), + dstView->imageSubresources(), dstLayout, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - dstImage->info().layout, - dstImage->info().stages, - dstImage->info().access); + dstView->image()->info().layout, + dstView->image()->info().stages, + dstView->image()->info().access); m_execBarriers.accessImage( - srcImage, srcSubresourceRange, srcLayout, + srcView->image(), + srcView->imageSubresources(), srcLayout, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT, - srcImage->info().layout, - srcImage->info().stages, - srcImage->info().access); + srcView->image()->info().layout, + srcView->image()->info().stages, + srcView->image()->info().access); - m_cmd->trackResource(dstImage); - m_cmd->trackResource(srcImage); + m_cmd->trackResource(dstView->image()); + m_cmd->trackResource(srcView->image()); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 8a7407e51..86f4a8514 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -383,19 +383,17 @@ namespace dxvk { /** * \brief Blits an image * - * \param [in] dstImage Destination image - * \param [in] dstMapping Destination swizzle - * \param [in] srcImage Source image - * \param [in] srcMapping Source swizzle - * \param [in] region Blit region + * \param [in] dstView Destination image view + * \param [in] srcView Source image view + * \param [in] dstOffsets Two pixel coordinates in the destination image + * \param [in] srcOffsets Two pixel coordinates in the source image * \param [in] filter Texture filter */ - void blitImage( - const Rc& dstImage, - const VkComponentMapping& dstMapping, - const Rc& srcImage, - const VkComponentMapping& srcMapping, - const VkImageBlit& region, + void blitImageView( + const Rc& dstView, + const VkOffset3D* dstOffsets, + const Rc& srcView, + const VkOffset3D* srcOffsets, VkFilter filter); /** @@ -1462,16 +1460,17 @@ namespace dxvk { std::array m_cpLookupCache = { }; void blitImageFb( - const Rc& dstImage, - const Rc& srcImage, - const VkImageBlit& region, - const VkComponentMapping& mapping, + Rc dstView, + const VkOffset3D* dstOffsets, + Rc srcView, + const VkOffset3D* srcOffsets, VkFilter filter); void blitImageHw( - const Rc& dstImage, - const Rc& srcImage, - const VkImageBlit& region, + const Rc& dstView, + const VkOffset3D* dstOffsets, + const Rc& srcView, + const VkOffset3D* srcOffsets, VkFilter filter); template diff --git a/src/dxvk/dxvk_meta_blit.cpp b/src/dxvk/dxvk_meta_blit.cpp index e99238b93..e2a3abdef 100644 --- a/src/dxvk/dxvk_meta_blit.cpp +++ b/src/dxvk/dxvk_meta_blit.cpp @@ -11,111 +11,6 @@ namespace dxvk { - DxvkMetaBlitRenderPass::DxvkMetaBlitRenderPass( - const Rc& device, - const Rc& dstImage, - const Rc& srcImage, - const VkImageBlit& region, - const VkComponentMapping& mapping) - : m_vkd (device->vkd()), - m_dstImage (dstImage), - m_srcImage (srcImage), - m_region (region), - m_dstView (createDstView()), - m_srcView (createSrcView(mapping)) { - - } - - - DxvkMetaBlitRenderPass::~DxvkMetaBlitRenderPass() { - m_vkd->vkDestroyImageView(m_vkd->device(), m_dstView, nullptr); - m_vkd->vkDestroyImageView(m_vkd->device(), m_srcView, nullptr); - } - - - VkImageViewType DxvkMetaBlitRenderPass::viewType() const { - static const std::array viewTypes = {{ - VK_IMAGE_VIEW_TYPE_1D_ARRAY, - VK_IMAGE_VIEW_TYPE_2D_ARRAY, - VK_IMAGE_VIEW_TYPE_3D, - }}; - - return viewTypes.at(uint32_t(m_srcImage->info().type)); - } - - - uint32_t DxvkMetaBlitRenderPass::framebufferLayerIndex() const { - uint32_t result = m_region.dstSubresource.baseArrayLayer; - - if (m_dstImage->info().type == VK_IMAGE_TYPE_3D) - result = std::min(m_region.dstOffsets[0].z, m_region.dstOffsets[1].z); - - return result; - } - - - uint32_t DxvkMetaBlitRenderPass::framebufferLayerCount() const { - uint32_t result = m_region.dstSubresource.layerCount; - - if (m_dstImage->info().type == VK_IMAGE_TYPE_3D) { - uint32_t minZ = std::min(m_region.dstOffsets[0].z, m_region.dstOffsets[1].z); - uint32_t maxZ = std::max(m_region.dstOffsets[0].z, m_region.dstOffsets[1].z); - result = maxZ - minZ; - } - - return result; - } - - - VkImageView DxvkMetaBlitRenderPass::createDstView() { - std::array viewTypes = {{ - VK_IMAGE_VIEW_TYPE_1D_ARRAY, - VK_IMAGE_VIEW_TYPE_2D_ARRAY, - VK_IMAGE_VIEW_TYPE_2D_ARRAY, - }}; - - VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; - usageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - - VkImageViewCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo }; - info.image = m_dstImage->handle(); - info.viewType = viewTypes.at(uint32_t(m_dstImage->info().type)); - info.format = m_dstImage->info().format; - info.components = VkComponentMapping(); - info.subresourceRange = vk::makeSubresourceRange(m_region.dstSubresource); - - if (m_dstImage->info().type) { - info.subresourceRange.baseArrayLayer = framebufferLayerIndex(); - info.subresourceRange.layerCount = framebufferLayerCount(); - } - - VkImageView result; - if (m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaBlitRenderPass: Failed to create image view"); - return result; - } - - - VkImageView DxvkMetaBlitRenderPass::createSrcView(const VkComponentMapping& mapping) { - VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; - usageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; - - VkImageViewCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo }; - info.image = m_srcImage->handle(); - info.viewType = this->viewType(); - info.format = m_srcImage->info().format; - info.components = mapping; - info.subresourceRange = vk::makeSubresourceRange(m_region.srcSubresource); - - VkImageView result; - if (m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaBlitRenderPass: Failed to create image view"); - return result; - } - - - - DxvkMetaBlitObjects::DxvkMetaBlitObjects(const DxvkDevice* device) : m_vkd (device->vkd()), m_samplerCopy (createSampler(VK_FILTER_NEAREST)), diff --git a/src/dxvk/dxvk_meta_blit.h b/src/dxvk/dxvk_meta_blit.h index 32a1eab0d..cd2382e83 100644 --- a/src/dxvk/dxvk_meta_blit.h +++ b/src/dxvk/dxvk_meta_blit.h @@ -86,51 +86,7 @@ namespace dxvk { VkPipeline pipeHandle; }; - - /** - * \brief Blit render pass - * - * Stores image view, render pass and framebuffer - * objects for a blit operation, as well as some - * metadata. - */ - class DxvkMetaBlitRenderPass : public DxvkResource { - public: - - DxvkMetaBlitRenderPass( - const Rc& device, - const Rc& dstImage, - const Rc& srcImage, - const VkImageBlit& region, - const VkComponentMapping& mapping); - - ~DxvkMetaBlitRenderPass(); - - VkImageViewType viewType() const; - - uint32_t framebufferLayerIndex() const; - uint32_t framebufferLayerCount() const; - - VkImageView getDstView() const { return m_dstView; } - VkImageView getSrcView() const { return m_srcView; } - - private: - - Rc m_vkd; - Rc m_dstImage; - Rc m_srcImage; - - VkImageBlit m_region; - VkImageView m_dstView; - VkImageView m_srcView; - - VkImageView createDstView(); - VkImageView createSrcView(const VkComponentMapping& mapping); - - }; - - /** * \brief Blitter objects *