@@ -74,43 +74,74 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
7474 * Samplers for combined image samplers can also be mutable, which for a binding of a descriptor set is specified also at creation time by leaving the immutableSamplers
7575 * field set to its default (nullptr).
7676 */
77- smart_refctd_ptr<IGPUDescriptorSetLayout> dsLayout ;
77+ smart_refctd_ptr<IGPUDescriptorSetLayout> lumaPresentDSLayout, tonemapperDSLayout ;
7878 {
79- auto defaultSampler = m_device->createSampler ({
80- .AnisotropicFilter = 0
81- });
82-
83- const IGPUDescriptorSetLayout::SBinding bindings[1 ] = { {
84- .binding = 0 ,
85- .type = IDescriptor::E_TYPE::ET_COMBINED_IMAGE_SAMPLER,
86- .createFlags = IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_NONE,
87- .stageFlags = IShader::E_SHADER_STAGE::ESS_FRAGMENT,
88- .count = 1 ,
89- .immutableSamplers = &defaultSampler
90- }
79+ auto defaultSampler = m_device->createSampler (
80+ {
81+ .AnisotropicFilter = 0
82+ }
83+ );
84+
85+ const IGPUDescriptorSetLayout::SBinding lumaPresentBindings[1 ] = {
86+ {
87+ .binding = 0 ,
88+ .type = IDescriptor::E_TYPE::ET_COMBINED_IMAGE_SAMPLER,
89+ .createFlags = IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_NONE,
90+ .stageFlags = IShader::E_SHADER_STAGE::ESS_FRAGMENT | IShader::E_SHADER_STAGE::ESS_COMPUTE,
91+ .count = 1 ,
92+ .immutableSamplers = &defaultSampler
93+ }
9194 };
92- dsLayout = m_device->createDescriptorSetLayout (bindings );
93- if (!dsLayout )
94- return logFail (" Failed to Create Descriptor Layout" );
95+ lumaPresentDSLayout = m_device->createDescriptorSetLayout (lumaPresentBindings );
96+ if (!lumaPresentDSLayout )
97+ return logFail (" Failed to Create Descriptor Layout: lumaPresentDSLayout " );
9598
99+ const IGPUDescriptorSetLayout::SBinding tonemapperBindings[1 ] = {
100+ {
101+ .binding = 1 ,
102+ .type = IDescriptor::E_TYPE::ET_COMBINED_IMAGE_SAMPLER,
103+ .createFlags = IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_NONE,
104+ .stageFlags = IShader::E_SHADER_STAGE::ESS_COMPUTE,
105+ .count = 1 ,
106+ .immutableSamplers = &defaultSampler
107+ }
108+ };
109+ tonemapperDSLayout = m_device->createDescriptorSetLayout (tonemapperBindings);
110+ if (!tonemapperDSLayout)
111+ return logFail (" Failed to Create Descriptor Layout: tonemapperDSLayout" );
96112 }
97113
98- // Create semaphore
99- m_semaphore = m_device->createSemaphore (m_submitIx);
114+ // Create semaphores
115+ m_lumaMeterSemaphore = m_device->createSemaphore (m_submitIx);
116+ m_tonemapperSemaphore = m_device->createSemaphore (m_submitIx);
117+ m_presentSemaphore = m_device->createSemaphore (m_submitIx);
100118
101- // create the descriptor set and with enough room for one image sampler
119+ // create the descriptor sets and with enough room
102120 {
103- const uint32_t setCount = 1 ;
104- auto pool = m_device->createDescriptorPoolForDSLayouts (IDescriptorPool::E_CREATE_FLAGS::ECF_NONE, { &dsLayout.get (),1 }, &setCount);
105- if (!pool)
106- return logFail (" Failed to Create Descriptor Pool" );
107-
108- m_descriptorSets[0 ] = pool->createDescriptorSet (core::smart_refctd_ptr (dsLayout));
109- if (!m_descriptorSets[0 ])
110- return logFail (" Could not create Descriptor Set!" );
121+ constexpr uint32_t lumaPresentSetCount = 2 , tonemapperSetCount = 1 ;
122+ auto lumaPresentPool = m_device->createDescriptorPoolForDSLayouts (
123+ IDescriptorPool::E_CREATE_FLAGS::ECF_NONE,
124+ { &lumaPresentDSLayout.get (), 1 },
125+ &lumaPresentSetCount
126+ );
127+ auto tonemapperPool = m_device->createDescriptorPoolForDSLayouts (
128+ IDescriptorPool::E_CREATE_FLAGS::ECF_NONE,
129+ { &tonemapperDSLayout.get (), 1 },
130+ &tonemapperSetCount
131+ );
132+
133+ if (!lumaPresentPool || !tonemapperPool)
134+ return logFail (" Failed to Create Descriptor Pools" );
135+
136+ m_lumaPresentDS[0 ] = lumaPresentPool->createDescriptorSet (core::smart_refctd_ptr (lumaPresentDSLayout));
137+ if (!m_lumaPresentDS[0 ])
138+ return logFail (" Could not create Descriptor Set: lumaPresentDS!" );
139+ m_tonemapperDS[0 ] = tonemapperPool->createDescriptorSet (core::smart_refctd_ptr (tonemapperDSLayout));
140+ if (!m_tonemapperDS[0 ])
141+ return logFail (" Could not create Descriptor Set: tonemapperDS!" );
142+
111143 }
112144
113- auto ds = m_descriptorSets[0 ].get ();
114145 auto queue = getGraphicsQueue ();
115146
116147 // Gather swapchain resources
@@ -184,13 +215,13 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
184215 if (!fragmentShader)
185216 return logFail (" Failed to Load and Compile Fragment Shader!" );
186217
187- auto layout = m_device->createPipelineLayout ({}, nullptr , nullptr , nullptr , core::smart_refctd_ptr (dsLayout ));
218+ auto layout = m_device->createPipelineLayout ({}, nullptr , nullptr , nullptr , core::smart_refctd_ptr (lumaPresentDSLayout ));
188219 const IGPUShader::SSpecInfo fragSpec = {
189220 .entryPoint = " main" ,
190221 .shader = fragmentShader.get ()
191222 };
192- m_pipeline = fsTriProtoPPln.createPipeline (fragSpec, layout.get (), scResources->getRenderpass ());
193- if (!m_pipeline )
223+ m_presentPipeline = fsTriProtoPPln.createPipeline (fragSpec, layout.get (), scResources->getRenderpass ());
224+ if (!m_presentPipeline )
194225 return logFail (" Could not create Graphics Pipeline!" );
195226 }
196227
@@ -374,7 +405,7 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
374405
375406 IGPUDescriptorSet::SWriteDescriptorSet writeDescriptors[] = {
376407 {
377- .dstSet = ds ,
408+ .dstSet = m_lumaPresentDS[ 0 ]. get () ,
378409 .binding = 0 ,
379410 .arrayElement = 0 ,
380411 .count = 1 ,
@@ -387,6 +418,10 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
387418 queue->endCapture ();
388419 }
389420
421+ // Allocate and create texture for tonemapping
422+ {
423+ }
424+
390425 return true ;
391426 }
392427
@@ -401,7 +436,7 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
401436
402437 auto queue = getGraphicsQueue ();
403438 auto cmdbuf = m_cmdBufs[0 ].get ();
404- auto ds = m_descriptorSets [0 ].get ();
439+ auto ds = m_lumaPresentDS [0 ].get ();
405440
406441 queue->startCapture ();
407442 // Render to the swapchain
@@ -437,8 +472,8 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
437472 cmdbuf->beginRenderPass (info, IGPUCommandBuffer::SUBPASS_CONTENTS::INLINE);
438473 }
439474
440- cmdbuf->bindGraphicsPipeline (m_pipeline .get ());
441- cmdbuf->bindDescriptorSets (nbl::asset::EPBP_GRAPHICS, m_pipeline ->getLayout (), 3 , 1 , &ds);
475+ cmdbuf->bindGraphicsPipeline (m_presentPipeline .get ());
476+ cmdbuf->bindDescriptorSets (nbl::asset::EPBP_GRAPHICS, m_presentPipeline ->getLayout (), 3 , 1 , &ds);
442477 ext::FullScreenTriangle::recordDrawCall (cmdbuf);
443478 cmdbuf->endRenderPass ();
444479
@@ -447,7 +482,7 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
447482
448483 // submit
449484 const IQueue::SSubmitInfo::SSemaphoreInfo rendered[1 ] = { {
450- .semaphore = m_semaphore .get (),
485+ .semaphore = m_presentSemaphore .get (),
451486 .value = ++m_submitIx,
452487 // just as we've outputted all pixels, signal
453488 .stageMask = PIPELINE_STAGE_FLAGS::COLOR_ATTACHMENT_OUTPUT_BIT
@@ -482,7 +517,7 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
482517 {
483518 const ISemaphore::SWaitInfo cmdbufDonePending[] = {
484519 {
485- .semaphore = m_semaphore .get (),
520+ .semaphore = m_presentSemaphore .get (),
486521 .value = m_submitIx
487522 }
488523 };
@@ -506,27 +541,32 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
506541 }
507542
508543protected:
509- smart_refctd_ptr<IGPUImage> m_gpuImg;
510- smart_refctd_ptr<IGPUImageView> m_gpuImgView;
544+ uint64_t m_lumaGatherBDA;
545+ smart_refctd_ptr<IGPUImage> m_gpuImg, m_gpuTonemapImg;
546+ smart_refctd_ptr<IGPUImageView> m_gpuImgView, m_gpuTonemapImgView;
511547
512548 // for image uploads
513549 smart_refctd_ptr<ISemaphore> m_scratchSemaphore;
514550 SIntendedSubmitInfo m_intendedSubmit;
515551
516- // Command Buffers and other resources
517- std::array<smart_refctd_ptr<IGPUDescriptorSet>, ISwapchain::MaxImages> m_descriptorSets;
552+ // Pipelines
553+ smart_refctd_ptr<IGPUGraphicsPipeline> m_presentPipeline;
554+ smart_refctd_ptr<IGPUComputePipeline> m_lumaMeterPipeline, m_tonemapperPipeline;
555+
556+ // Descriptor Sets
557+ std::array<smart_refctd_ptr<IGPUDescriptorSet>, ISwapchain::MaxImages> m_lumaPresentDS, m_tonemapperDS;
558+
559+ // Command Buffers
518560 smart_refctd_ptr<IGPUCommandPool> m_cmdPool;
519561 std::array<smart_refctd_ptr<IGPUCommandBuffer>, ISwapchain::MaxImages> m_cmdBufs;
520- smart_refctd_ptr<IGPUGraphicsPipeline> m_pipeline;
521- smart_refctd_ptr<ISemaphore> m_semaphore;
562+
563+ // Semaphores
564+ smart_refctd_ptr<ISemaphore> m_lumaMeterSemaphore, m_tonemapperSemaphore, m_presentSemaphore;
522565 uint64_t m_submitIx = 0 ;
523566
524567 // window
525568 smart_refctd_ptr<IWindow> m_window;
526569 smart_refctd_ptr<CSimpleResizeSurface<CDefaultSwapchainFramebuffers>> m_surface;
527-
528- // luma gather
529- uint64_t m_lumaGatherBDA;
530570};
531571
532572NBL_MAIN_FUNC (AutoexposureApp)
0 commit comments