1010#include < glm/glm.hpp>
1111#include < glm/gtc/matrix_transform.hpp>
1212
13+ #include < algorithm>
1314#include < array>
1415#include < cassert>
1516#include < cstdint>
@@ -74,17 +75,38 @@ struct CameraLayout
7475 }
7576};
7677
78+ struct SamplingStateLayout
79+ {
80+ std::uint32_t numSamplesPerPixel;
81+ std::uint32_t numBounces;
82+ std::uint32_t accumulatedSampleCount;
83+ std::uint32_t padding;
84+
85+ SamplingStateLayout (
86+ const SamplingParams& samplingParams,
87+ const std::uint32_t accumulatedSampleCount)
88+ : numSamplesPerPixel(samplingParams.numSamplesPerPixel),
89+ numBounces (samplingParams.numBounces),
90+ accumulatedSampleCount(accumulatedSampleCount),
91+ padding(0 )
92+ {
93+ }
94+ };
95+
7796struct RenderParamsLayout
7897{
79- FrameDataLayout frameData;
80- CameraLayout camera;
98+ FrameDataLayout frameData;
99+ CameraLayout camera;
100+ SamplingStateLayout samplingState;
81101
82102 RenderParamsLayout (
83103 const Extent2u& dimensions,
84104 const std::uint32_t frameCount,
85- const RenderParameters& renderParams)
105+ const RenderParameters& renderParams,
106+ const std::uint32_t accumulatedSampleCount)
86107 : frameData(dimensions, frameCount),
87- camera (renderParams.camera)
108+ camera (renderParams.camera),
109+ samplingState(renderParams.samplingParams, accumulatedSampleCount)
88110 {
89111 }
90112};
@@ -166,6 +188,12 @@ Renderer::Renderer(
166188 textureDescriptorBuffer(),
167189 textureBuffer(),
168190 sceneBindGroup(nullptr ),
191+ imageBuffer(
192+ gpuContext.device,
193+ " image buffer" ,
194+ WGPUBufferUsage_Storage,
195+ sizeof (float [4 ]) * rendererDesc.maxFramebufferSize.x * rendererDesc.maxFramebufferSize.y),
196+ imageBindGroup(nullptr ),
169197 querySet(nullptr ),
170198 queryBuffer(
171199 gpuContext.device,
@@ -180,6 +208,7 @@ Renderer::Renderer(
180208 renderPipeline(nullptr ),
181209 currentRenderParams(rendererDesc.renderParams),
182210 frameCount(0 ),
211+ accumulatedSampleCount(0 ),
183212 timestampBufferMapContext{×tampBuffer, &drawDurationsNs, &renderPassDurationsNs}
184213{
185214 {
@@ -420,12 +449,28 @@ Renderer::Renderer(
420449 const WGPUBindGroupLayout sceneBindGroupLayout =
421450 wgpuDeviceCreateBindGroupLayout (gpuContext.device , &sceneBindGroupLayoutDesc);
422451
452+ // image bind group layout
453+
454+ const WGPUBindGroupLayoutEntry imageBindGroupLayoutEntry =
455+ imageBuffer.bindGroupLayoutEntry (0 , WGPUShaderStage_Fragment);
456+
457+ const WGPUBindGroupLayoutDescriptor imageBindGroupLayoutDesc{
458+ .nextInChain = nullptr ,
459+ .label = " image bind group layout" ,
460+ .entryCount = 1 ,
461+ .entries = &imageBindGroupLayoutEntry,
462+ };
463+
464+ const WGPUBindGroupLayout imageBindGroupLayout =
465+ wgpuDeviceCreateBindGroupLayout (gpuContext.device , &imageBindGroupLayoutDesc);
466+
423467 // pipeline layout
424468
425- std::array<WGPUBindGroupLayout, 3 > bindGroupLayouts{
469+ std::array<WGPUBindGroupLayout, 4 > bindGroupLayouts{
426470 uniformsBindGroupLayout,
427471 renderParamsBindGroupLayout,
428472 sceneBindGroupLayout,
473+ imageBindGroupLayout,
429474 };
430475
431476 const WGPUPipelineLayoutDescriptor pipelineLayoutDesc{
@@ -485,6 +530,22 @@ Renderer::Renderer(
485530 };
486531 sceneBindGroup = wgpuDeviceCreateBindGroup (gpuContext.device , &sceneBindGroupDesc);
487532
533+ // image bind group
534+
535+ const WGPUBindGroupEntry imageBindGroupEntry = imageBuffer.bindGroupEntry (0 );
536+
537+ const WGPUBindGroupDescriptor imageBindGroupDesc{
538+ .nextInChain = nullptr ,
539+ .label = " image bind group" ,
540+ .layout = imageBindGroupLayout,
541+ .entryCount = 1 ,
542+ .entries = &imageBindGroupEntry,
543+ };
544+
545+ imageBindGroup = wgpuDeviceCreateBindGroup (gpuContext.device , &imageBindGroupDesc);
546+
547+ // pipeline
548+
488549 const WGPURenderPipelineDescriptor pipelineDesc{
489550 .nextInChain = nullptr ,
490551 .label = " Render pipeline" ,
@@ -544,6 +605,8 @@ Renderer::~Renderer()
544605 renderPipeline = nullptr ;
545606 querySetSafeRelease (querySet);
546607 querySet = nullptr ;
608+ bindGroupSafeRelease (imageBindGroup);
609+ imageBindGroup = nullptr ;
547610 bindGroupSafeRelease (sceneBindGroup);
548611 sceneBindGroup = nullptr ;
549612 bindGroupSafeRelease (renderParamsBindGroup);
@@ -554,7 +617,11 @@ Renderer::~Renderer()
554617
555618void Renderer::setRenderParameters (const RenderParameters& renderParams)
556619{
557- currentRenderParams = renderParams;
620+ if (currentRenderParams != renderParams)
621+ {
622+ currentRenderParams = renderParams;
623+ accumulatedSampleCount = 0 ; // reset the temporal accumulation
624+ }
558625}
559626
560627void Renderer::render (const GpuContext& gpuContext, Gui& gui)
@@ -568,15 +635,20 @@ void Renderer::render(const GpuContext& gpuContext, Gui& gui)
568635 }
569636
570637 {
571- // TODO: framebuffersize is now a part of render params struct, adjust constructor
572- const RenderParamsLayout renderParamsLayout (
573- currentRenderParams.framebufferSize , frameCount++, currentRenderParams);
638+ assert (accumulatedSampleCount <= currentRenderParams.samplingParams .numSamplesPerPixel );
639+ const RenderParamsLayout renderParamsLayout{
640+ currentRenderParams.framebufferSize ,
641+ frameCount++,
642+ currentRenderParams,
643+ accumulatedSampleCount};
574644 wgpuQueueWriteBuffer (
575645 gpuContext.queue ,
576646 renderParamsBuffer.handle (),
577647 0 ,
578648 &renderParamsLayout,
579649 sizeof (RenderParamsLayout));
650+ accumulatedSampleCount = std::min (
651+ accumulatedSampleCount + 1 , currentRenderParams.samplingParams .numSamplesPerPixel );
580652 }
581653
582654 const WGPUCommandEncoder encoder = [&gpuContext]() {
@@ -620,6 +692,7 @@ void Renderer::render(const GpuContext& gpuContext, Gui& gui)
620692 wgpuRenderPassEncoderSetBindGroup (
621693 renderPassEncoder, 1 , renderParamsBindGroup, 0 , nullptr );
622694 wgpuRenderPassEncoderSetBindGroup (renderPassEncoder, 2 , sceneBindGroup, 0 , nullptr );
695+ wgpuRenderPassEncoderSetBindGroup (renderPassEncoder, 3 , imageBindGroup, 0 , nullptr );
623696 wgpuRenderPassEncoderSetVertexBuffer (
624697 renderPassEncoder, 0 , vertexBuffer.handle (), 0 , vertexBuffer.byteSize ());
625698
@@ -731,4 +804,10 @@ float Renderer::averageRenderpassDurationMs() const
731804 renderPassDurationsNs.begin (), renderPassDurationsNs.end (), std::uint64_t (0 ));
732805 return 0 .000001f * static_cast <float >(sum) / renderPassDurationsNs.size ();
733806}
807+
808+ float Renderer::renderProgressPercentage () const
809+ {
810+ return 100 .0f * static_cast <float >(accumulatedSampleCount) /
811+ static_cast <float >(currentRenderParams.samplingParams .numSamplesPerPixel );
812+ }
734813} // namespace nlrs
0 commit comments