#include "dxvk_framebuffer.h" namespace dxvk { DxvkRenderTargets:: DxvkRenderTargets() { } DxvkRenderTargets::~DxvkRenderTargets() { } DxvkRenderPassFormat DxvkRenderTargets::renderPassFormat() const { DxvkRenderPassFormat result; for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if (m_colorTargets.at(i).view != nullptr) { result.setColorFormat(i, DxvkRenderTargetFormat { m_colorTargets.at(i).view->info().format, m_colorTargets.at(i).view->imageInfo().layout, m_colorTargets.at(i).view->imageInfo().layout, m_colorTargets.at(i).layout }); result.setSampleCount(m_colorTargets.at(i).view->imageInfo().sampleCount); } } if (m_depthTarget.view != nullptr) { result.setDepthFormat(DxvkRenderTargetFormat { m_depthTarget.view->info().format, m_depthTarget.view->imageInfo().layout, m_depthTarget.view->imageInfo().layout, m_depthTarget.layout }); result.setSampleCount(m_depthTarget.view->imageInfo().sampleCount); } return result; } uint32_t DxvkRenderTargets::getAttachments(VkImageView* viewHandles) const { uint32_t numViews = 0; if (m_depthTarget.view != nullptr) viewHandles[numViews++] = m_depthTarget.view->handle(); for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if (m_colorTargets.at(i).view != nullptr) viewHandles[numViews++] = m_colorTargets.at(i).view->handle(); } return numViews; } DxvkFramebufferSize DxvkRenderTargets::getImageSize( const DxvkFramebufferSize& defaultSize) const { if (m_depthTarget.view != nullptr) return this->renderTargetSize(m_depthTarget.view); for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if (m_colorTargets.at(i).view != nullptr) return this->renderTargetSize(m_colorTargets.at(i).view); } return defaultSize; } bool DxvkRenderTargets::hasAttachments() const { bool result = m_depthTarget.view != nullptr; for (uint32_t i = 0; (i < MaxNumRenderTargets) && !result; i++) result |= m_colorTargets.at(i).view != nullptr; return result; } bool DxvkRenderTargets::matches(const DxvkRenderTargets& other) const { bool equal = m_depthTarget.view == other.m_depthTarget.view && m_depthTarget.layout == other.m_depthTarget.layout; for (uint32_t i = 0; i < MaxNumRenderTargets && equal; i++) { equal &= m_colorTargets.at(i).view == other.m_colorTargets.at(i).view && m_colorTargets.at(i).layout == other.m_colorTargets.at(i).layout; } return equal; } DxvkFramebufferSize DxvkRenderTargets::renderTargetSize( const Rc& renderTarget) const { auto extent = renderTarget->mipLevelExtent(0); auto layers = renderTarget->info().numLayers; return DxvkFramebufferSize { extent.width, extent.height, layers }; } DxvkFramebuffer::DxvkFramebuffer( const Rc& vkd, const Rc& renderPass, const DxvkRenderTargets& renderTargets, const DxvkFramebufferSize& defaultSize) : m_vkd (vkd), m_renderPass (renderPass), m_renderTargets (renderTargets), m_framebufferSize (renderTargets.getImageSize(defaultSize)) { std::array views; uint32_t viewCount = renderTargets.getAttachments(views.data()); VkFramebufferCreateInfo info; info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; info.pNext = nullptr; info.flags = 0; info.renderPass = renderPass->handle(); info.attachmentCount = viewCount; info.pAttachments = views.data(); info.width = m_framebufferSize.width; info.height = m_framebufferSize.height; info.layers = m_framebufferSize.layers; if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &info, nullptr, &m_framebuffer) != VK_SUCCESS) throw DxvkError("DxvkFramebuffer: Failed to create framebuffer object"); } DxvkFramebuffer::~DxvkFramebuffer() { m_vkd->vkDestroyFramebuffer( m_vkd->device(), m_framebuffer, nullptr); } uint32_t DxvkFramebuffer::findAttachment( const Rc& view) const { if (m_renderTargets.getDepthTarget().view == view) return 0; for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if (m_renderTargets.getColorTarget(i).view == view) return i; } return MaxNumRenderTargets; } }