2017-10-10 23:32:13 +02:00
|
|
|
#include "dxvk_renderpass.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
DxvkRenderPassFormat::DxvkRenderPassFormat() {
|
2017-10-14 13:37:40 +02:00
|
|
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
|
2017-10-10 23:32:13 +02:00
|
|
|
m_color.at(i) = VK_FORMAT_UNDEFINED;
|
|
|
|
m_depth = VK_FORMAT_UNDEFINED;
|
|
|
|
m_samples = VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t DxvkRenderPassFormat::hash() const {
|
|
|
|
DxvkHashState result;
|
|
|
|
std::hash<VkFormat> fhash;
|
|
|
|
std::hash<VkSampleCountFlagBits> shash;
|
|
|
|
|
2017-10-14 13:37:40 +02:00
|
|
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
|
2017-10-10 23:32:13 +02:00
|
|
|
result.add(fhash(m_color.at(i)));
|
|
|
|
|
|
|
|
result.add(fhash(m_depth));
|
|
|
|
result.add(shash(m_samples));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DxvkRenderPassFormat::operator == (const DxvkRenderPassFormat& other) const {
|
|
|
|
bool equal = m_depth == other.m_depth
|
|
|
|
&& m_samples == other.m_samples;
|
2017-10-14 13:37:40 +02:00
|
|
|
for (uint32_t i = 0; i < MaxNumRenderTargets && !equal; i++)
|
2017-10-10 23:32:13 +02:00
|
|
|
equal = m_color.at(i) == other.m_color.at(i);
|
|
|
|
return equal;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DxvkRenderPassFormat::operator != (const DxvkRenderPassFormat& other) const {
|
|
|
|
return !this->operator == (other);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DxvkRenderPass::DxvkRenderPass(
|
|
|
|
const Rc<vk::DeviceFn>& vkd,
|
2017-12-05 13:00:06 +01:00
|
|
|
const DxvkRenderPassFormat& fmt)
|
2017-10-10 23:32:13 +02:00
|
|
|
: m_vkd(vkd), m_format(fmt) {
|
|
|
|
std::vector<VkAttachmentDescription> attachments;
|
|
|
|
|
2017-11-20 15:35:29 +01:00
|
|
|
VkAttachmentReference depthRef;
|
2017-10-14 13:37:40 +02:00
|
|
|
std::array<VkAttachmentReference, MaxNumRenderTargets> colorRef;
|
2017-10-10 23:32:13 +02:00
|
|
|
|
|
|
|
// Render passes may not require the previous
|
|
|
|
// contents of the attachments to be preserved.
|
|
|
|
if (fmt.getDepthFormat() != VK_FORMAT_UNDEFINED) {
|
|
|
|
VkAttachmentDescription desc;
|
|
|
|
desc.flags = 0;
|
|
|
|
desc.format = fmt.getDepthFormat();
|
|
|
|
desc.samples = fmt.getSampleCount();
|
2017-12-05 13:00:06 +01:00
|
|
|
desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
|
|
desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
|
|
desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
|
|
desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
|
|
desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
|
|
desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
2017-10-10 23:32:13 +02:00
|
|
|
|
|
|
|
depthRef.attachment = attachments.size();
|
|
|
|
depthRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
|
|
|
|
|
|
attachments.push_back(desc);
|
|
|
|
}
|
|
|
|
|
2017-10-14 13:37:40 +02:00
|
|
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
2017-10-10 23:32:13 +02:00
|
|
|
colorRef.at(i).attachment = VK_ATTACHMENT_UNUSED;
|
|
|
|
colorRef.at(i).layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
|
|
|
|
|
|
if (fmt.getColorFormat(i) != VK_FORMAT_UNDEFINED) {
|
|
|
|
VkAttachmentDescription desc;
|
2017-12-05 13:00:06 +01:00
|
|
|
desc.flags = 0;
|
|
|
|
desc.format = fmt.getColorFormat(i);
|
|
|
|
desc.samples = fmt.getSampleCount();
|
|
|
|
desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
|
|
desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
|
|
desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
|
|
desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
|
|
desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
|
|
desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
2017-10-10 23:32:13 +02:00
|
|
|
|
|
|
|
colorRef.at(i).attachment = attachments.size();
|
|
|
|
colorRef.at(i).layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
|
|
|
|
|
|
attachments.push_back(desc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VkSubpassDescription subpass;
|
|
|
|
subpass.flags = 0;
|
|
|
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
|
|
|
subpass.inputAttachmentCount = 0;
|
|
|
|
subpass.pInputAttachments = nullptr;
|
|
|
|
subpass.colorAttachmentCount = colorRef.size();
|
|
|
|
subpass.pColorAttachments = colorRef.data();
|
|
|
|
subpass.pResolveAttachments = nullptr;
|
|
|
|
subpass.pDepthStencilAttachment = fmt.getDepthFormat() != VK_FORMAT_UNDEFINED ? &depthRef : nullptr;
|
|
|
|
subpass.preserveAttachmentCount = 0;
|
|
|
|
subpass.pPreserveAttachments = nullptr;
|
|
|
|
|
|
|
|
VkRenderPassCreateInfo info;
|
|
|
|
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
|
|
|
info.pNext = nullptr;
|
|
|
|
info.flags = 0;
|
|
|
|
info.attachmentCount = attachments.size();
|
|
|
|
info.pAttachments = attachments.data();
|
|
|
|
info.subpassCount = 1;
|
|
|
|
info.pSubpasses = &subpass;
|
|
|
|
info.dependencyCount = 0;
|
|
|
|
info.pDependencies = nullptr;
|
|
|
|
|
|
|
|
if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &m_renderPass) != VK_SUCCESS)
|
|
|
|
throw DxvkError("DxvkRenderPass::DxvkRenderPass: Failed to create render pass object");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DxvkRenderPass::~DxvkRenderPass() {
|
|
|
|
m_vkd->vkDestroyRenderPass(
|
|
|
|
m_vkd->device(), m_renderPass, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DxvkRenderPassPool::DxvkRenderPassPool(const Rc<vk::DeviceFn>& vkd)
|
2017-10-11 00:27:33 +02:00
|
|
|
: m_vkd(vkd) {
|
2017-11-26 14:01:41 +01:00
|
|
|
|
2017-10-11 00:27:33 +02:00
|
|
|
}
|
2017-10-10 23:32:13 +02:00
|
|
|
|
|
|
|
|
|
|
|
DxvkRenderPassPool::~DxvkRenderPassPool() {
|
2017-11-26 14:01:41 +01:00
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Rc<DxvkRenderPass> DxvkRenderPassPool::getRenderPass(
|
|
|
|
const DxvkRenderPassFormat& fmt) {
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
|
|
|
auto rp = m_renderPasses.find(fmt);
|
|
|
|
|
|
|
|
if (rp != m_renderPasses.end())
|
|
|
|
return rp->second;
|
|
|
|
|
|
|
|
auto result = this->createRenderPass(fmt);
|
|
|
|
m_renderPasses.insert(std::make_pair(fmt, result));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Rc<DxvkRenderPass> DxvkRenderPassPool::createRenderPass(
|
|
|
|
const DxvkRenderPassFormat& fmt) {
|
2017-12-05 13:00:06 +01:00
|
|
|
return new DxvkRenderPass(m_vkd, fmt);
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|