Skip to content

Commit 461efd3

Browse files
committed
Acquire swapchain image and present uploaded image to it
1 parent 54bf38f commit 461efd3

File tree

1 file changed

+138
-4
lines changed

1 file changed

+138
-4
lines changed

26_Autoexposure/main.cpp

Lines changed: 138 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include "nbl/asset/interchange/IAssetLoader.h"
99
#include "nbl/ext/FullScreenTriangle/FullScreenTriangle.h"
1010

11-
1211
using namespace nbl;
1312
using namespace core;
1413
using namespace hlsl;
@@ -95,6 +94,9 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
9594

9695
}
9796

97+
// Create semaphore
98+
m_semaphore = m_device->createSemaphore(m_submitIx);
99+
98100
// create the descriptor set and with enough room for one image sampler
99101
{
100102
const uint32_t setCount = 1;
@@ -107,6 +109,7 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
107109
return logFail("Could not create Descriptor Set!");
108110
}
109111

112+
auto ds = m_descriptorSets[0].get();
110113
auto queue = getGraphicsQueue();
111114

112115
// Gather swapchain resources
@@ -256,7 +259,7 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
256259
const auto cpuImgView = ICPUImageView::create(std::move(viewParams));
257260
const auto& cpuImgParams = cpuImgView->getCreationParameters();
258261

259-
// create matching size image
262+
// create matching size image upto dimensions
260263
IGPUImage::SCreationParams imageParams = {};
261264
imageParams = cpuImgParams.image->getCreationParameters();
262265
imageParams.usage |= IGPUImage::EUF_TRANSFER_DST_BIT | IGPUImage::EUF_SAMPLED_BIT | IGPUImage::E_USAGE_FLAGS::EUF_TRANSFER_SRC_BIT;
@@ -304,7 +307,6 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
304307

305308
// upload image and write to descriptor set
306309
queue->startCapture();
307-
auto ds = m_descriptorSets[0].get();
308310

309311
cmdbuf->begin(IGPUCommandBuffer::USAGE::ONE_TIME_SUBMIT_BIT);
310312
// change the layout of the image
@@ -331,11 +333,28 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
331333
);
332334
IGPUImageView::SCreationParams gpuImgViewParams = {
333335
.image = m_gpuImg,
334-
.viewType = IGPUImageView::ET_2D_ARRAY,
336+
.viewType = IGPUImageView::ET_2D,
335337
.format = m_gpuImg->getCreationParameters().format
336338
};
337339

338340
m_gpuImgView = m_device->createImageView(std::move(gpuImgViewParams));
341+
342+
IGPUDescriptorSet::SDescriptorInfo info = {};
343+
info.info.image.imageLayout = IImage::LAYOUT::READ_ONLY_OPTIMAL;
344+
info.desc = m_gpuImgView;
345+
346+
IGPUDescriptorSet::SWriteDescriptorSet writeDescriptors[] = {
347+
{
348+
.dstSet = ds,
349+
.binding = 0,
350+
.arrayElement = 0,
351+
.count = 1,
352+
.info = &info
353+
}
354+
};
355+
356+
m_device->updateDescriptorSets(1, writeDescriptors, 0, nullptr);
357+
339358
queue->endCapture();
340359
}
341360

