10
10
#include < glm/glm.hpp>
11
11
#include < glm/gtc/matrix_transform.hpp>
12
12
13
+ #include < algorithm>
13
14
#include < array>
14
15
#include < cassert>
15
16
#include < cstdint>
@@ -74,17 +75,38 @@ struct CameraLayout
74
75
}
75
76
};
76
77
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
+
77
96
struct RenderParamsLayout
78
97
{
79
- FrameDataLayout frameData;
80
- CameraLayout camera;
98
+ FrameDataLayout frameData;
99
+ CameraLayout camera;
100
+ SamplingStateLayout samplingState;
81
101
82
102
RenderParamsLayout (
83
103
const Extent2u& dimensions,
84
104
const std::uint32_t frameCount,
85
- const RenderParameters& renderParams)
105
+ const RenderParameters& renderParams,
106
+ const std::uint32_t accumulatedSampleCount)
86
107
: frameData(dimensions, frameCount),
87
- camera (renderParams.camera)
108
+ camera (renderParams.camera),
109
+ samplingState(renderParams.samplingParams, accumulatedSampleCount)
88
110
{
89
111
}
90
112
};
@@ -166,6 +188,12 @@ Renderer::Renderer(
166
188
textureDescriptorBuffer(),
167
189
textureBuffer(),
168
190
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 ),
169
197
querySet(nullptr ),
170
198
queryBuffer(
171
199
gpuContext.device,
@@ -180,6 +208,7 @@ Renderer::Renderer(
180
208
renderPipeline(nullptr ),
181
209
currentRenderParams(rendererDesc.renderParams),
182
210
frameCount(0 ),
211
+ accumulatedSampleCount(0 ),
183
212
timestampBufferMapContext{×tampBuffer, &drawDurationsNs, &renderPassDurationsNs}
184
213
{
185
214
{
@@ -420,12 +449,28 @@ Renderer::Renderer(
420
449
const WGPUBindGroupLayout sceneBindGroupLayout =
421
450
wgpuDeviceCreateBindGroupLayout (gpuContext.device , &sceneBindGroupLayoutDesc);
422
451
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
+
423
467
// pipeline layout
424
468
425
- std::array<WGPUBindGroupLayout, 3 > bindGroupLayouts{
469
+ std::array<WGPUBindGroupLayout, 4 > bindGroupLayouts{
426
470
uniformsBindGroupLayout,
427
471
renderParamsBindGroupLayout,
428
472
sceneBindGroupLayout,
473
+ imageBindGroupLayout,
429
474
};
430
475
431
476
const WGPUPipelineLayoutDescriptor pipelineLayoutDesc{
@@ -485,6 +530,22 @@ Renderer::Renderer(
485
530
};
486
531
sceneBindGroup = wgpuDeviceCreateBindGroup (gpuContext.device , &sceneBindGroupDesc);
487
532
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
+
488
549
const WGPURenderPipelineDescriptor pipelineDesc{
489
550
.nextInChain = nullptr ,
490
551
.label = " Render pipeline" ,
@@ -544,6 +605,8 @@ Renderer::~Renderer()
544
605
renderPipeline = nullptr ;
545
606
querySetSafeRelease (querySet);
546
607
querySet = nullptr ;
608
+ bindGroupSafeRelease (imageBindGroup);
609
+ imageBindGroup = nullptr ;
547
610
bindGroupSafeRelease (sceneBindGroup);
548
611
sceneBindGroup = nullptr ;
549
612
bindGroupSafeRelease (renderParamsBindGroup);
@@ -554,7 +617,11 @@ Renderer::~Renderer()
554
617
555
618
void Renderer::setRenderParameters (const RenderParameters& renderParams)
556
619
{
557
- currentRenderParams = renderParams;
620
+ if (currentRenderParams != renderParams)
621
+ {
622
+ currentRenderParams = renderParams;
623
+ accumulatedSampleCount = 0 ; // reset the temporal accumulation
624
+ }
558
625
}
559
626
560
627
void Renderer::render (const GpuContext& gpuContext, Gui& gui)
@@ -568,15 +635,20 @@ void Renderer::render(const GpuContext& gpuContext, Gui& gui)
568
635
}
569
636
570
637
{
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};
574
644
wgpuQueueWriteBuffer (
575
645
gpuContext.queue ,
576
646
renderParamsBuffer.handle (),
577
647
0 ,
578
648
&renderParamsLayout,
579
649
sizeof (RenderParamsLayout));
650
+ accumulatedSampleCount = std::min (
651
+ accumulatedSampleCount + 1 , currentRenderParams.samplingParams .numSamplesPerPixel );
580
652
}
581
653
582
654
const WGPUCommandEncoder encoder = [&gpuContext]() {
@@ -620,6 +692,7 @@ void Renderer::render(const GpuContext& gpuContext, Gui& gui)
620
692
wgpuRenderPassEncoderSetBindGroup (
621
693
renderPassEncoder, 1 , renderParamsBindGroup, 0 , nullptr );
622
694
wgpuRenderPassEncoderSetBindGroup (renderPassEncoder, 2 , sceneBindGroup, 0 , nullptr );
695
+ wgpuRenderPassEncoderSetBindGroup (renderPassEncoder, 3 , imageBindGroup, 0 , nullptr );
623
696
wgpuRenderPassEncoderSetVertexBuffer (
624
697
renderPassEncoder, 0 , vertexBuffer.handle (), 0 , vertexBuffer.byteSize ());
625
698
@@ -731,4 +804,10 @@ float Renderer::averageRenderpassDurationMs() const
731
804
renderPassDurationsNs.begin (), renderPassDurationsNs.end (), std::uint64_t (0 ));
732
805
return 0 .000001f * static_cast <float >(sum) / renderPassDurationsNs.size ();
733
806
}
807
+
808
+ float Renderer::renderProgressPercentage () const
809
+ {
810
+ return 100 .0f * static_cast <float >(accumulatedSampleCount) /
811
+ static_cast <float >(currentRenderParams.samplingParams .numSamplesPerPixel );
812
+ }
734
813
} // namespace nlrs
0 commit comments