diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index a717536d..293d66dd 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -512,12 +512,12 @@ namespace dxvk { // we'll have to use a fallback using a texel buffer view and buffer copies. bool isViewCompatible = uavFormat == rawFormat; - if (!isViewCompatible && (imageView->imageInfo().flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) { - uint32_t formatCount = imageView->imageInfo().viewFormatCount; + if (!isViewCompatible && (imageView->image()->info().flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) { + uint32_t formatCount = imageView->image()->info().viewFormatCount; isViewCompatible = formatCount == 0; for (uint32_t i = 0; i < formatCount && !isViewCompatible; i++) - isViewCompatible = imageView->imageInfo().viewFormats[i] == rawFormat; + isViewCompatible = imageView->image()->info().viewFormats[i] == rawFormat; } if (isViewCompatible || isZeroClearValue) { @@ -5428,8 +5428,8 @@ namespace dxvk { || curView->info().numLayers != refView->info().numLayers) return false; - if (curView->imageInfo().sampleCount - != refView->imageInfo().sampleCount) + if (curView->image()->info().sampleCount + != refView->image()->info().sampleCount) return false; // Color targets must all be the same size diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 4b873f70..8fe0ee65 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -558,9 +558,7 @@ namespace dxvk { Rc image = m_device->importImage(imageInfo, imageHandle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - - m_imageViews[i] = new DxvkImageView( - m_device->vkd(), image, viewInfo); + m_imageViews[i] = image->createView(viewInfo); } } diff --git a/src/d3d11/d3d11_view_dsv.h b/src/d3d11/d3d11_view_dsv.h index de1958fc..a8b2a2d5 100644 --- a/src/d3d11/d3d11_view_dsv.h +++ b/src/d3d11/d3d11_view_dsv.h @@ -50,7 +50,7 @@ namespace dxvk { } VkImageLayout GetRenderLayout() const { - if (m_view->imageInfo().tiling == VK_IMAGE_TILING_OPTIMAL) { + if (m_view->image()->info().tiling == VK_IMAGE_TILING_OPTIMAL) { switch (m_desc.Flags & (D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL)) { default: // case 0 return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; @@ -67,7 +67,7 @@ namespace dxvk { } UINT GetSampleCount() const { - return UINT(m_view->imageInfo().sampleCount); + return UINT(m_view->image()->info().sampleCount); } VkImageAspectFlags GetWritableAspectMask() const { diff --git a/src/d3d11/d3d11_view_rtv.h b/src/d3d11/d3d11_view_rtv.h index 0be9ff7a..cd98bbb7 100644 --- a/src/d3d11/d3d11_view_rtv.h +++ b/src/d3d11/d3d11_view_rtv.h @@ -52,13 +52,13 @@ namespace dxvk { } VkImageLayout GetRenderLayout() const { - return m_view->imageInfo().tiling == VK_IMAGE_TILING_OPTIMAL + return m_view->image()->info().tiling == VK_IMAGE_TILING_OPTIMAL ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL; } UINT GetSampleCount() const { - return UINT(m_view->imageInfo().sampleCount); + return UINT(m_view->image()->info().sampleCount); } D3D10RenderTargetView* GetD3D10Iface() { diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 259a89ca..33f6a93f 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -985,9 +985,7 @@ namespace dxvk { Rc image = m_device->importImage(imageInfo, imageHandle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - - m_wctx->imageViews[i] = new DxvkImageView( - m_device->vkd(), image, viewInfo); + m_wctx->imageViews[i] = image->createView(viewInfo); } } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index d25dd2ae..fc518606 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -730,7 +730,7 @@ namespace dxvk { return; // Create one depth view and one stencil view - DxvkImageViewCreateInfo dViewInfo; + DxvkImageViewCreateInfo dViewInfo = { }; dViewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; dViewInfo.format = srcImage->info().format; dViewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; @@ -743,8 +743,8 @@ namespace dxvk { DxvkImageViewCreateInfo sViewInfo = dViewInfo; sViewInfo.aspect = VK_IMAGE_ASPECT_STENCIL_BIT; - Rc dView = m_device->createImageView(srcImage, dViewInfo); - Rc sView = m_device->createImageView(srcImage, sViewInfo); + Rc dView = srcImage->createView(dViewInfo); + Rc sView = srcImage->createView(sViewInfo); // Create a descriptor set for the pack operation VkImageLayout layout = srcImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); @@ -817,9 +817,6 @@ namespace dxvk { dstBuffer->info().stages, dstBuffer->info().access); - m_cmd->trackResource(dView); - m_cmd->trackResource(sView); - m_cmd->trackResource(dstBuffer); m_cmd->trackResource(srcImage); } @@ -1662,22 +1659,22 @@ namespace dxvk { VkImageLayout srcLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); // If necessary, transition first mip level to the read-only layout - if (imageView->imageInfo().layout != srcLayout) { + if (imageView->image()->info().layout != srcLayout) { m_execAcquires.accessImage(imageView->image(), mipGenerator->getTopSubresource(), - imageView->imageInfo().layout, - imageView->imageInfo().stages, 0, + imageView->image()->info().layout, + imageView->image()->info().stages, 0, srcLayout, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); } // If necessary, initialize all levels that are written to - if (imageView->imageInfo().layout != dstLayout) { + if (imageView->image()->info().layout != dstLayout) { m_execAcquires.accessImage(imageView->image(), mipGenerator->getAllTargetSubresources(), VK_IMAGE_LAYOUT_UNDEFINED, - imageView->imageInfo().stages, 0, + imageView->image()->info().stages, 0, dstLayout, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); @@ -1785,9 +1782,9 @@ namespace dxvk { VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, - imageView->imageInfo().layout, - imageView->imageInfo().stages, - imageView->imageInfo().access); + imageView->image()->info().layout, + imageView->image()->info().stages, + imageView->image()->info().access); } else { m_execBarriers.accessImage(imageView->image(), mipGenerator->getAllSourceSubresources(), @@ -1796,18 +1793,18 @@ namespace dxvk { VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, - imageView->imageInfo().layout, - imageView->imageInfo().stages, - imageView->imageInfo().access); + imageView->image()->info().layout, + imageView->image()->info().stages, + imageView->image()->info().access); m_execBarriers.accessImage(imageView->image(), mipGenerator->getBottomSubresource(), dstLayout, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - imageView->imageInfo().layout, - imageView->imageInfo().stages, - imageView->imageInfo().access); + imageView->image()->info().layout, + imageView->image()->info().stages, + imageView->image()->info().access); } m_cmd->trackResource(mipGenerator); @@ -1971,14 +1968,14 @@ namespace dxvk { VkClearValue clearValue) { DxvkColorAttachmentOps colorOp; colorOp.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - colorOp.loadLayout = imageView->imageInfo().layout; - colorOp.storeLayout = imageView->imageInfo().layout; + colorOp.loadLayout = imageView->image()->info().layout; + colorOp.storeLayout = imageView->image()->info().layout; DxvkDepthAttachmentOps depthOp; depthOp.loadOpD = VK_ATTACHMENT_LOAD_OP_LOAD; depthOp.loadOpS = VK_ATTACHMENT_LOAD_OP_LOAD; - depthOp.loadLayout = imageView->imageInfo().layout; - depthOp.storeLayout = imageView->imageInfo().layout; + depthOp.loadLayout = imageView->image()->info().layout; + depthOp.storeLayout = imageView->image()->info().layout; if (clearAspects & VK_IMAGE_ASPECT_COLOR_BIT) colorOp.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; @@ -2015,7 +2012,7 @@ namespace dxvk { attachmentIndex = -1; } - bool is3D = imageView->imageInfo().type == VK_IMAGE_TYPE_3D; + bool is3D = imageView->image()->info().type == VK_IMAGE_TYPE_3D; if ((clearAspects | discardAspects) == imageView->info().aspect && !is3D) { colorOp.loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; @@ -2023,7 +2020,7 @@ namespace dxvk { } if (attachmentIndex < 0) { - bool hasViewFormatMismatch = imageView->info().format != imageView->imageInfo().format; + bool hasViewFormatMismatch = imageView->info().format != imageView->image()->info().format; if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); @@ -2120,10 +2117,9 @@ namespace dxvk { imageView->imageSubresources(), imageLayout, clearStages, clearAccess, storeLayout, - imageView->imageInfo().stages, - imageView->imageInfo().access); + imageView->image()->info().stages, + imageView->image()->info().access); - m_cmd->trackResource(imageView); m_cmd->trackResource(imageView->image()); } else { // Perform the operation when starting the next render pass @@ -2221,7 +2217,7 @@ namespace dxvk { void DxvkContext::flushSharedImages() { for (auto i = m_deferredClears.begin(); i != m_deferredClears.end(); ) { - if (i->imageView->imageInfo().shared) { + if (i->imageView->image()->info().shared) { this->performClear(i->imageView, -1, i->discardAspects, i->clearAspects, i->clearValue); i = m_deferredClears.erase(i); } else { @@ -3320,11 +3316,11 @@ namespace dxvk { renderingInfo.pStencilAttachment = &attachmentInfo; } - if (clearLayout != imageView->imageInfo().layout) { + if (clearLayout != imageView->image()->info().layout) { m_execAcquires.accessImage( imageView->image(), imageView->imageSubresources(), - imageView->imageInfo().layout, clearStages, 0, + imageView->image()->info().layout, clearStages, 0, clearLayout, clearStages, clearAccess); m_execAcquires.recordCommands(m_cmd); } @@ -3365,11 +3361,10 @@ namespace dxvk { imageView->image(), imageView->imageSubresources(), clearLayout, clearStages, clearAccess, - imageView->imageInfo().layout, - imageView->imageInfo().stages, - imageView->imageInfo().access); + imageView->image()->info().layout, + imageView->image()->info().stages, + imageView->image()->info().access); - m_cmd->trackResource(imageView); m_cmd->trackResource(imageView->image()); } } @@ -3399,7 +3394,7 @@ namespace dxvk { VkDescriptorImageInfo viewInfo; viewInfo.sampler = VK_NULL_HANDLE; viewInfo.imageView = imageView->handle(); - viewInfo.imageLayout = imageView->imageInfo().layout; + viewInfo.imageLayout = imageView->image()->info().layout; VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; descriptorWrite.dstSet = descriptorSet; @@ -3443,14 +3438,13 @@ namespace dxvk { m_execBarriers.accessImage( imageView->image(), imageView->imageSubresources(), - imageView->imageInfo().layout, + imageView->image()->info().layout, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT, - imageView->imageInfo().layout, - imageView->imageInfo().stages, - imageView->imageInfo().access); + imageView->image()->info().layout, + imageView->image()->info().stages, + imageView->image()->info().access); - m_cmd->trackResource(imageView); m_cmd->trackResource(imageView->image()); } @@ -4687,8 +4681,8 @@ namespace dxvk { VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, ops.depthOps.storeLayout, - depthAttachment.view->imageInfo().stages, - depthAttachment.view->imageInfo().access); + depthAttachment.view->image()->info().stages, + depthAttachment.view->image()->info().access); } else { VkAccessFlags srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; @@ -4699,8 +4693,8 @@ namespace dxvk { VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, srcAccess, - depthAttachment.view->imageInfo().stages, - depthAttachment.view->imageInfo().access); + depthAttachment.view->image()->info().stages, + depthAttachment.view->image()->info().access); } } @@ -4717,15 +4711,15 @@ namespace dxvk { VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, ops.colorOps[i].storeLayout, - colorAttachment.view->imageInfo().stages, - colorAttachment.view->imageInfo().access); + colorAttachment.view->image()->info().stages, + colorAttachment.view->image()->info().access); } else { m_execBarriers.accessMemory( VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - colorAttachment.view->imageInfo().stages, - colorAttachment.view->imageInfo().access); + colorAttachment.view->image()->info().stages, + colorAttachment.view->image()->info().access); } } } @@ -4764,7 +4758,7 @@ namespace dxvk { // We can't use LOAD_OP_CLEAR if the view format does not match the // underlying image format, so just discard here and use clear later. - if (colorTarget.view->info().format != colorTarget.view->imageInfo().format) { + if (colorTarget.view->info().format != colorTarget.view->image()->info().format) { colorInfos[i].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; auto& clear = lateClears[lateClearCount++]; @@ -4830,10 +4824,8 @@ namespace dxvk { m_cmd->cmdClearAttachments(lateClearCount, lateClears.data(), 1, &clearRect); } - for (uint32_t i = 0; i < framebufferInfo.numAttachments(); i++) { - m_cmd->trackResource (framebufferInfo.getAttachment(i).view); + for (uint32_t i = 0; i < framebufferInfo.numAttachments(); i++) m_cmd->trackResource(framebufferInfo.getAttachment(i).view->image()); - } m_cmd->addStatCtr(DxvkStatCounter::CmdRenderPassCount, 1); } @@ -5258,12 +5250,10 @@ namespace dxvk { if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { descriptorInfo.image.sampler = VK_NULL_HANDLE; descriptorInfo.image.imageView = res.imageView->handle(binding.viewType); - descriptorInfo.image.imageLayout = res.imageView->imageInfo().layout; + descriptorInfo.image.imageLayout = res.imageView->image()->info().layout; - if (m_rcTracked.set(binding.resourceBinding)) { - m_cmd->trackResource(res.imageView); + if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.imageView->image()); - } } else { descriptorInfo.image.sampler = VK_NULL_HANDLE; descriptorInfo.image.imageView = VK_NULL_HANDLE; @@ -5277,12 +5267,10 @@ namespace dxvk { if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { descriptorInfo.image.sampler = VK_NULL_HANDLE; descriptorInfo.image.imageView = res.imageView->handle(binding.viewType); - descriptorInfo.image.imageLayout = res.imageView->imageInfo().layout; + descriptorInfo.image.imageLayout = res.imageView->image()->info().layout; - if (m_rcTracked.set(binding.resourceBinding)) { - m_cmd->trackResource(res.imageView); + if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.imageView->image()); - } } else { descriptorInfo.image.sampler = VK_NULL_HANDLE; descriptorInfo.image.imageView = VK_NULL_HANDLE; @@ -5297,11 +5285,10 @@ namespace dxvk { && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { descriptorInfo.image.sampler = res.sampler->handle(); descriptorInfo.image.imageView = res.imageView->handle(binding.viewType); - descriptorInfo.image.imageLayout = res.imageView->imageInfo().layout; + descriptorInfo.image.imageLayout = res.imageView->image()->info().layout; if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.sampler); - m_cmd->trackResource(res.imageView); m_cmd->trackResource(res.imageView->image()); } } else { @@ -5472,17 +5459,17 @@ namespace dxvk { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { const DxvkAttachment& color = m_state.om.framebufferInfo.getColorTarget(i); - if (color.view != nullptr && (!sharedOnly || color.view->imageInfo().shared)) { + if (color.view != nullptr && (!sharedOnly || color.view->image()->info().shared)) { this->transitionColorAttachment(color, m_rtLayouts.color[i]); - m_rtLayouts.color[i] = color.view->imageInfo().layout; + m_rtLayouts.color[i] = color.view->image()->info().layout; } } const DxvkAttachment& depth = m_state.om.framebufferInfo.getDepthTarget(); - if (depth.view != nullptr && (!sharedOnly || depth.view->imageInfo().shared)) { + if (depth.view != nullptr && (!sharedOnly || depth.view->image()->info().shared)) { this->transitionDepthAttachment(depth, m_rtLayouts.depth); - m_rtLayouts.depth = depth.view->imageInfo().layout; + m_rtLayouts.depth = depth.view->image()->info().layout; } } @@ -5490,15 +5477,15 @@ namespace dxvk { void DxvkContext::transitionColorAttachment( const DxvkAttachment& attachment, VkImageLayout oldLayout) { - if (oldLayout != attachment.view->imageInfo().layout) { + if (oldLayout != attachment.view->image()->info().layout) { m_execBarriers.accessImage( attachment.view->image(), attachment.view->imageSubresources(), oldLayout, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - attachment.view->imageInfo().layout, - attachment.view->imageInfo().stages, - attachment.view->imageInfo().access); + attachment.view->image()->info().layout, + attachment.view->image()->info().stages, + attachment.view->image()->info().access); m_cmd->trackResource(attachment.view->image()); } @@ -5508,7 +5495,7 @@ namespace dxvk { void DxvkContext::transitionDepthAttachment( const DxvkAttachment& attachment, VkImageLayout oldLayout) { - if (oldLayout != attachment.view->imageInfo().layout) { + if (oldLayout != attachment.view->image()->info().layout) { m_execBarriers.accessImage( attachment.view->image(), attachment.view->imageSubresources(), oldLayout, @@ -5516,9 +5503,9 @@ namespace dxvk { VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, oldLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : 0, - attachment.view->imageInfo().layout, - attachment.view->imageInfo().stages, - attachment.view->imageInfo().access); + attachment.view->image()->info().layout, + attachment.view->image()->info().stages, + attachment.view->image()->info().access); m_cmd->trackResource(attachment.view->image()); } @@ -5532,11 +5519,11 @@ namespace dxvk { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if (newFb.getColorTarget(i).view != nullptr) - layouts.color[i] = newFb.getColorTarget(i).view->imageInfo().layout; + layouts.color[i] = newFb.getColorTarget(i).view->image()->info().layout; } if (newFb.getDepthTarget().view != nullptr) - layouts.depth = newFb.getDepthTarget().view->imageInfo().layout; + layouts.depth = newFb.getDepthTarget().view->image()->info().layout; // Check whether any of the previous attachments have been moved // around or been rebound with a different view. This may help @@ -6184,7 +6171,7 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: if ((slot.imageView != nullptr) - && (slot.imageView->imageInfo().access & storageImageAccess)) { + && (slot.imageView->image()->info().access & storageImageAccess)) { requiresBarrier = this->checkImageViewBarrier(slot.imageView, util::pipelineStages(binding.stage), binding.access); } @@ -6267,11 +6254,11 @@ namespace dxvk { m_execBarriers.accessImage( imageView->image(), imageView->imageSubresources(), - imageView->imageInfo().layout, + imageView->image()->info().layout, stages, access, - imageView->imageInfo().layout, - imageView->imageInfo().stages, - imageView->imageInfo().access); + imageView->image()->info().layout, + imageView->image()->info().stages, + imageView->image()->info().access); return false; } else { DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(access); diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 77017b02..0c6ec0fd 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -174,7 +174,7 @@ namespace dxvk { Rc DxvkDevice::createImageView( const Rc& image, const DxvkImageViewCreateInfo& createInfo) { - return new DxvkImageView(m_vkd, image, createInfo); + return image->createView(createInfo); } diff --git a/src/dxvk/dxvk_framebuffer.cpp b/src/dxvk/dxvk_framebuffer.cpp index e911c0a2..5683c484 100644 --- a/src/dxvk/dxvk_framebuffer.cpp +++ b/src/dxvk/dxvk_framebuffer.cpp @@ -16,13 +16,13 @@ namespace dxvk { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if (m_renderTargets.color[i].view != nullptr) { m_attachments[m_attachmentCount++] = i; - m_sampleCount = m_renderTargets.color[i].view->imageInfo().sampleCount; + m_sampleCount = m_renderTargets.color[i].view->image()->info().sampleCount; } } if (m_renderTargets.depth.view != nullptr) { m_attachments[m_attachmentCount++] = -1; - m_sampleCount = m_renderTargets.depth.view->imageInfo().sampleCount; + m_sampleCount = m_renderTargets.depth.view->image()->info().sampleCount; } } diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index 798c798c..770cdfdb 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -77,6 +77,35 @@ namespace dxvk { } + Rc DxvkImage::createView( + const DxvkImageViewCreateInfo& info) { + DxvkImageViewKey key = { }; + key.viewType = info.type; + key.format = info.format; + key.usage = info.usage; + key.aspects = info.aspect; + key.mipIndex = info.minLevel; + key.mipCount = info.numLevels; + key.layerIndex = info.minLayer; + key.layerCount = info.numLayers; + + if (info.usage == VK_IMAGE_USAGE_SAMPLED_BIT) { + key.packedSwizzle = + (uint16_t(info.swizzle.r) << 0) | + (uint16_t(info.swizzle.g) << 4) | + (uint16_t(info.swizzle.b) << 8) | + (uint16_t(info.swizzle.a) << 12); + } + + std::unique_lock lock(m_viewMutex); + + auto entry = m_views.emplace(std::piecewise_construct, + std::make_tuple(key), std::make_tuple(this, key)); + + return &entry.first->second; + } + + Rc DxvkImage::createResource() { const DxvkFormatInfo* formatInfo = lookupFormatInfo(m_info.format); @@ -195,108 +224,84 @@ namespace dxvk { DxvkImageView::DxvkImageView( - const Rc& vkd, - const Rc& image, - const DxvkImageViewCreateInfo& info) - : m_vkd(vkd), m_image(image), m_info(info) { - for (uint32_t i = 0; i < ViewCount; i++) - m_views[i] = VK_NULL_HANDLE; - - switch (m_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, m_info.numLayers); - } break; - - case VK_IMAGE_VIEW_TYPE_2D: - case VK_IMAGE_VIEW_TYPE_2D_ARRAY: - this->createView(VK_IMAGE_VIEW_TYPE_2D, 1); - [[fallthrough]]; + DxvkImage* image, + const DxvkImageViewKey& key) + : m_image(image), m_key(key) { - case VK_IMAGE_VIEW_TYPE_CUBE: - case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: { - this->createView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, m_info.numLayers); - - if (m_image->info().flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) { - uint32_t cubeCount = m_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 && m_info.numLevels == 1) { - this->createView(VK_IMAGE_VIEW_TYPE_2D, 1); - this->createView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, m_image->mipLevelExtent(m_info.minLevel).depth); - } - } break; - - default: - throw DxvkError(str::format("DxvkImageView: Invalid view type: ", m_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 = m_info.aspect; - subresourceRange.baseMipLevel = m_info.minLevel; - subresourceRange.levelCount = m_info.numLevels; - subresourceRange.baseArrayLayer = m_info.minLayer; - subresourceRange.layerCount = numLayers; - VkImageViewUsageCreateInfo viewUsage = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; - viewUsage.usage = m_info.usage; - - VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &viewUsage }; - viewInfo.image = m_image->handle(); - viewInfo.viewType = type; - viewInfo.format = m_info.format; - viewInfo.components = m_info.swizzle; - viewInfo.subresourceRange = subresourceRange; + VkImageView DxvkImageView::createView(VkImageViewType type) const { + DxvkImageViewKey key = m_key; + key.viewType = type; - if (m_info.usage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { - viewInfo.components = { - VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }; + // Only use one layer for non-arrayed view types + if (type == VK_IMAGE_VIEW_TYPE_1D || type == VK_IMAGE_VIEW_TYPE_2D) + key.layerCount = 1u; + + switch (m_image->info().type) { + case VK_IMAGE_TYPE_1D: { + // Trivial, just validate that view types are compatible + if (type != VK_IMAGE_VIEW_TYPE_1D && type != VK_IMAGE_VIEW_TYPE_1D_ARRAY) + return VK_NULL_HANDLE; + } break; + + case VK_IMAGE_TYPE_2D: { + if (type == VK_IMAGE_VIEW_TYPE_CUBE || type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) { + // Ensure that the image is compatible with cube maps + if (key.layerCount < 6 || !(m_image->info().flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) + return VK_NULL_HANDLE; + + // Adjust layer count to make sure it's a multiple of 6 + key.layerCount = type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY + ? key.layerCount - key.layerCount % 6u : 6u; + } else if (type != VK_IMAGE_VIEW_TYPE_2D && type != VK_IMAGE_VIEW_TYPE_2D_ARRAY) { + return VK_NULL_HANDLE; + } + } break; + + case VK_IMAGE_TYPE_3D: { + if (type == VK_IMAGE_VIEW_TYPE_2D || type == VK_IMAGE_VIEW_TYPE_2D_ARRAY) { + // Ensure that the image is actually compatible with 2D views + if (!(m_image->info().flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT)) + return VK_NULL_HANDLE; + + // In case the view's native type is 3D, we can only create 2D compat + // views if there is only one mip and with the full set of array layers. + if (m_key.viewType == VK_IMAGE_VIEW_TYPE_3D) { + if (m_key.mipCount != 1u) + return VK_NULL_HANDLE; + + key.layerIndex = 0u; + key.layerCount = type == VK_IMAGE_VIEW_TYPE_2D_ARRAY + ? m_image->mipLevelExtent(key.mipIndex).depth : 1u; + } + } else if (type != VK_IMAGE_VIEW_TYPE_3D) { + return VK_NULL_HANDLE; + } + } break; + + default: + return VK_NULL_HANDLE; } - - if (m_vkd->vkCreateImageView(m_vkd->device(), - &viewInfo, nullptr, &m_views[type]) != VK_SUCCESS) { - throw DxvkError(str::format( - "DxvkImageView: Failed to create image view:" - "\n View type: ", viewInfo.viewType, - "\n View format: ", viewInfo.format, - "\n Subresources: ", - "\n Aspect mask: ", std::hex, viewInfo.subresourceRange.aspectMask, - "\n Mip levels: ", viewInfo.subresourceRange.baseMipLevel, " - ", - viewInfo.subresourceRange.levelCount, - "\n Array layers: ", viewInfo.subresourceRange.baseArrayLayer, " - ", - viewInfo.subresourceRange.layerCount, - "\n Image properties:", - "\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)); + + return m_image->m_storage->createImageView(key); + } + + + void DxvkImageView::updateViews() { + // Update all views that are not currently null + for (uint32_t i = 0; i < m_views.size(); i++) { + if (m_views[i]) + m_views[i] = createView(VkImageViewType(i)); } + + m_version = m_image->m_version; } } diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index 1f9f49a7..5f90d20f 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -9,8 +9,6 @@ namespace dxvk { - class DxvkImageView; - /** * \brief Image create info * @@ -106,6 +104,203 @@ namespace dxvk { }; + /** + * \brief Virtual image view + * + * Stores views for a number of different view types + * that the defined view is compatible with. + */ + class DxvkImageView { + constexpr static uint32_t ViewCount = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY + 1; + public: + + DxvkImageView( + DxvkImage* image, + const DxvkImageViewKey& key); + + ~DxvkImageView(); + + void incRef(); + void decRef(); + + /** + * \brief Image view handle for the default type + * + * 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() { + return handle(m_key.viewType); + } + + /** + * \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); + + /** + * \brief Image view type + * + * Convenience method to query the view type + * in order to check for resource compatibility. + * \returns Image view type + */ + VkImageViewType type() const { + return m_key.viewType; + } + + /** + * \brief Image view properties + * \returns Image view properties + */ + DxvkImageViewCreateInfo info() const { + DxvkImageViewCreateInfo info = { }; + info.type = m_key.viewType; + info.format = m_key.format; + info.usage = m_key.usage; + info.aspect = m_key.aspects; + info.minLevel = m_key.mipIndex; + info.numLevels = m_key.mipCount; + info.minLayer = m_key.layerIndex; + info.numLayers = m_key.layerCount; + info.swizzle.r = VkComponentSwizzle((m_key.packedSwizzle >> 0) & 0xf); + info.swizzle.g = VkComponentSwizzle((m_key.packedSwizzle >> 4) & 0xf); + info.swizzle.b = VkComponentSwizzle((m_key.packedSwizzle >> 8) & 0xf); + info.swizzle.a = VkComponentSwizzle((m_key.packedSwizzle >> 12) & 0xf); + return info; + } + + /** + * \brief Image object + * \returns Image object + */ + DxvkImage* image() const { + return m_image; + } + + /** + * \brief View format info + * \returns View format info + */ + const DxvkFormatInfo* formatInfo() const { + return lookupFormatInfo(m_key.format); + } + + /** + * \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; + + /** + * \brief View subresource range + * + * Returns the subresource range from the image + * description. For 2D views of 3D images, this + * will return the viewed 3D slices. + * \returns View subresource range + */ + VkImageSubresourceRange subresources() const { + VkImageSubresourceRange result; + result.aspectMask = m_key.aspects; + result.baseMipLevel = m_key.mipIndex; + result.levelCount = m_key.mipCount; + result.baseArrayLayer = m_key.layerIndex; + result.layerCount = m_key.layerCount; + return result; + } + + /** + * \brief Actual image subresource range + * + * Handles 3D images correctly in that it only + * returns one single array layer. Use this for + * barriers. + * \returns Image subresource range + */ + VkImageSubresourceRange imageSubresources() const; + + /** + * \brief Picks an image layout + * \see DxvkImage::pickLayout + */ + VkImageLayout pickLayout(VkImageLayout layout) const; + + /** + * \brief Retrieves descriptor info + * + * \param [in] type Exact view type + * \param [in] layout Image layout + * \returns Image descriptor + */ + DxvkDescriptorInfo getDescriptor(VkImageViewType type, VkImageLayout layout) { + DxvkDescriptorInfo result; + result.image.sampler = VK_NULL_HANDLE; + result.image.imageView = handle(type); + result.image.imageLayout = layout; + return result; + } + + /** + * \brief Checks whether this view matches another + * + * \param [in] view The other view to check + * \returns \c true if the two views have the same subresources + */ + bool matchesView(const Rc& view) const { + if (this == view.ptr()) + return true; + + return this->image() == view->image() + && this->subresources() == view->subresources() + && this->info().type == view->info().type + && this->info().format == view->info().format; + } + + /** + * \brief Checks whether this view overlaps with another one + * + * Two views overlap if they were created for the same + * image and have at least one subresource in common. + * \param [in] view The other view to check + * \returns \c true if the two views overlap + */ + bool checkSubresourceOverlap(const Rc& view) const { + if (likely(m_image != view->m_image)) + return false; + + return vk::checkSubresourceRangeOverlap( + this->imageSubresources(), + view->imageSubresources()); + } + + private: + + DxvkImage* m_image = nullptr; + DxvkImageViewKey m_key = { }; + + uint32_t m_version = 0u; + + std::array m_views = { }; + + VkImageView createView(VkImageViewType type) const; + + void updateViews(); + + }; + + /** * \brief Virtual image resource * @@ -114,8 +309,8 @@ namespace dxvk { * memory type and if created with the linear tiling option. */ class DxvkImage : public DxvkPagedResource { + friend DxvkImageView; friend class DxvkContext; - friend class DxvkImageView; public: DxvkImage( @@ -348,6 +543,15 @@ namespace dxvk { return old; } + /** + * \brief Creates or retrieves an image view + * + * \param [in] info Image view create info + * \returns Newly created image view + */ + Rc createView( + const DxvkImageViewCreateInfo& info); + private: Rc m_vkd; @@ -365,6 +569,10 @@ namespace dxvk { small_vector m_viewFormats; + dxvk::mutex m_viewMutex; + std::unordered_map m_views; + VkImageCreateInfo getImageCreateInfo() const; void copyFormatList( @@ -377,219 +585,58 @@ namespace dxvk { const DxvkSharedHandleInfo& sharingInfo) const; }; - - - /** - * \brief DXVK image view - */ - class DxvkImageView : public DxvkResource { - friend class DxvkImage; - constexpr static uint32_t ViewCount = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY + 1; - public: - - DxvkImageView( - const Rc& vkd, - const Rc& image, - const DxvkImageViewCreateInfo& info); - - ~DxvkImageView(); - - /** - * \brief Image view handle for the default type - * - * 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 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 { - if (unlikely(viewType == VK_IMAGE_VIEW_TYPE_MAX_ENUM)) - viewType = m_info.type; - return m_views[viewType]; - } - - /** - * \brief Image view type - * - * Convenience method to query the view type - * in order to check for resource compatibility. - * \returns Image view type - */ - VkImageViewType type() const { - return m_info.type; - } - - /** - * \brief Image view properties - * \returns Image view properties - */ - const DxvkImageViewCreateInfo& info() const { - return m_info; - } - - /** - * \brief Image handle - * \returns Image handle - */ - VkImage imageHandle() const { - return m_image->handle(); - } - - /** - * \brief Image properties - * \returns Image properties - */ - const DxvkImageCreateInfo& imageInfo() const { - return m_image->info(); - } - - /** - * \brief Image object - * \returns Image object - */ - const Rc& image() const { - return m_image; - } - - /** - * \brief View format info - * \returns View format info - */ - const DxvkFormatInfo* formatInfo() const { - return lookupFormatInfo(m_info.format); - } - - /** - * \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, m_info.aspect); - } - - /** - * \brief View subresource range - * - * Returns the subresource range from the image - * description. For 2D views of 3D images, this - * will return the viewed 3D slices. - * \returns View subresource range - */ - VkImageSubresourceRange subresources() const { - VkImageSubresourceRange result; - result.aspectMask = m_info.aspect; - result.baseMipLevel = m_info.minLevel; - result.levelCount = m_info.numLevels; - result.baseArrayLayer = m_info.minLayer; - result.layerCount = m_info.numLayers; - return result; + + + + + inline void DxvkImageView::incRef() { + m_image->incRef(); + } + + + inline void DxvkImageView::decRef() { + m_image->decRef(); + } + + + inline VkImageSubresourceRange DxvkImageView::imageSubresources() const { + VkImageSubresourceRange result = { }; + result.aspectMask = m_key.aspects; + result.baseMipLevel = m_key.mipIndex; + result.levelCount = m_key.mipCount; + + if (likely(m_image->info().type != VK_IMAGE_TYPE_3D)) { + result.baseArrayLayer = m_key.layerIndex; + result.layerCount = m_key.layerCount; + } else { + result.baseArrayLayer = 0; + result.layerCount = 1; } - /** - * \brief Actual image subresource range - * - * Handles 3D images correctly in that it only - * returns one single array layer. Use this for - * barriers. - * \returns Image subresource range - */ - VkImageSubresourceRange imageSubresources() const { - VkImageSubresourceRange result; - result.aspectMask = m_info.aspect; - result.baseMipLevel = m_info.minLevel; - result.levelCount = m_info.numLevels; - if (likely(m_image->info().type != VK_IMAGE_TYPE_3D)) { - result.baseArrayLayer = m_info.minLayer; - result.layerCount = m_info.numLayers; - } else { - result.baseArrayLayer = 0; - result.layerCount = 1; - } - return result; - } - - /** - * \brief Picks an image layout - * \see DxvkImage::pickLayout - */ - VkImageLayout pickLayout(VkImageLayout layout) const { - return m_image->pickLayout(layout); - } + return result; + } - /** - * \brief Retrieves descriptor info - * - * \param [in] type Exact view type - * \param [in] layout Image layout - * \returns Image descriptor - */ - DxvkDescriptorInfo getDescriptor(VkImageViewType type, VkImageLayout layout) const { - DxvkDescriptorInfo result; - result.image.sampler = VK_NULL_HANDLE; - result.image.imageView = handle(type); - result.image.imageLayout = layout; - return result; - } - /** - * \brief Checks whether this view matches another - * - * \param [in] view The other view to check - * \returns \c true if the two views have the same subresources - */ - bool matchesView(const Rc& view) const { - if (this == view.ptr()) - return true; + inline VkExtent3D DxvkImageView::mipLevelExtent(uint32_t level) const { + return m_image->mipLevelExtent(level + m_key.mipIndex, m_key.aspects); + } - return this->image() == view->image() - && this->subresources() == view->subresources() - && this->info().type == view->info().type - && this->info().format == view->info().format; - } - /** - * \brief Checks whether this view overlaps with another one - * - * Two views overlap if they were created for the same - * image and have at least one subresource in common. - * \param [in] view The other view to check - * \returns \c true if the two views overlap - */ - bool checkSubresourceOverlap(const Rc& view) const { - if (likely(m_image != view->m_image)) - return false; + inline VkImageLayout DxvkImageView::pickLayout(VkImageLayout layout) const { + return m_image->pickLayout(layout); + } - return vk::checkSubresourceRangeOverlap( - this->imageSubresources(), - view->imageSubresources()); - } - private: - - Rc m_vkd; - Rc m_image; - - DxvkImageViewCreateInfo m_info; - VkImageView m_views[ViewCount]; + inline VkImageView DxvkImageView::handle(VkImageViewType viewType) { + viewType = viewType != VK_IMAGE_VIEW_TYPE_MAX_ENUM ? viewType : m_key.viewType; + + if (unlikely(m_version < m_image->m_version)) + updateViews(); + + if (unlikely(!m_views[viewType])) + m_views[viewType] = createView(viewType); + + return m_views[viewType]; + } - void createView(VkImageViewType type, uint32_t numLayers); - - }; - } diff --git a/src/dxvk/dxvk_meta_mipgen.cpp b/src/dxvk/dxvk_meta_mipgen.cpp index 46c2dd73..4d0450b4 100644 --- a/src/dxvk/dxvk_meta_mipgen.cpp +++ b/src/dxvk/dxvk_meta_mipgen.cpp @@ -13,8 +13,8 @@ namespace dxvk { { VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_2D_ARRAY }, }}; - m_srcViewType = viewTypes.at(uint32_t(view->imageInfo().type)).first; - m_dstViewType = viewTypes.at(uint32_t(view->imageInfo().type)).second; + m_srcViewType = viewTypes.at(uint32_t(view->image()->info().type)).first; + m_dstViewType = viewTypes.at(uint32_t(view->image()->info().type)).second; // Create image views and framebuffers m_passes.resize(view->info().numLevels - 1); @@ -35,7 +35,7 @@ namespace dxvk { VkExtent3D DxvkMetaMipGenRenderPass::computePassExtent(uint32_t passId) const { VkExtent3D extent = m_view->mipLevelExtent(passId + 1); - if (m_view->imageInfo().type != VK_IMAGE_TYPE_3D) + if (m_view->image()->info().type != VK_IMAGE_TYPE_3D) extent.depth = m_view->info().numLayers; return extent; @@ -48,7 +48,7 @@ namespace dxvk { VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo }; - viewInfo.image = m_view->imageHandle(); + viewInfo.image = m_view->image()->handle(); viewInfo.format = m_view->info().format; // Create source image view, which points to @@ -76,7 +76,7 @@ namespace dxvk { dstSubresources.baseMipLevel = m_view->info().minLevel + pass + 1; dstSubresources.levelCount = 1; - if (m_view->imageInfo().type != VK_IMAGE_TYPE_3D) { + if (m_view->image()->info().type != VK_IMAGE_TYPE_3D) { dstSubresources.baseArrayLayer = m_view->info().minLayer; dstSubresources.layerCount = m_view->info().numLayers; } else { diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index bd1ea7cf..b08eb5dc 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -33,21 +33,21 @@ namespace dxvk { if (!dstRect.extent.width || !dstRect.extent.height) { dstRect.offset = { 0, 0 }; dstRect.extent = { - dstView->imageInfo().extent.width, - dstView->imageInfo().extent.height }; + dstView->image()->info().extent.width, + dstView->image()->info().extent.height }; } if (!srcRect.extent.width || !srcRect.extent.height) { srcRect.offset = { 0, 0 }; srcRect.extent = { - srcView->imageInfo().extent.width, - srcView->imageInfo().extent.height }; + srcView->image()->info().extent.width, + srcView->image()->info().extent.height }; } bool sameSize = dstRect.extent == srcRect.extent; bool usedResolveImage = false; - if (srcView->imageInfo().sampleCount == VK_SAMPLE_COUNT_1_BIT) { + if (srcView->image()->info().sampleCount == VK_SAMPLE_COUNT_1_BIT) { this->draw(ctx, sameSize ? m_fsCopy : m_fsBlit, dstView, dstRect, srcView, srcRect); } else if (sameSize) { @@ -55,9 +55,9 @@ namespace dxvk { dstView, dstRect, srcView, srcRect); } else { if (m_resolveImage == nullptr - || m_resolveImage->info().extent != srcView->imageInfo().extent - || m_resolveImage->info().format != srcView->imageInfo().format) - this->createResolveImage(srcView->imageInfo()); + || m_resolveImage->info().extent != srcView->image()->info().extent + || m_resolveImage->info().format != srcView->image()->info().format) + this->createResolveImage(srcView->image()->info()); this->resolve(ctx, m_resolveView, srcView); this->draw(ctx, m_fsBlit, dstView, dstRect, m_resolveView, srcRect); @@ -185,8 +185,8 @@ namespace dxvk { ctx->bindRenderTargets(std::move(renderTargets), 0u); VkExtent2D dstExtent = { - dstView->imageInfo().extent.width, - dstView->imageInfo().extent.height }; + dstView->image()->info().extent.width, + dstView->image()->info().extent.height }; if (dstRect.extent == dstExtent) ctx->discardImageView(dstView, VK_IMAGE_ASPECT_COLOR_BIT); @@ -212,7 +212,7 @@ namespace dxvk { ctx->pushConstants(0, sizeof(args), &args); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, srcView->imageInfo().sampleCount); + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, srcView->image()->info().sampleCount); ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 1, m_gammaView != nullptr); ctx->draw(3, 1, 0, 0); } @@ -226,7 +226,7 @@ namespace dxvk { resolve.srcOffset = { 0, 0, 0 }; resolve.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; resolve.dstOffset = { 0, 0, 0 }; - resolve.extent = dstView->imageInfo().extent; + resolve.extent = dstView->image()->info().extent; ctx->resolveImage(dstView->image(), srcView->image(), resolve, VK_FORMAT_UNDEFINED); }