@@ -345,6 +364,119 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
345364
// We do a very simple thing, display an image and wait `DisplayImageMs` to show it
346365
inline void workLoopBody() override
347366
{
367+
// Acquire
368+
auto acquire = m_surface->acquireNextImage();
369+
if (!acquire)
370+
return;
371+
372+
auto queue = getGraphicsQueue();
373+
auto cmdbuf = m_cmdBufs[0].get();
374+
auto ds = m_descriptorSets[0].get();
375+
376+
// there's no previous operation to wait for
377+
const SMemoryBarrier toTransferBarrier = {
378+
.dstStageMask = PIPELINE_STAGE_FLAGS::COPY_BIT,
379+
.dstAccessMask = ACCESS_FLAGS::TRANSFER_WRITE_BIT
380+
};
381+
const auto gpuImgCreationParams = m_gpuImg->getCreationParameters();
382+
const auto gpuImgViewCreationParams = m_gpuImgView->getCreationParameters();
383+
384+
queue->startCapture();
385+
// Render to the Image
386+
{
387+
cmdbuf->begin(IGPUCommandBuffer::USAGE::ONE_TIME_SUBMIT_BIT);
388+
389+
// need a pipeline barrier to transition layout
390+
const IGPUCommandBuffer::SImageMemoryBarrier<IGPUCommandBuffer::SOwnershipTransferBarrier> imgBarriers[] = { {
391+
.barrier = {
392+
.dep = toTransferBarrier.nextBarrier(PIPELINE_STAGE_FLAGS::FRAGMENT_SHADER_BIT,ACCESS_FLAGS::SAMPLED_READ_BIT)
393+
},
394+
.image = m_gpuImg.get(),
395+
.subresourceRange = gpuImgViewCreationParams.subresourceRange,
396+
.oldLayout = IGPUImage::LAYOUT::TRANSFER_DST_OPTIMAL,
397+
.newLayout = IGPUImage::LAYOUT::READ_ONLY_OPTIMAL
398+
} };
399+
cmdbuf->pipelineBarrier(E_DEPENDENCY_FLAGS::EDF_NONE, { .imgBarriers = imgBarriers });
400+
401+
const VkRect2D currentRenderArea =
402+
{
403+
.offset = {0,0},
404+
.extent = {gpuImgCreationParams.extent.width, gpuImgCreationParams.extent.height}
405+
};
406+
// set viewport
407+
{
408+
const asset::SViewport viewport =
409+
{
410+
.width = float(gpuImgCreationParams.extent.width),
411+
.height = float(gpuImgCreationParams.extent.height)
412+
};
413+
cmdbuf->setViewport({ &viewport,1 });
414+
}
415+
cmdbuf->setScissor({ &currentRenderArea,1 });
416+
417+
// begin the renderpass
418+
{
419+
const IGPUCommandBuffer::SClearColorValue clearValue = { .float32 = {1.f,0.f,1.f,1.f} };
420+
auto scRes = static_cast<CDefaultSwapchainFramebuffers*>(m_surface->getSwapchainResources());
421+
const IGPUCommandBuffer::SRenderpassBeginInfo info = {
422+
.framebuffer = scRes->getFramebuffer(acquire.imageIndex),
423+
.colorClearValues = &clearValue,
424+
.depthStencilClearValues = nullptr,
425+
.renderArea = currentRenderArea
426+
};
427+
cmdbuf->beginRenderPass(info, IGPUCommandBuffer::SUBPASS_CONTENTS::INLINE);
428+
}
429+
cmdbuf->bindGraphicsPipeline(m_pipeline.get());
430+
cmdbuf->bindDescriptorSets(nbl::asset::EPBP_GRAPHICS, m_pipeline->getLayout(), 3, 1, &ds);
431+
ext::FullScreenTriangle::recordDrawCall(cmdbuf);
432+
cmdbuf->endRenderPass();
433+
434+
cmdbuf->end();
435+
}
436+
437+
// submit
438+
const IQueue::SSubmitInfo::SSemaphoreInfo rendered[1] = { {
439+
.semaphore = m_semaphore.get(),
440+
.value = ++m_submitIx,
441+
// just as we've outputted all pixels, signal
442+
.stageMask = PIPELINE_STAGE_FLAGS::COLOR_ATTACHMENT_OUTPUT_BIT
443+
} };
444+
{
445+
{
446+
const IQueue::SSubmitInfo::SCommandBufferInfo commandBuffers[1] = { {
447+
.cmdbuf = cmdbuf
448+
} };
449+
// we don't need to wait for the transfer semaphore, because we submit everything to the same queue
450+
const IQueue::SSubmitInfo::SSemaphoreInfo acquired[1] = { {
451+
.semaphore = acquire.semaphore,
452+
.value = acquire.acquireCount,
453+
.stageMask = PIPELINE_STAGE_FLAGS::NONE
454+
} };
455+
const IQueue::SSubmitInfo infos[1] = { {
456+
.waitSemaphores = acquired,
457+
.commandBuffers = commandBuffers,
458+
.signalSemaphores = rendered
459+
} };
460+
// we won't signal the sema if no success
461+
if (queue->submit(infos) != IQueue::RESULT::SUCCESS)
462+
m_submitIx--;
463+
}
464+
}
465+
466+
// Present
467+
m_surface->present(acquire.imageIndex, rendered);
468+
getGraphicsQueue()->endCapture();
469+
470+
{
471+
const ISemaphore::SWaitInfo cmdbufDonePending[] = {
472+
{
473+
.semaphore = m_semaphore.get(),
474+
.value = m_submitIx
475+
}
476+
};
477+
if (m_device->blockForSemaphores(cmdbufDonePending) != ISemaphore::WAIT_RESULT::SUCCESS)
478+
return;
479+
}
348480
}
349481

350482
inline bool keepRunning() override
@@ -374,6 +506,8 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
374506
smart_refctd_ptr<IGPUCommandPool> m_cmdPool;
375507
std::array<smart_refctd_ptr<IGPUCommandBuffer>, ISwapchain::MaxImages> m_cmdBufs;
376508
smart_refctd_ptr<IGPUGraphicsPipeline> m_pipeline;
509+
smart_refctd_ptr<ISemaphore> m_semaphore;
510+
uint64_t m_submitIx = 0;
377511

378512
// window
379513
smart_refctd_ptr<IWindow> m_window;

0 commit comments

Comments
 (0)