Skip to content

Commit dfcac42

Browse files
authored
make ClearRenderTarget and ClearDepthStencil work with dynamic rendering (#414)
For issue #408 ClearRenderTarget and ClearDepthStencil now work within a dynamic render pass. RenderArea is now saved directly in BeginRendering. DynamicRendering sample is updated to call both these functions. These functions still work in the Cube sample as well (for a non dynamic rendering example).
1 parent df7b4ca commit dfcac42

File tree

4 files changed

+88
-30
lines changed

4 files changed

+88
-30
lines changed

include/ppx/grfx/grfx_command.h

+15-4
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,20 @@ class CommandBuffer
582582
//
583583
void Draw(const grfx::FullscreenQuad* pQuad, uint32_t setCount, const grfx::DescriptorSet* const* ppSets);
584584

585+
protected:
586+
struct DynamicRenderPassInfo
587+
{
588+
grfx::Rect mRenderArea = {};
589+
std::vector<grfx::RenderTargetViewPtr> mRenderTargetViews = {};
590+
grfx::DepthStencilViewPtr mDepthStencilView = nullptr;
591+
};
592+
593+
// Returns true when inside a render pass (dynamic or regular)
594+
bool HasActiveRenderPass() const;
595+
596+
bool mDynamicRenderPassActive = false;
597+
DynamicRenderPassInfo mDynamicRenderPassInfo = {};
598+
585599
private:
586600
virtual void BeginRenderPassImpl(const grfx::RenderPassBeginInfo* pBeginInfo) = 0;
587601
virtual void EndRenderPassImpl() = 0;
@@ -601,10 +615,7 @@ class CommandBuffer
601615
const grfx::StorageImageView* pStorageImageView,
602616
const grfx::Sampler* pSampler) = 0;
603617

604-
bool HasActiveRenderPass() const;
605-
606-
const grfx::RenderPass* mCurrentRenderPass = nullptr;
607-
bool mDynamicRenderPassActive = false;
618+
const grfx::RenderPass* mCurrentRenderPass = nullptr;
608619
};
609620

610621
} // namespace grfx

projects/dynamic_rendering/DynamicRendering.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,9 @@ void DynamicRenderingApp::Setup()
126126
grfx::RenderingInfo renderingInfo = {};
127127
renderingInfo.flags.bits.suspending = true;
128128
renderingInfo.renderArea = {0, 0, swapchain->GetWidth(), swapchain->GetHeight()};
129-
renderingInfo.RTVClearValues[0] = {{0.7f, 0.7f, 0.7f, 1.0f}};
130-
renderingInfo.DSVClearValue = {1.0f, 0xFF};
131129
renderingInfo.renderTargetCount = 1;
132-
renderingInfo.pRenderTargetViews[0] = swapchain->GetRenderTargetView(imageIndex, grfx::AttachmentLoadOp::ATTACHMENT_LOAD_OP_CLEAR);
130+
// There will be an explicit clear inside a renderpass.
131+
renderingInfo.pRenderTargetViews[0] = swapchain->GetRenderTargetView(imageIndex, grfx::AttachmentLoadOp::ATTACHMENT_LOAD_OP_LOAD);
133132
renderingInfo.pDepthStencilView = swapchain->GetDepthStencilView(imageIndex);
134133

135134
float4x4 P = glm::perspective(glm::radians(60.0f), GetWindowAspect(), 0.001f, 10000.0f);
@@ -139,6 +138,10 @@ void DynamicRenderingApp::Setup()
139138

140139
preRecordedCmd->BeginRendering(&renderingInfo);
141140
{
141+
grfx::RenderTargetClearValue rtvClearValue = {0.7f, 0.7f, 0.7f, 1.0f};
142+
grfx::DepthStencilClearValue dsvClearValue = {1.0f, 0xFF};
143+
preRecordedCmd->ClearRenderTarget(swapchain->GetColorImage(imageIndex), rtvClearValue);
144+
preRecordedCmd->ClearDepthStencil(swapchain->GetDepthImage(imageIndex), dsvClearValue, grfx::CLEAR_FLAG_DEPTH);
142145
preRecordedCmd->SetScissors(GetScissor());
143146
preRecordedCmd->SetViewports(GetViewport());
144147
preRecordedCmd->PushGraphicsConstants(mPipelineInterface, 16, &mat);

src/ppx/grfx/grfx_command.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,14 @@ void CommandBuffer::BeginRendering(const grfx::RenderingInfo* pRenderingInfo)
7070
PPX_ASSERT_MSG(!HasActiveRenderPass(), "cannot nest render passes");
7171

7272
BeginRenderingImpl(pRenderingInfo);
73-
mDynamicRenderPassActive = true;
73+
mDynamicRenderPassActive = true;
74+
mDynamicRenderPassInfo.mRenderArea = pRenderingInfo->renderArea;
75+
auto views = pRenderingInfo->pRenderTargetViews;
76+
for (uint32_t i = 0; i < pRenderingInfo->renderTargetCount; ++i) {
77+
const grfx::RenderTargetViewPtr& rtv = views[i];
78+
mDynamicRenderPassInfo.mRenderTargetViews.push_back(rtv);
79+
}
80+
mDynamicRenderPassInfo.mDepthStencilView = pRenderingInfo->pDepthStencilView;
7481
}
7582

7683
void CommandBuffer::EndRendering()
@@ -80,6 +87,7 @@ void CommandBuffer::EndRendering()
8087

8188
EndRenderingImpl();
8289
mDynamicRenderPassActive = false;
90+
mDynamicRenderPassInfo = {};
8391
}
8492

8593
void CommandBuffer::BeginRenderPass(const grfx::RenderPass* pRenderPass)

src/ppx/grfx/vk/vk_command.cpp

