2017-10-10 23:32:13 +02:00
|
|
|
#include "dxvk_framebuffer.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
DxvkRenderTargets:: DxvkRenderTargets() { }
|
|
|
|
DxvkRenderTargets::~DxvkRenderTargets() { }
|
|
|
|
|
|
|
|
|
|
|
|
DxvkRenderPassFormat DxvkRenderTargets::renderPassFormat() const {
|
|
|
|
DxvkRenderPassFormat result;
|
|
|
|
|
2017-10-14 13:37:40 +02:00
|
|
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
2018-02-06 17:31:23 +01:00
|
|
|
if (m_colorTargets.at(i).view != nullptr) {
|
2018-01-22 19:21:46 +01:00
|
|
|
result.setColorFormat(i, DxvkRenderTargetFormat {
|
2018-02-06 17:31:23 +01:00
|
|
|
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);
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-06 17:31:23 +01:00
|
|
|
if (m_depthTarget.view != nullptr) {
|
2018-01-22 19:21:46 +01:00
|
|
|
result.setDepthFormat(DxvkRenderTargetFormat {
|
2018-02-06 17:31:23 +01:00
|
|
|
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);
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-02-07 16:46:39 +01:00
|
|
|
uint32_t DxvkRenderTargets::getAttachments(VkImageView* viewHandles) const {
|
|
|
|
uint32_t numViews = 0;
|
2017-10-10 23:32:13 +02:00
|
|
|
|
2018-02-06 17:31:23 +01:00
|
|
|
if (m_depthTarget.view != nullptr)
|
2018-02-07 16:46:39 +01:00
|
|
|
viewHandles[numViews++] = m_depthTarget.view->handle();
|
2017-10-10 23:32:13 +02:00
|
|
|
|
2017-10-14 13:37:40 +02:00
|
|
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
2018-02-06 17:31:23 +01:00
|
|
|
if (m_colorTargets.at(i).view != nullptr)
|
2018-02-07 16:46:39 +01:00
|
|
|
viewHandles[numViews++] = m_colorTargets.at(i).view->handle();
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
2018-02-07 16:46:39 +01:00
|
|
|
return numViews;
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-29 11:19:18 +02:00
|
|
|
DxvkFramebufferSize DxvkRenderTargets::getImageSize(
|
|
|
|
const DxvkFramebufferSize& defaultSize) const {
|
2018-02-06 17:31:23 +01:00
|
|
|
if (m_depthTarget.view != nullptr)
|
|
|
|
return this->renderTargetSize(m_depthTarget.view);
|
2017-10-10 23:32:13 +02:00
|
|
|
|
2017-10-14 13:37:40 +02:00
|
|
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
2018-02-06 17:31:23 +01:00
|
|
|
if (m_colorTargets.at(i).view != nullptr)
|
|
|
|
return this->renderTargetSize(m_colorTargets.at(i).view);
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
2018-04-29 11:19:18 +02:00
|
|
|
return defaultSize;
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-19 18:12:18 +01:00
|
|
|
bool DxvkRenderTargets::hasAttachments() const {
|
2018-02-06 17:31:23 +01:00
|
|
|
bool result = m_depthTarget.view != nullptr;
|
2017-12-19 18:12:18 +01:00
|
|
|
|
|
|
|
for (uint32_t i = 0; (i < MaxNumRenderTargets) && !result; i++)
|
2018-02-06 17:31:23 +01:00
|
|
|
result |= m_colorTargets.at(i).view != nullptr;
|
2017-12-19 18:12:18 +01:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-15 03:01:52 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
DxvkFramebufferSize DxvkRenderTargets::renderTargetSize(
|
|
|
|
const Rc<DxvkImageView>& renderTarget) const {
|
2018-01-06 02:09:07 +01:00
|
|
|
auto extent = renderTarget->mipLevelExtent(0);
|
2017-10-10 23:32:13 +02:00
|
|
|
auto layers = renderTarget->info().numLayers;
|
|
|
|
return DxvkFramebufferSize { extent.width, extent.height, layers };
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DxvkFramebuffer::DxvkFramebuffer(
|
|
|
|
const Rc<vk::DeviceFn>& vkd,
|
|
|
|
const Rc<DxvkRenderPass>& renderPass,
|
2018-04-29 11:19:18 +02:00
|
|
|
const DxvkRenderTargets& renderTargets,
|
|
|
|
const DxvkFramebufferSize& defaultSize)
|
2017-10-10 23:32:13 +02:00
|
|
|
: m_vkd (vkd),
|
|
|
|
m_renderPass (renderPass),
|
|
|
|
m_renderTargets (renderTargets),
|
2018-04-29 11:19:18 +02:00
|
|
|
m_framebufferSize (renderTargets.getImageSize(defaultSize)) {
|
2018-02-07 16:46:39 +01:00
|
|
|
std::array<VkImageView, MaxNumRenderTargets + 1> views;
|
|
|
|
uint32_t viewCount = renderTargets.getAttachments(views.data());
|
2017-10-10 23:32:13 +02:00
|
|
|
|
|
|
|
VkFramebufferCreateInfo info;
|
|
|
|
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
|
|
|
info.pNext = nullptr;
|
|
|
|
info.flags = 0;
|
|
|
|
info.renderPass = renderPass->handle();
|
2018-02-07 16:46:39 +01:00
|
|
|
info.attachmentCount = viewCount;
|
2017-10-10 23:32:13 +02:00
|
|
|
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)
|
2018-04-13 17:03:35 +02:00
|
|
|
throw DxvkError("DxvkFramebuffer: Failed to create framebuffer object");
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DxvkFramebuffer::~DxvkFramebuffer() {
|
|
|
|
m_vkd->vkDestroyFramebuffer(
|
|
|
|
m_vkd->device(), m_framebuffer, nullptr);
|
|
|
|
}
|
|
|
|
|
2018-03-17 17:59:43 +01:00
|
|
|
|
|
|
|
uint32_t DxvkFramebuffer::findAttachment(
|
|
|
|
const Rc<DxvkImageView>& 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;
|
|
|
|
}
|
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|