From 2527ea45b9e0ed4ab34ff026ce1778f99c2387c6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 5 Nov 2021 13:56:19 +0100 Subject: [PATCH] [dxvk] Refactor framebuffer creation --- src/dxvk/dxvk_context.cpp | 2 +- src/dxvk/dxvk_device.cpp | 9 +- src/dxvk/dxvk_device.h | 6 +- src/dxvk/dxvk_framebuffer.cpp | 137 ++++----------------------- src/dxvk/dxvk_framebuffer.h | 171 +--------------------------------- 5 files changed, 26 insertions(+), 299 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 06ceee51..f328884a 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4004,7 +4004,7 @@ namespace dxvk { const VkClearValue* clearValues) { const DxvkFramebufferSize fbSize = framebufferInfo.size(); - Rc framebuffer = m_device->createFramebuffer(framebufferInfo.attachments()); + Rc framebuffer = m_device->createFramebuffer(framebufferInfo); VkRect2D renderArea; renderArea.offset = VkOffset2D { 0, 0 }; diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index f21e846c..b5720e52 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -113,13 +113,8 @@ namespace dxvk { Rc DxvkDevice::createFramebuffer( - const DxvkRenderTargets& renderTargets) { - auto renderPassFormat = DxvkFramebuffer::getRenderPassFormat(renderTargets); - auto renderPassObject = m_objects.renderPassPool().getRenderPass(renderPassFormat); - - return new DxvkFramebuffer(m_vkd, - renderPassObject, renderTargets, - getDefaultFramebufferSize()); + const DxvkFramebufferInfo& info) { + return new DxvkFramebuffer(m_vkd, info); } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 31336f10..41c7df58 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -270,13 +270,11 @@ namespace dxvk { /** * \brief Creates framebuffer for a set of render targets * - * Automatically deduces framebuffer dimensions - * from the supplied render target views. - * \param [in] renderTargets Render targets + * \param [in] info Framebuffer info * \returns The framebuffer object */ Rc createFramebuffer( - const DxvkRenderTargets& renderTargets); + const DxvkFramebufferInfo& info); /** * \brief Creates a buffer object diff --git a/src/dxvk/dxvk_framebuffer.cpp b/src/dxvk/dxvk_framebuffer.cpp index 856e9d33..6a545cae 100644 --- a/src/dxvk/dxvk_framebuffer.cpp +++ b/src/dxvk/dxvk_framebuffer.cpp @@ -127,41 +127,31 @@ namespace dxvk { DxvkFramebuffer::DxvkFramebuffer( const Rc& vkd, - DxvkRenderPass* renderPass, - const DxvkRenderTargets& renderTargets, - const DxvkFramebufferSize& defaultSize) - : m_vkd (vkd), - m_renderPass (renderPass), - m_renderTargets (renderTargets), - m_renderSize (computeRenderSize(defaultSize)) { + const DxvkFramebufferInfo& info) + : m_vkd (vkd) { std::array views; + uint32_t attachmentCount = 0; for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (m_renderTargets.color[i].view != nullptr) { - views[m_attachmentCount] = m_renderTargets.color[i].view->handle(); - m_attachments[m_attachmentCount] = i; - m_attachmentCount += 1; - } + if (info.getColorTarget(i).view != nullptr) + views[attachmentCount++] = info.getColorTarget(i).view->handle(); } - if (m_renderTargets.depth.view != nullptr) { - views[m_attachmentCount] = m_renderTargets.depth.view->handle(); - m_attachments[m_attachmentCount] = -1; - m_attachmentCount += 1; - } + if (info.getDepthTarget().view != nullptr) + views[attachmentCount++] = info.getDepthTarget().view->handle(); - VkFramebufferCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.renderPass = m_renderPass->getDefaultHandle(); - info.attachmentCount = m_attachmentCount; - info.pAttachments = views.data(); - info.width = m_renderSize.width; - info.height = m_renderSize.height; - info.layers = m_renderSize.layers; + VkFramebufferCreateInfo fbInfo; + fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + fbInfo.pNext = nullptr; + fbInfo.flags = 0; + fbInfo.renderPass = info.renderPass()->getDefaultHandle(); + fbInfo.attachmentCount = attachmentCount; + fbInfo.pAttachments = views.data(); + fbInfo.width = info.size().width; + fbInfo.height = info.size().height; + fbInfo.layers = info.size().layers; - if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &info, nullptr, &m_handle) != VK_SUCCESS) + if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fbInfo, nullptr, &m_handle) != VK_SUCCESS) Logger::err("DxvkFramebuffer: Failed to create framebuffer object"); } @@ -169,96 +159,5 @@ namespace dxvk { DxvkFramebuffer::~DxvkFramebuffer() { m_vkd->vkDestroyFramebuffer(m_vkd->device(), m_handle, nullptr); } - - - int32_t DxvkFramebuffer::findAttachment(const Rc& view) const { - for (uint32_t i = 0; i < m_attachmentCount; i++) { - if (getAttachment(i).view->matchesView(view)) - return int32_t(i); - } - - return -1; - } - - - bool DxvkFramebuffer::hasTargets(const DxvkRenderTargets& renderTargets) { - bool eq = m_renderTargets.depth.view == renderTargets.depth.view - && m_renderTargets.depth.layout == renderTargets.depth.layout; - - for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) { - eq &= m_renderTargets.color[i].view == renderTargets.color[i].view - && m_renderTargets.color[i].layout == renderTargets.color[i].layout; - } - - return eq; - } - - - bool DxvkFramebuffer::isFullSize(const Rc& view) const { - return m_renderSize.width == view->mipLevelExtent(0).width - && m_renderSize.height == view->mipLevelExtent(0).height - && m_renderSize.layers == view->info().numLayers; - } - - bool DxvkFramebuffer::isWritable(uint32_t attachmentIndex, VkImageAspectFlags aspects) const { - VkImageAspectFlags writableAspects = vk::getWritableAspectsForLayout(getAttachment(attachmentIndex).layout); - return (writableAspects & aspects) == aspects; - } - - - DxvkRenderPassFormat DxvkFramebuffer::getRenderPassFormat(const DxvkRenderTargets& renderTargets) { - DxvkRenderPassFormat format; - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (renderTargets.color[i].view != nullptr) { - format.sampleCount = renderTargets.color[i].view->imageInfo().sampleCount; - format.color[i].format = renderTargets.color[i].view->info().format; - format.color[i].layout = renderTargets.color[i].layout; - } - } - - if (renderTargets.depth.view != nullptr) { - format.sampleCount = renderTargets.depth.view->imageInfo().sampleCount; - format.depth.format = renderTargets.depth.view->info().format; - format.depth.layout = renderTargets.depth.layout; - } - - return format; - } - - - DxvkFramebufferSize DxvkFramebuffer::computeRenderSize( - const DxvkFramebufferSize& defaultSize) const { - // Some games bind render targets of a different size and - // expect it to work, so we'll compute the minimum size - DxvkFramebufferSize minSize = defaultSize; - - if (m_renderTargets.depth.view != nullptr) { - DxvkFramebufferSize depthSize = this->computeRenderTargetSize(m_renderTargets.depth.view); - minSize.width = std::min(minSize.width, depthSize.width); - minSize.height = std::min(minSize.height, depthSize.height); - minSize.layers = std::min(minSize.layers, depthSize.layers); - } - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (m_renderTargets.color[i].view != nullptr) { - DxvkFramebufferSize colorSize = this->computeRenderTargetSize(m_renderTargets.color[i].view); - minSize.width = std::min(minSize.width, colorSize.width); - minSize.height = std::min(minSize.height, colorSize.height); - minSize.layers = std::min(minSize.layers, colorSize.layers); - } - } - - return minSize; - } - - - DxvkFramebufferSize DxvkFramebuffer::computeRenderTargetSize( - const Rc& renderTarget) const { - auto extent = renderTarget->mipLevelExtent(0); - auto layers = renderTarget->info().numLayers; - return DxvkFramebufferSize { extent.width, extent.height, layers }; - } - } \ No newline at end of file diff --git a/src/dxvk/dxvk_framebuffer.h b/src/dxvk/dxvk_framebuffer.h index aead5d9e..2c14f95c 100644 --- a/src/dxvk/dxvk_framebuffer.h +++ b/src/dxvk/dxvk_framebuffer.h @@ -236,9 +236,7 @@ namespace dxvk { DxvkFramebuffer( const Rc& vkd, - DxvkRenderPass* renderPass, - const DxvkRenderTargets& renderTargets, - const DxvkFramebufferSize& defaultSize); + const DxvkFramebufferInfo& info); ~DxvkFramebuffer(); @@ -250,173 +248,10 @@ namespace dxvk { return m_handle; } - /** - * \brief Framebuffer size - * \returns Framebuffer size - */ - DxvkFramebufferSize size() const { - return m_renderSize; - } - - /** - * \brief Framebuffer sample count - * - * Returns the sample count of the color - * and depth-stencil attachments, or 0 if - * there are no attachments. - * \returns Sample count - */ - VkSampleCountFlags getSampleCount() const { - return m_attachmentCount != 0 - ? m_renderPass->getSampleCount() - : 0; - } - - /** - * \brief Retrieves default render pass handle - * - * Retrieves the render pass handle that was used - * to create the Vulkan framebuffer object with, - * and that should be used to create pipelines. - * \returns The default render pass handle - */ - VkRenderPass getDefaultRenderPassHandle() const { - return m_renderPass->getDefaultHandle(); - } - - /** - * \brief Retrieves render pass handle - * - * Retrieves a render pass handle that can - * be used to begin a render pass instance. - * \param [in] ops Render pass ops - * \returns The render pass handle - */ - VkRenderPass getRenderPassHandle(const DxvkRenderPassOps& ops) const { - return m_renderPass->getHandle(ops); - } - - /** - * \brief Retrieves render pass - * \returns Render pass reference - */ - DxvkRenderPass* getRenderPass() const { - return m_renderPass; - } - - /** - * \brief Depth-stencil target - * \returns Depth-stencil target - */ - const DxvkAttachment& getDepthTarget() const { - return m_renderTargets.depth; - } - - /** - * \brief Color target - * - * \param [in] id Target Index - * \returns The color target - */ - const DxvkAttachment& getColorTarget(uint32_t id) const { - return m_renderTargets.color[id]; - } - - /** - * \brief Number of framebuffer attachment - * \returns Total attachment count - */ - uint32_t numAttachments() const { - return m_attachmentCount; - } - - /** - * \brief Queries color attachment index of a given attachment - * \returns The index, or -1 if the given attachment is the depth attachment - */ - const int32_t getColorAttachmentIndex(uint32_t id) const { - return m_attachments[id]; - } - - /** - * \brief Retrieves attachment by index - * - * \param [in] id Framebuffer attachment ID - * \returns The framebuffer attachment - */ - const DxvkAttachment& getAttachment(uint32_t id) const { - int32_t idx = getColorAttachmentIndex(id); - return idx < 0 ? m_renderTargets.depth : m_renderTargets.color[idx]; - } - - /** - * \brief Finds attachment index by view - * - * Color attachments start at 0 - * \param [in] view Image view - * \returns Attachment index - */ - int32_t findAttachment(const Rc& view) const; - - /** - * \brief Checks whether the framebuffer's targets match - * - * \param [in] renderTargets Render targets to check - * \returns \c true if the render targets are the same - * as the ones used for this framebuffer object. - */ - bool hasTargets(const DxvkRenderTargets& renderTargets); - - /** - * \brief Checks whether view and framebuffer sizes match - * - * Tests whether the size of the framebuffer is the same - * as the size of one of its views. This may be \c false - * when mixing attachments with mismatched dimensions. - * \param [in] view Image view to test - * \returns \c true if \c view has the same size as - * the framebuffer. - */ - bool isFullSize(const Rc& view) const; - - /** - * \brief Checks whether an attachment is writable - * - * Needed for certain clear optimizations. - * \param [in] attachmentIndex Attachment to check - * \param [in] aspects Aspect mask to check - * \returns \c true if all aspects can be written for the given attachment - */ - bool isWritable(uint32_t attachmentIndex, VkImageAspectFlags aspects) const; - - /** - * \brief Generatess render pass format - * - * This render pass format can be used to - * look up a compatible render pass. - * \param [in] renderTargets Render targets - * \returns The render pass format - */ - static DxvkRenderPassFormat getRenderPassFormat( - const DxvkRenderTargets& renderTargets); - private: - const Rc m_vkd; - DxvkRenderPass* m_renderPass; - const DxvkRenderTargets m_renderTargets; - const DxvkFramebufferSize m_renderSize; - - uint32_t m_attachmentCount = 0; - std::array m_attachments; - - VkFramebuffer m_handle = VK_NULL_HANDLE; - - DxvkFramebufferSize computeRenderSize( - const DxvkFramebufferSize& defaultSize) const; - - DxvkFramebufferSize computeRenderTargetSize( - const Rc& renderTarget) const; + Rc m_vkd; + VkFramebuffer m_handle; };