+58-22
Original file line numberDiff line numberDiff line change
@@ -290,36 +290,62 @@ void CommandBuffer::ClearRenderTarget(
290290
grfx::Image* pImage,
291291
const grfx::RenderTargetClearValue& clearValue)
292292
{
293-
auto pCurrentRenderPass = GetCurrentRenderPass();
294-
if (IsNull(pCurrentRenderPass)) {
293+
if (!HasActiveRenderPass()) {
294+
PPX_LOG_WARN("No active render pass.");
295295
return;
296296
}
297297

298-
// Make sure pImage is a render target in current render pass
299-
const uint32_t renderTargetIndex = pCurrentRenderPass->GetRenderTargetImageIndex(pImage);
300-
if (renderTargetIndex == UINT32_MAX) {
301-
return;
298+
grfx::Rect renderArea;
299+
uint32_t colorAttachment = UINT32_MAX;
300+
uint32_t baseArrayLayer;
301+
302+
// Dynamic render pass
303+
if (mDynamicRenderPassActive) {
304+
renderArea = mDynamicRenderPassInfo.mRenderArea;
305+
306+
auto views = mDynamicRenderPassInfo.mRenderTargetViews;
307+
for (uint32_t i = 0; i < views.size(); ++i) {
308+
auto rtv = views[i];
309+
auto image = rtv->GetImage();
310+
if (image.Get() == pImage) {
311+
colorAttachment = i;
312+
baseArrayLayer = rtv->GetArrayLayer();
313+
break;
314+
}
315+
}
302316
}
317+
else {
318+
// active regular render pass
319+
auto pCurrentRenderPass = GetCurrentRenderPass();
320+
renderArea = pCurrentRenderPass->GetRenderArea();
321+
322+
// Make sure pImage is a render target in current render pass
323+
const uint32_t renderTargetIndex = pCurrentRenderPass->GetRenderTargetImageIndex(pImage);
324+
colorAttachment = renderTargetIndex;
303325

304-
// Get view at renderTargetIndex
305-
auto view = pCurrentRenderPass->GetRenderTargetView(renderTargetIndex);
326+
auto view = pCurrentRenderPass->GetRenderTargetView(renderTargetIndex);
327+
baseArrayLayer = view->GetArrayLayer();
328+
}
329+
330+
if (colorAttachment == UINT32_MAX) {
331+
PPX_ASSERT_MSG(false, "Passed image is not a render target.");
332+
return;
333+
}
306334

307335
// Clear attachment
308336
VkClearAttachment attachment = {};
309337
attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
310-
attachment.colorAttachment = renderTargetIndex;
338+
attachment.colorAttachment = colorAttachment;
311339
attachment.clearValue.color.float32[0] = clearValue.r;
312340
attachment.clearValue.color.float32[1] = clearValue.g;
313341
attachment.clearValue.color.float32[2] = clearValue.b;
314342
attachment.clearValue.color.float32[3] = clearValue.a;
315343

316344
// Clear rect
317-
auto renderArea = pCurrentRenderPass->GetRenderArea();
318-
319345
VkClearRect clearRect = {};
320346
clearRect.rect.offset = {renderArea.x, renderArea.y};
321347
clearRect.rect.extent = {renderArea.width, renderArea.height};
322-
clearRect.baseArrayLayer = view->GetArrayLayer();
348+
clearRect.baseArrayLayer = baseArrayLayer;
323349
clearRect.layerCount = 1;
324350

325351
vkCmdClearAttachments(
@@ -335,18 +361,30 @@ void CommandBuffer::ClearDepthStencil(
335361
const grfx::DepthStencilClearValue& clearValue,
336362
uint32_t clearFlags)
337363
{
338-
auto pCurrentRenderPass = GetCurrentRenderPass();
339-
if (IsNull(pCurrentRenderPass)) {
364+
if (!HasActiveRenderPass()) {
365+
PPX_LOG_WARN("No active render pass.");
340366
return;
341367
}
342368

343-
// Make sure pImage is depth stencil in current render pass
344-
if (pCurrentRenderPass->GetDepthStencilImage().Get() != pImage) {
345-
return;
369+
grfx::Rect renderArea;
370+
uint32_t baseArrayLayer;
371+
372+
// Dynamic render pass
373+
if (mDynamicRenderPassActive) {
374+
renderArea = mDynamicRenderPassInfo.mRenderArea;
375+
376+
baseArrayLayer = mDynamicRenderPassInfo.mDepthStencilView->GetArrayLayer();
346377
}
378+
else {
379+
// active regular render pass
380+
auto pCurrentRenderPass = GetCurrentRenderPass();
347381

348-
// Get view
349-
auto view = pCurrentRenderPass->GetDepthStencilView();
382+
auto view = pCurrentRenderPass->GetDepthStencilView();
383+
384+
renderArea = pCurrentRenderPass->GetRenderArea();
385+
386+
baseArrayLayer = view->GetArrayLayer();
387+
}
350388

351389
// Aspect mask
352390
VkImageAspectFlags aspectMask = 0;
@@ -364,12 +402,10 @@ void CommandBuffer::ClearDepthStencil(
364402
attachment.clearValue.depthStencil.stencil = clearValue.stencil;
365403

366404
// Clear rect
367-
auto renderArea = pCurrentRenderPass->GetRenderArea();
368-
369405
VkClearRect clearRect = {};
370406
clearRect.rect.offset = {renderArea.x, renderArea.y};
371407
clearRect.rect.extent = {renderArea.width, renderArea.height};
372-
clearRect.baseArrayLayer = view->GetArrayLayer();
408+
clearRect.baseArrayLayer = baseArrayLayer;
373409
clearRect.layerCount = 1;
374410

375411
vkCmdClearAttachments(

0 commit comments

Comments
 (0)