8
8
#include " nbl/asset/interchange/IAssetLoader.h"
9
9
#include " nbl/ext/FullScreenTriangle/FullScreenTriangle.h"
10
10
11
-
12
11
using namespace nbl ;
13
12
using namespace core ;
14
13
using namespace hlsl ;
@@ -95,6 +94,9 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
95
94
96
95
}
97
96
97
+ // Create semaphore
98
+ m_semaphore = m_device->createSemaphore (m_submitIx);
99
+
98
100
// create the descriptor set and with enough room for one image sampler
99
101
{
100
102
const uint32_t setCount = 1 ;
@@ -107,6 +109,7 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
107
109
return logFail (" Could not create Descriptor Set!" );
108
110
}
109
111
112
+ auto ds = m_descriptorSets[0 ].get ();
110
113
auto queue = getGraphicsQueue ();
111
114
112
115
// Gather swapchain resources
@@ -256,7 +259,7 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
256
259
const auto cpuImgView = ICPUImageView::create (std::move (viewParams));
257
260
const auto & cpuImgParams = cpuImgView->getCreationParameters ();
258
261
259
- // create matching size image
262
+ // create matching size image upto dimensions
260
263
IGPUImage::SCreationParams imageParams = {};
261
264
imageParams = cpuImgParams.image ->getCreationParameters ();
262
265
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
304
307
305
308
// upload image and write to descriptor set
306
309
queue->startCapture ();
307
- auto ds = m_descriptorSets[0 ].get ();
308
310
309
311
cmdbuf->begin (IGPUCommandBuffer::USAGE::ONE_TIME_SUBMIT_BIT);
310
312
// change the layout of the image
@@ -331,11 +333,28 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
331
333
);
332
334
IGPUImageView::SCreationParams gpuImgViewParams = {
333
335
.image = m_gpuImg,
334
- .viewType = IGPUImageView::ET_2D_ARRAY ,
336
+ .viewType = IGPUImageView::ET_2D ,
335
337
.format = m_gpuImg->getCreationParameters ().format
336
338
};
337
339
338
340
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
+
339
358
queue->endCapture ();
340
359
}
341
360
@@ -345,6 +364,119 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
345
364
// We do a very simple thing, display an image and wait `DisplayImageMs` to show it
346
365
inline void workLoopBody () override
347
366
{
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 ({ ¤tRenderArea,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
+ }
348
480
}
349
481
350
482
inline bool keepRunning () override
@@ -374,6 +506,8 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
374
506
smart_refctd_ptr<IGPUCommandPool> m_cmdPool;
375
507
std::array<smart_refctd_ptr<IGPUCommandBuffer>, ISwapchain::MaxImages> m_cmdBufs;
376
508
smart_refctd_ptr<IGPUGraphicsPipeline> m_pipeline;
509
+ smart_refctd_ptr<ISemaphore> m_semaphore;
510
+ uint64_t m_submitIx = 0 ;
377
511
378
512
// window
379
513
smart_refctd_ptr<IWindow> m_window;
0 commit comments