Removed redundant RenderPassType::RENDER_PASS_GENERATE_SHADOWMAPS
Added support for multiple color attachments in a render pass. WIP render graph implementation. Deleted copy constructors for KRContextObject
This commit is contained in:
@@ -187,7 +187,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
|
|||||||
if (settings.m_cShadowBuffers > 0) {
|
if (settings.m_cShadowBuffers > 0) {
|
||||||
GL_PUSH_GROUP_MARKER("Generate Shadowmaps");
|
GL_PUSH_GROUP_MARKER("Generate Shadowmaps");
|
||||||
|
|
||||||
scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_GENERATE_SHADOWMAPS), false /*settings.bEnableDeferredLighting*/);
|
scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_SHADOWMAP), false /*settings.bEnableDeferredLighting*/);
|
||||||
GL_POP_GROUP_MARKER;
|
GL_POP_GROUP_MARKER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -969,9 +969,6 @@ std::string KRCamera::getDebugText()
|
|||||||
case RenderPassType::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE:
|
case RenderPassType::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE:
|
||||||
stream << "vol add";
|
stream << "vol add";
|
||||||
break;
|
break;
|
||||||
case RenderPassType::RENDER_PASS_GENERATE_SHADOWMAPS:
|
|
||||||
stream << "g shadow";
|
|
||||||
break;
|
|
||||||
case RenderPassType::RENDER_PASS_SHADOWMAP:
|
case RenderPassType::RENDER_PASS_SHADOWMAP:
|
||||||
stream << "shadow";
|
stream << "shadow";
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ public:
|
|||||||
~KRContextObject();
|
~KRContextObject();
|
||||||
|
|
||||||
KRContext& getContext() const;
|
KRContext& getContext() const;
|
||||||
|
KRContextObject(const KRContextObject&) = delete;
|
||||||
|
KRContextObject& operator=(KRContextObject&) = delete;
|
||||||
protected:
|
protected:
|
||||||
KRContext* m_pContext;
|
KRContext* m_pContext;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ void KRLight::render(RenderInfo& ri)
|
|||||||
|
|
||||||
KRNode::render(ri);
|
KRNode::render(ri);
|
||||||
|
|
||||||
if (ri.renderPass->getType() == RenderPassType::RENDER_PASS_GENERATE_SHADOWMAPS && (ri.camera->settings.volumetric_environment_enable || ri.camera->settings.dust_particle_enable || (ri.camera->settings.m_cShadowBuffers > 0 && m_casts_shadow))) {
|
if (ri.renderPass->getType() == RenderPassType::RENDER_PASS_SHADOWMAP && (ri.camera->settings.volumetric_environment_enable || ri.camera->settings.dust_particle_enable || (ri.camera->settings.m_cShadowBuffers > 0 && m_casts_shadow))) {
|
||||||
allocateShadowBuffers(configureShadowBufferViewports(ri.viewport));
|
allocateShadowBuffers(configureShadowBufferViewports(ri.viewport));
|
||||||
renderShadowBuffers(ri);
|
renderShadowBuffers(ri);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ void KRModel::render(KRNode::RenderInfo& ri)
|
|||||||
&& ri.renderPass->getType() != RenderPassType::RENDER_PASS_ADDITIVE_PARTICLES
|
&& ri.renderPass->getType() != RenderPassType::RENDER_PASS_ADDITIVE_PARTICLES
|
||||||
&& ri.renderPass->getType() != RenderPassType::RENDER_PASS_PARTICLE_OCCLUSION
|
&& ri.renderPass->getType() != RenderPassType::RENDER_PASS_PARTICLE_OCCLUSION
|
||||||
&& ri.renderPass->getType()!= RenderPassType::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE
|
&& ri.renderPass->getType()!= RenderPassType::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE
|
||||||
&& ri.renderPass->getType() != RenderPassType::RENDER_PASS_GENERATE_SHADOWMAPS
|
&& ri.renderPass->getType() != RenderPassType::RENDER_PASS_SHADOWMAP
|
||||||
&& ri.renderPass->getType() != RenderPassType::RENDER_PASS_PRESTREAM) {
|
&& ri.renderPass->getType() != RenderPassType::RENDER_PASS_PRESTREAM) {
|
||||||
loadModel();
|
loadModel();
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ void KRModel::render(KRNode::RenderInfo& ri)
|
|||||||
m_pLightMap = getContext().getTextureManager()->getTexture(m_lightMap);
|
m_pLightMap = getContext().getTextureManager()->getTexture(m_lightMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pLightMap && ri.camera->settings.bEnableLightMap && ri.renderPass->getType() != RENDER_PASS_SHADOWMAP && ri.renderPass->getType() != RENDER_PASS_GENERATE_SHADOWMAPS) {
|
if (m_pLightMap && ri.camera->settings.bEnableLightMap && ri.renderPass->getType() != RENDER_PASS_SHADOWMAP && ri.renderPass->getType() != RENDER_PASS_SHADOWMAP) {
|
||||||
m_pLightMap->resetPoolExpiry(lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP);
|
m_pLightMap->resetPoolExpiry(lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP);
|
||||||
// TODO - Vulkan refactoring. We need to bind the shadow map in KRMesh::Render
|
// TODO - Vulkan refactoring. We need to bind the shadow map in KRMesh::Render
|
||||||
// m_pContext->getTextureManager()->selectTexture(5, m_pLightMap, lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP);
|
// m_pContext->getTextureManager()->selectTexture(5, m_pLightMap, lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP);
|
||||||
|
|||||||
@@ -662,7 +662,7 @@ bool KRPipeline::bind(VkCommandBuffer& commandBuffer, KRCamera& camera, const KR
|
|||||||
//int light_point_count = 0;
|
//int light_point_count = 0;
|
||||||
//int light_spot_count = 0;
|
//int light_spot_count = 0;
|
||||||
// TODO - Need to support multiple lights and more light types in forward rendering
|
// TODO - Need to support multiple lights and more light types in forward rendering
|
||||||
if (renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_LIGHTS && renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_GBUFFER && renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_OPAQUE && renderPass->getType() != RenderPassType::RENDER_PASS_GENERATE_SHADOWMAPS) {
|
if (renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_LIGHTS && renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_GBUFFER && renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_OPAQUE && renderPass->getType() != RenderPassType::RENDER_PASS_SHADOWMAP) {
|
||||||
|
|
||||||
|
|
||||||
if (directional_lights) {
|
if (directional_lights) {
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ KRPipeline *KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInf
|
|||||||
int light_directional_count = 0;
|
int light_directional_count = 0;
|
||||||
int light_point_count = 0;
|
int light_point_count = 0;
|
||||||
int light_spot_count = 0;
|
int light_spot_count = 0;
|
||||||
if(info.renderPass != RenderPassType::RENDER_PASS_DEFERRED_LIGHTS && info.renderPass != RenderPassType::RENDER_PASS_DEFERRED_GBUFFER && info.renderPass != RenderPassType::RENDER_PASS_DEFERRED_OPAQUE && info.renderPass != RenderPassType::RENDER_PASS_GENERATE_SHADOWMAPS) {
|
if(info.renderPass != RenderPassType::RENDER_PASS_DEFERRED_LIGHTS && info.renderPass != RenderPassType::RENDER_PASS_DEFERRED_GBUFFER && info.renderPass != RenderPassType::RENDER_PASS_DEFERRED_OPAQUE && info.renderPass != RenderPassType::RENDER_PASS_SHADOWMAP) {
|
||||||
if (info.directional_lights) {
|
if (info.directional_lights) {
|
||||||
light_directional_count = (int)info.directional_lights->size();
|
light_directional_count = (int)info.directional_lights->size();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,17 +44,103 @@ KRRenderGraph::~KRRenderGraph()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int KRRenderGraph::addAttachment(const char* name, VkFormat format)
|
||||||
|
{
|
||||||
|
AttachmentInfo& attachment = m_attachments.emplace_back(AttachmentInfo{});
|
||||||
|
strncpy(attachment.name, name, RENDER_PASS_ATTACHMENT_NAME_LENGTH);
|
||||||
|
attachment.format = format;
|
||||||
|
|
||||||
|
return static_cast<int>(m_attachments.size());
|
||||||
|
}
|
||||||
|
|
||||||
void KRRenderGraph::addRenderPass(KRDevice& device, const RenderPassInfo& info)
|
void KRRenderGraph::addRenderPass(KRDevice& device, const RenderPassInfo& info)
|
||||||
{
|
{
|
||||||
KRRenderPass &pass = m_renderPasses.emplace_back(getContext());
|
int attachmentCount = 0;
|
||||||
pass.create(device, info);
|
std::array<VkAttachmentDescription, RENDER_PASS_ATTACHMENT_MAX_COUNT> passAttachments{};
|
||||||
|
|
||||||
|
if (info.depthAttachment.id != 0) {
|
||||||
|
VkAttachmentDescription& depthAttachment = passAttachments[attachmentCount++];
|
||||||
|
|
||||||
|
depthAttachment.format = m_attachments[info.depthAttachment.id - 1].format;
|
||||||
|
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
depthAttachment.loadOp = info.depthAttachment.loadOp;
|
||||||
|
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
depthAttachment.stencilLoadOp = info.depthAttachment.stencilLoadOp;
|
||||||
|
depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
depthAttachment.initialLayout = (info.depthAttachment.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<RENDER_PASS_ATTACHMENT_MAX_COUNT; i++) {
|
||||||
|
const RenderPassAttachmentInfo& attachmentInfo = info.colorAttachments[i];
|
||||||
|
if (attachmentInfo.id == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkAttachmentDescription& colorAttachment = passAttachments[attachmentCount++];
|
||||||
|
colorAttachment.format = m_attachments[attachmentInfo.id - 1].format;
|
||||||
|
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
colorAttachment.loadOp = attachmentInfo.loadOp;
|
||||||
|
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
colorAttachment.initialLayout = (attachmentInfo.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
if (info.finalPass) {
|
||||||
|
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
} else {
|
||||||
|
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkAttachmentReference depthAttachmentRef{};
|
||||||
|
depthAttachmentRef.attachment = 0;
|
||||||
|
depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentReference colorAttachmentRef[RENDER_PASS_ATTACHMENT_MAX_COUNT]{};
|
||||||
|
for(int i=0; i < RENDER_PASS_ATTACHMENT_MAX_COUNT; i++) {
|
||||||
|
colorAttachmentRef[i].attachment = i;
|
||||||
|
colorAttachmentRef[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSubpassDescription subpass{};
|
||||||
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
subpass.colorAttachmentCount = attachmentCount;
|
||||||
|
subpass.pColorAttachments = colorAttachmentRef;
|
||||||
|
if (info.depthAttachment.id != 0) {
|
||||||
|
subpass.pDepthStencilAttachment = &depthAttachmentRef;
|
||||||
|
subpass.colorAttachmentCount--;
|
||||||
|
subpass.pColorAttachments++;
|
||||||
|
} else {
|
||||||
|
subpass.pDepthStencilAttachment = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSubpassDependency dependency{};
|
||||||
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
dependency.dstSubpass = 0;
|
||||||
|
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||||
|
dependency.srcAccessMask = 0;
|
||||||
|
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||||
|
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
|
|
||||||
|
VkRenderPassCreateInfo renderPassInfo{};
|
||||||
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
|
renderPassInfo.attachmentCount = attachmentCount;
|
||||||
|
renderPassInfo.pAttachments = passAttachments.data();
|
||||||
|
renderPassInfo.subpassCount = 1;
|
||||||
|
renderPassInfo.pSubpasses = &subpass;
|
||||||
|
renderPassInfo.dependencyCount = 1;
|
||||||
|
renderPassInfo.pDependencies = &dependency;
|
||||||
|
|
||||||
|
KRRenderPass *pass = new KRRenderPass(getContext());
|
||||||
|
pass->create(device, info, renderPassInfo);
|
||||||
|
m_renderPasses.push_back(pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
KRRenderPass* KRRenderGraph::getRenderPass(RenderPassType type)
|
KRRenderPass* KRRenderGraph::getRenderPass(RenderPassType type)
|
||||||
{
|
{
|
||||||
for(KRRenderPass& pass : m_renderPasses) {
|
for(KRRenderPass* pass : m_renderPasses) {
|
||||||
if (pass.getType() == type) {
|
if (pass->getType() == type) {
|
||||||
return &pass;
|
return pass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -62,16 +148,18 @@ KRRenderPass* KRRenderGraph::getRenderPass(RenderPassType type)
|
|||||||
|
|
||||||
void KRRenderGraph::render(VkCommandBuffer &commandBuffer, KRSurface& surface)
|
void KRRenderGraph::render(VkCommandBuffer &commandBuffer, KRSurface& surface)
|
||||||
{
|
{
|
||||||
for(KRRenderPass& pass : m_renderPasses) {
|
for(KRRenderPass* pass : m_renderPasses) {
|
||||||
pass.begin(commandBuffer, surface);
|
pass->begin(commandBuffer, surface);
|
||||||
pass.end(commandBuffer);
|
pass->end(commandBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRRenderGraph::destroy(KRDevice& device)
|
void KRRenderGraph::destroy(KRDevice& device)
|
||||||
{
|
{
|
||||||
for(KRRenderPass& pass : m_renderPasses) {
|
for(KRRenderPass* pass : m_renderPasses) {
|
||||||
pass.destroy(device);
|
pass->destroy(device);
|
||||||
|
delete pass;
|
||||||
}
|
}
|
||||||
m_renderPasses.clear();
|
m_renderPasses.clear();
|
||||||
|
m_attachments.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,12 +42,15 @@ class KRDevice;
|
|||||||
struct RenderPassInfo;
|
struct RenderPassInfo;
|
||||||
enum RenderPassType : uint8_t;
|
enum RenderPassType : uint8_t;
|
||||||
|
|
||||||
|
#define RENDER_PASS_ATTACHMENT_NAME_LENGTH 64
|
||||||
|
|
||||||
class KRRenderGraph : public KRContextObject
|
class KRRenderGraph : public KRContextObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
KRRenderGraph(KRContext& context);
|
KRRenderGraph(KRContext& context);
|
||||||
~KRRenderGraph();
|
~KRRenderGraph();
|
||||||
|
|
||||||
|
int addAttachment(const char* name, VkFormat format);
|
||||||
void addRenderPass(KRDevice& device, const RenderPassInfo& info);
|
void addRenderPass(KRDevice& device, const RenderPassInfo& info);
|
||||||
KRRenderPass* getRenderPass(RenderPassType type);
|
KRRenderPass* getRenderPass(RenderPassType type);
|
||||||
void render(VkCommandBuffer &commandBuffer, KRSurface& surface);
|
void render(VkCommandBuffer &commandBuffer, KRSurface& surface);
|
||||||
@@ -55,6 +58,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::list<KRRenderPass> m_renderPasses;
|
struct AttachmentInfo
|
||||||
|
{
|
||||||
|
char name[RENDER_PASS_ATTACHMENT_NAME_LENGTH];
|
||||||
|
VkFormat format;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<AttachmentInfo> m_attachments;
|
||||||
|
std::vector<KRRenderPass*> m_renderPasses;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,72 +48,12 @@ KRRenderPass::~KRRenderPass()
|
|||||||
assert(m_renderPass == VK_NULL_HANDLE);
|
assert(m_renderPass == VK_NULL_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRRenderPass::create(KRDevice& device, const RenderPassInfo& info)
|
void KRRenderPass::create(KRDevice& device, const RenderPassInfo& info, const VkRenderPassCreateInfo& createInfo)
|
||||||
{
|
{
|
||||||
if (m_renderPass) {
|
assert(m_renderPass == VK_NULL_HANDLE);
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_info = info;
|
m_info = info;
|
||||||
|
|
||||||
VkAttachmentDescription colorAttachment{};
|
if (vkCreateRenderPass(device.m_logicalDevice, &createInfo, nullptr, &m_renderPass) != VK_SUCCESS) {
|
||||||
colorAttachment.format = info.colorFormat;
|
|
||||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
colorAttachment.loadOp = info.clearColor ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
||||||
colorAttachment.storeOp = info.keepColor ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
||||||
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
||||||
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
||||||
colorAttachment.initialLayout = info.clearColor ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
||||||
if (info.finalPass) {
|
|
||||||
colorAttachment.finalLayout = info.keepColor ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR : VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
} else {
|
|
||||||
colorAttachment.finalLayout = info.keepColor ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkAttachmentDescription depthAttachment{};
|
|
||||||
depthAttachment.format = info.depthStencilFormat;
|
|
||||||
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
depthAttachment.loadOp = info.clearDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
||||||
depthAttachment.storeOp = info.keepDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
||||||
depthAttachment.stencilLoadOp = info.clearStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
||||||
depthAttachment.stencilStoreOp = info.keepStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
||||||
depthAttachment.initialLayout = info.clearDepth ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
||||||
depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
||||||
|
|
||||||
VkAttachmentReference depthAttachmentRef{};
|
|
||||||
depthAttachmentRef.attachment = 1;
|
|
||||||
depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
||||||
|
|
||||||
VkAttachmentReference colorAttachmentRef{};
|
|
||||||
colorAttachmentRef.attachment = 0;
|
|
||||||
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
||||||
|
|
||||||
VkSubpassDescription subpass{};
|
|
||||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
|
||||||
subpass.colorAttachmentCount = 1;
|
|
||||||
subpass.pColorAttachments = &colorAttachmentRef;
|
|
||||||
subpass.pDepthStencilAttachment = &depthAttachmentRef;
|
|
||||||
|
|
||||||
VkSubpassDependency dependency{};
|
|
||||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
|
||||||
dependency.dstSubpass = 0;
|
|
||||||
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
|
||||||
dependency.srcAccessMask = 0;
|
|
||||||
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
|
||||||
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
|
||||||
|
|
||||||
std::array<VkAttachmentDescription, 2> attachments = { colorAttachment, depthAttachment };
|
|
||||||
|
|
||||||
VkRenderPassCreateInfo renderPassInfo{};
|
|
||||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
|
||||||
renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
|
|
||||||
renderPassInfo.pAttachments = attachments.data();
|
|
||||||
renderPassInfo.subpassCount = 1;
|
|
||||||
renderPassInfo.pSubpasses = &subpass;
|
|
||||||
renderPassInfo.dependencyCount = 1;
|
|
||||||
renderPassInfo.pDependencies = &dependency;
|
|
||||||
|
|
||||||
if (vkCreateRenderPass(device.m_logicalDevice, &renderPassInfo, nullptr, &m_renderPass) != VK_SUCCESS) {
|
|
||||||
// failed! TODO - Error handling
|
// failed! TODO - Error handling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,13 +68,18 @@ void KRRenderPass::destroy(KRDevice& device)
|
|||||||
|
|
||||||
void KRRenderPass::begin(VkCommandBuffer& commandBuffer, KRSurface& surface)
|
void KRRenderPass::begin(VkCommandBuffer& commandBuffer, KRSurface& surface)
|
||||||
{
|
{
|
||||||
std::array<VkClearValue, 2> clearValues{};
|
int attachmentCount = 0;
|
||||||
clearValues[0].color.float32[0] = m_info.clearColorValue[0];
|
std::array<VkClearValue, RENDER_PASS_ATTACHMENT_MAX_COUNT> clearValues{};
|
||||||
clearValues[0].color.float32[1] = m_info.clearColorValue[1];
|
if (m_info.depthAttachment.id != 0) {
|
||||||
clearValues[0].color.float32[2] = m_info.clearColorValue[2];
|
clearValues[attachmentCount] = m_info.depthAttachment.clearVaue;
|
||||||
clearValues[0].color.float32[3] = m_info.clearColorValue[3];
|
attachmentCount++;
|
||||||
clearValues[1].depthStencil.depth = m_info.clearDepthValue;
|
}
|
||||||
clearValues[1].depthStencil.stencil = m_info.clearStencilValue;
|
for(int i=0; i < RENDER_PASS_ATTACHMENT_MAX_COUNT; i++) {
|
||||||
|
if(m_info.colorAttachments[i].id != 0) {
|
||||||
|
clearValues[attachmentCount] = m_info.colorAttachments[i].clearVaue;
|
||||||
|
attachmentCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VkRenderPassBeginInfo renderPassInfo{};
|
VkRenderPassBeginInfo renderPassInfo{};
|
||||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
@@ -142,7 +87,7 @@ void KRRenderPass::begin(VkCommandBuffer& commandBuffer, KRSurface& surface)
|
|||||||
renderPassInfo.framebuffer = surface.m_swapChain->m_framebuffers[surface.m_frameIndex % surface.m_swapChain->m_framebuffers.size()];
|
renderPassInfo.framebuffer = surface.m_swapChain->m_framebuffers[surface.m_frameIndex % surface.m_swapChain->m_framebuffers.size()];
|
||||||
renderPassInfo.renderArea.offset = { 0, 0 };
|
renderPassInfo.renderArea.offset = { 0, 0 };
|
||||||
renderPassInfo.renderArea.extent = surface.m_swapChain->m_extent;
|
renderPassInfo.renderArea.extent = surface.m_swapChain->m_extent;
|
||||||
renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
|
renderPassInfo.clearValueCount = attachmentCount;
|
||||||
renderPassInfo.pClearValues = clearValues.data();
|
renderPassInfo.pClearValues = clearValues.data();
|
||||||
|
|
||||||
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ enum RenderPassType : uint8_t
|
|||||||
RENDER_PASS_PARTICLE_OCCLUSION,
|
RENDER_PASS_PARTICLE_OCCLUSION,
|
||||||
RENDER_PASS_ADDITIVE_PARTICLES,
|
RENDER_PASS_ADDITIVE_PARTICLES,
|
||||||
RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE,
|
RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE,
|
||||||
RENDER_PASS_GENERATE_SHADOWMAPS,
|
|
||||||
RENDER_PASS_SHADOWMAP,
|
RENDER_PASS_SHADOWMAP,
|
||||||
RENDER_PASS_PRESTREAM,
|
RENDER_PASS_PRESTREAM,
|
||||||
RENDER_PASS_POST_COMPOSITE,
|
RENDER_PASS_POST_COMPOSITE,
|
||||||
@@ -54,23 +53,21 @@ enum RenderPassType : uint8_t
|
|||||||
RENDER_PASS_BLACK_FRAME,
|
RENDER_PASS_BLACK_FRAME,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RENDER_PASS_ATTACHMENT_MAX_COUNT 16
|
||||||
|
|
||||||
|
struct RenderPassAttachmentInfo
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
VkAttachmentLoadOp loadOp;
|
||||||
|
VkAttachmentLoadOp stencilLoadOp;
|
||||||
|
VkClearValue clearVaue;
|
||||||
|
};
|
||||||
|
|
||||||
struct RenderPassInfo
|
struct RenderPassInfo
|
||||||
{
|
{
|
||||||
RenderPassType type;
|
RenderPassType type;
|
||||||
bool clearColor;
|
RenderPassAttachmentInfo colorAttachments[RENDER_PASS_ATTACHMENT_MAX_COUNT];
|
||||||
bool keepColor;
|
RenderPassAttachmentInfo depthAttachment;
|
||||||
hydra::Vector4 clearColorValue;
|
|
||||||
VkFormat colorFormat;
|
|
||||||
|
|
||||||
bool clearDepth;
|
|
||||||
bool keepDepth;
|
|
||||||
float clearDepthValue;
|
|
||||||
|
|
||||||
bool clearStencil;
|
|
||||||
bool keepStencil;
|
|
||||||
uint32_t clearStencilValue;
|
|
||||||
|
|
||||||
VkFormat depthStencilFormat;
|
|
||||||
|
|
||||||
bool finalPass;
|
bool finalPass;
|
||||||
};
|
};
|
||||||
@@ -82,7 +79,7 @@ public:
|
|||||||
KRRenderPass(KRContext& context);
|
KRRenderPass(KRContext& context);
|
||||||
~KRRenderPass();
|
~KRRenderPass();
|
||||||
|
|
||||||
void create(KRDevice& device, const RenderPassInfo& info);
|
void create(KRDevice& device, const RenderPassInfo& m_info, const VkRenderPassCreateInfo& info);
|
||||||
void destroy(KRDevice& device);
|
void destroy(KRDevice& device);
|
||||||
|
|
||||||
void begin(VkCommandBuffer& commandBuffer, KRSurface& surface);
|
void begin(VkCommandBuffer& commandBuffer, KRSurface& surface);
|
||||||
|
|||||||
@@ -171,70 +171,133 @@ KrResult KRSurface::createSwapChain()
|
|||||||
imageCount = surfaceCapabilities.maxImageCount;
|
imageCount = surfaceCapabilities.maxImageCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----- Configuration -----
|
||||||
|
int shadow_buffer_count = 0;
|
||||||
|
bool enable_deferred_lighting = false;
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
int attachment_compositeDepth = m_renderGraph->addAttachment("Composite Depth", depthImageFormat);
|
||||||
|
int attachment_compositeColor = m_renderGraph->addAttachment("Composite Color", selectedSurfaceFormat.format);
|
||||||
|
int attachment_lightAccumulation = m_renderGraph->addAttachment("Light Accumulation", VK_FORMAT_B8G8R8A8_UINT);
|
||||||
|
int attachment_gbuffer = m_renderGraph->addAttachment("GBuffer", VK_FORMAT_B8G8R8A8_UINT);
|
||||||
|
int attachment_shadow_cascades[3];
|
||||||
|
attachment_shadow_cascades[0] = m_renderGraph->addAttachment("Shadow Cascade 0", VK_FORMAT_D32_SFLOAT);
|
||||||
|
attachment_shadow_cascades[1] = m_renderGraph->addAttachment("Shadow Cascade 1", VK_FORMAT_D32_SFLOAT);
|
||||||
|
attachment_shadow_cascades[2] = m_renderGraph->addAttachment("Shadow Cascade 2", VK_FORMAT_D32_SFLOAT);
|
||||||
|
|
||||||
RenderPassInfo info{};
|
RenderPassInfo info{};
|
||||||
info.clearColor = true;
|
|
||||||
info.keepColor = true;
|
|
||||||
info.clearColorValue = Vector4::Zero();
|
|
||||||
info.colorFormat = selectedSurfaceFormat.format;
|
|
||||||
|
|
||||||
info.clearDepth = true;
|
|
||||||
info.keepDepth = true;
|
|
||||||
info.clearDepthValue = 1.0f;
|
|
||||||
|
|
||||||
info.clearStencil = true;
|
|
||||||
info.keepStencil = true;
|
|
||||||
info.clearStencilValue = 0;
|
|
||||||
info.depthStencilFormat = depthImageFormat;
|
|
||||||
|
|
||||||
info.finalPass = false;
|
info.finalPass = false;
|
||||||
info.type = RenderPassType::RENDER_PASS_FORWARD_OPAQUE;
|
|
||||||
|
// info.type = RenderPassType::RENDER_PASS_PRESTREAM;
|
||||||
|
// m_renderGraph->addRenderPass(*device, info);
|
||||||
|
|
||||||
|
for (int shadow_index = 0; shadow_index < shadow_buffer_count; shadow_index++) {
|
||||||
|
info.depthAttachment.id = attachment_shadow_cascades[shadow_index];
|
||||||
|
info.depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
info.depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
info.depthAttachment.clearVaue.depthStencil.depth = 1.0f;
|
||||||
|
info.depthAttachment.clearVaue.depthStencil.stencil = 0;
|
||||||
|
info.type = RenderPassType::RENDER_PASS_SHADOWMAP;
|
||||||
|
m_renderGraph->addRenderPass(*device, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable_deferred_lighting) {
|
||||||
|
// ----====---- Opaque Geometry, Deferred rendering Pass 1 ----====----
|
||||||
|
|
||||||
|
info.depthAttachment.id = attachment_compositeDepth;
|
||||||
|
info.depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
info.depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
info.depthAttachment.clearVaue.depthStencil.depth = 1.0f;
|
||||||
|
info.depthAttachment.clearVaue.depthStencil.stencil = 0;
|
||||||
|
|
||||||
|
info.colorAttachments[0].id = attachment_compositeColor;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[0] = 0.0f;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[1] = 0.0f;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[2] = 0.0f;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[3] = 0.0f;
|
||||||
|
info.colorAttachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
info.colorAttachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
info.type = RenderPassType::RENDER_PASS_DEFERRED_GBUFFER;
|
||||||
|
m_renderGraph->addRenderPass(*device, info);
|
||||||
|
|
||||||
|
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
|
||||||
|
|
||||||
|
info.depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
|
info.colorAttachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
|
|
||||||
|
info.colorAttachments[1].id = attachment_lightAccumulation;
|
||||||
|
info.colorAttachments[1].clearVaue.color.float32[0] = 0.0f;
|
||||||
|
info.colorAttachments[1].clearVaue.color.float32[1] = 0.0f;
|
||||||
|
info.colorAttachments[1].clearVaue.color.float32[2] = 0.0f;
|
||||||
|
info.colorAttachments[1].clearVaue.color.float32[3] = 0.0f;
|
||||||
|
info.colorAttachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
info.colorAttachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
info.type = RenderPassType::RENDER_PASS_DEFERRED_LIGHTS;
|
||||||
|
m_renderGraph->addRenderPass(*device, info);
|
||||||
|
|
||||||
|
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
|
||||||
|
info.colorAttachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
info.colorAttachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
|
info.type = RenderPassType::RENDER_PASS_DEFERRED_OPAQUE;
|
||||||
|
m_renderGraph->addRenderPass(*device, info);
|
||||||
|
|
||||||
|
info.colorAttachments[1] = {};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// !enable_deferred_lighting
|
||||||
|
|
||||||
|
// ----====---- Opaque Geometry, Forward Rendering ----====----
|
||||||
|
info.depthAttachment.id = attachment_compositeDepth;
|
||||||
|
info.depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
info.depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
info.depthAttachment.clearVaue.depthStencil.depth = 1.0f;
|
||||||
|
info.depthAttachment.clearVaue.depthStencil.stencil = 0;
|
||||||
|
|
||||||
|
info.colorAttachments[0].id = attachment_compositeColor;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[0] = 0.0f;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[1] = 0.0f;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[2] = 0.0f;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[3] = 0.0f;
|
||||||
|
info.colorAttachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
info.colorAttachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
|
||||||
|
info.type = RenderPassType::RENDER_PASS_FORWARD_OPAQUE;
|
||||||
|
m_renderGraph->addRenderPass(*device, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----====---- Transparent Geometry, Forward Rendering ----====----
|
||||||
|
info.depthAttachment.id = attachment_compositeDepth;
|
||||||
|
info.depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
info.depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
|
info.depthAttachment.clearVaue.depthStencil.depth = 1.0f;
|
||||||
|
info.depthAttachment.clearVaue.depthStencil.stencil = 0;
|
||||||
|
|
||||||
|
info.colorAttachments[0].id = attachment_compositeColor;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[0] = 0.0f;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[1] = 0.0f;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[2] = 0.0f;
|
||||||
|
info.colorAttachments[0].clearVaue.color.float32[3] = 0.0f;
|
||||||
|
info.colorAttachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
|
info.colorAttachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
|
||||||
|
info.type = RenderPassType::RENDER_PASS_FORWARD_TRANSPARENT;
|
||||||
m_renderGraph->addRenderPass(*device, info);
|
m_renderGraph->addRenderPass(*device, info);
|
||||||
|
|
||||||
info.clearColor = true;
|
|
||||||
info.keepColor = true;
|
|
||||||
info.clearDepth = true;
|
|
||||||
info.keepDepth = true;
|
|
||||||
info.finalPass = false;
|
|
||||||
info.type = RenderPassType::RENDER_PASS_DEFERRED_GBUFFER;
|
|
||||||
m_renderGraph->addRenderPass(*device, info);
|
|
||||||
|
|
||||||
info.clearColor = false;
|
|
||||||
info.keepColor = true;
|
|
||||||
info.clearDepth = false;
|
|
||||||
info.keepDepth = true;
|
|
||||||
info.finalPass = false;
|
|
||||||
info.type = RenderPassType::RENDER_PASS_DEFERRED_LIGHTS;
|
|
||||||
m_renderGraph->addRenderPass(*device, info);
|
|
||||||
|
|
||||||
info.clearColor = false;
|
|
||||||
info.keepColor = true;
|
|
||||||
info.clearDepth = false;
|
|
||||||
info.keepDepth = true;
|
|
||||||
info.finalPass = false;
|
|
||||||
info.type = RenderPassType::RENDER_PASS_DEFERRED_OPAQUE;
|
|
||||||
m_renderGraph->addRenderPass(*device, info);
|
|
||||||
|
|
||||||
info.clearColor = false;
|
|
||||||
info.keepColor = true;
|
|
||||||
info.clearDepth = false;
|
|
||||||
info.keepDepth = true;
|
|
||||||
info.finalPass = false;
|
|
||||||
info.type = RenderPassType::RENDER_PASS_DEBUG_OVERLAYS;
|
info.type = RenderPassType::RENDER_PASS_DEBUG_OVERLAYS;
|
||||||
m_renderGraph->addRenderPass(*device, info);
|
m_renderGraph->addRenderPass(*device, info);
|
||||||
|
|
||||||
info.clearColor = false;
|
|
||||||
info.keepColor = true;
|
|
||||||
info.clearDepth = false;
|
|
||||||
info.keepDepth = false;
|
|
||||||
info.finalPass = true;
|
info.finalPass = true;
|
||||||
info.type = RenderPassType::RENDER_PASS_POST_COMPOSITE;
|
info.type = RenderPassType::RENDER_PASS_POST_COMPOSITE;
|
||||||
m_renderGraph->addRenderPass(*device, info);
|
m_renderGraph->addRenderPass(*device, info);
|
||||||
|
|
||||||
info.clearColor = true;
|
|
||||||
info.keepColor = true;
|
int attachment_blackFrameDepth = m_blackFrameRenderGraph->addAttachment("Composite Depth", depthImageFormat);
|
||||||
info.clearDepth = true;
|
int attachment_blackFrameColor = m_blackFrameRenderGraph->addAttachment("Composite Color", selectedSurfaceFormat.format);
|
||||||
info.keepDepth = false;
|
|
||||||
|
info.colorAttachments[0].id = attachment_blackFrameColor;
|
||||||
|
info.colorAttachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
info.depthAttachment.id = attachment_blackFrameDepth;
|
||||||
|
info.depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
info.finalPass = true;
|
info.finalPass = true;
|
||||||
info.type = RenderPassType::RENDER_PASS_BLACK_FRAME;
|
info.type = RenderPassType::RENDER_PASS_BLACK_FRAME;
|
||||||
m_blackFrameRenderGraph->addRenderPass(*device, info);
|
m_blackFrameRenderGraph->addRenderPass(*device, info);
|
||||||
|
|||||||
@@ -180,8 +180,8 @@ KrResult KRSwapchain::create(KRDevice& device, VkSurfaceKHR& surface, VkSurfaceF
|
|||||||
|
|
||||||
for (size_t i = 0; i < m_imageViews.size(); i++) {
|
for (size_t i = 0; i < m_imageViews.size(); i++) {
|
||||||
std::array<VkImageView, 2> attachments = {
|
std::array<VkImageView, 2> attachments = {
|
||||||
m_imageViews[i],
|
m_depthImageView,
|
||||||
m_depthImageView
|
m_imageViews[i]
|
||||||
};
|
};
|
||||||
|
|
||||||
VkFramebufferCreateInfo framebufferInfo{};
|
VkFramebufferCreateInfo framebufferInfo{};
|
||||||
|
|||||||
Reference in New Issue
Block a user