Skip to content

Commit 57a6a0f

Browse files
committed
Fixed splatting
1 parent 2107be7 commit 57a6a0f

File tree

3 files changed

+121
-39
lines changed

3 files changed

+121
-39
lines changed

31_HLSLPathTracer/app_resources/hlsl/pathtracer.hlsl

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ struct Unidirectional
292292
measure_type getMeasure(uint32_t numSamples, uint32_t depth, NBL_CONST_REF_ARG(scene_type) scene)
293293
{
294294
measure_type Li = (measure_type)0.0;
295-
scalar_type meanLumaSq = 0.0;
295+
//scalar_type meanLumaSq = 0.0;
296296
for (uint32_t i = 0; i < numSamples; i++)
297297
{
298298
measure_type accumulation = getSingleSampleMeasure(i, depth, scene);
@@ -328,6 +328,8 @@ struct Unidirectional
328328
// most of this code is stolen from https://cg.ivd.kit.edu/publications/2018/rwmc/tool/split.cpp
329329
for (uint32_t i = 0; i < numSamples; i++)
330330
{
331+
measure_type accumulation = getSingleSampleMeasure(i, depth, scene);
332+
331333
const float luma = getLuma(accumulation);
332334
//const float luma = calculateLumaRec709(float32_t4(accumulation, 1.0f));
333335

@@ -354,13 +356,9 @@ struct Unidirectional
354356
else
355357
higherCascadeLevelWeight = upperScale / luma;
356358

357-
cascade[uint3(coords.x, coords.y, lowerCascadeIndex)] = float32_t4(accumulation * lowerCascadeLevelWeight, 1.0f);
358-
cascade[uint3(coords.x, coords.y, lowerCascadeIndex + 1u)] = float32_t4(accumulation * higherCascadeLevelWeight, 1.0f);
359+
cascade[uint3(coords.x, coords.y, lowerCascadeIndex)] += float32_t4(accumulation * lowerCascadeLevelWeight, 1.0f);
360+
cascade[uint3(coords.x, coords.y, lowerCascadeIndex + 1u)] += float32_t4(accumulation * higherCascadeLevelWeight, 1.0f);
359361
}
360-
361-
cascade[uint3(coords.x, coords.y, 0)] = float32_t4(Li.r, 0.0f, 0.0f, 0.0f);
362-
cascade[uint3(coords.x, coords.y, 1)] = float32_t4(0.0f, Li.g, 0.0f, 0.0f);
363-
cascade[uint3(coords.x, coords.y, 2)] = float32_t4(0.0f, 0.0f, Li.b, 0.0f);
364362
}
365363

366364
NBL_CONSTEXPR_STATIC_INLINE uint32_t MAX_DEPTH_LOG2 = 4u;

31_HLSLPathTracer/app_resources/hlsl/reweighting.hlsl

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ int32_t2 getCoordinates()
1717
return int32_t2(glsl::gl_GlobalInvocationID().x % width, glsl::gl_GlobalInvocationID().x / width);
1818
}
1919

20-
[numthreads(WorkgroupSize, 1, 1)]
21-
void main(uint32_t3 threadID : SV_DispatchThreadID)
20+
// this function is for testing purpose
21+
// simply adds every cascade buffer, output shoud be nearly the same as output of default accumulator (RWMC off)
22+
void sumCascade(in const int32_t2 coords)
2223
{
23-
const int32_t2 coords = getCoordinates();
24-
2524
float32_t3 accumulation = float32_t3(0.0f, 0.0f, 0.0f);
2625

2726
for (int i = 0; i < 6; ++i)
@@ -30,8 +29,25 @@ void main(uint32_t3 threadID : SV_DispatchThreadID)
3029
accumulation += float32_t3(cascadeLevel.r, cascadeLevel.g, cascadeLevel.b);
3130
}
3231

33-
//accumulation /= 32.0f;
32+
accumulation /= 32.0f;
33+
3434
float32_t4 output = float32_t4(accumulation, 1.0f);
3535

3636
outImage[coords] = output;
3737
}
38+
39+
[numthreads(WorkgroupSize, 1, 1)]
40+
void main(uint32_t3 threadID : SV_DispatchThreadID)
41+
{
42+
// TODO: remove, ideally shader should not be called at all when we don't use RWMC
43+
bool useRWMC = true;
44+
if (!useRWMC)
45+
return;
46+
47+
const int32_t2 coords = getCoordinates();
48+
sumCascade(coords);
49+
50+
// zero out cascade
51+
for (int i = 0; i < 6; ++i)
52+
cascade[uint3(coords.x, coords.y, i)] = float32_t4(0.0f, 0.0f, 0.0f, 0.0f);
53+
}

31_HLSLPathTracer/main.cpp

Lines changed: 95 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -754,13 +754,18 @@ class HLSLComputePathtracer final : public examples::SimpleWindowedApplication,
754754
imgViewInfo.subresourceRange.aspectMask = IImage::E_ASPECT_FLAGS::EAF_COLOR_BIT;
755755
imgViewInfo.subresourceRange.baseArrayLayer = 0u;
756756
imgViewInfo.subresourceRange.baseMipLevel = 0u;
757-
imgViewInfo.subresourceRange.layerCount = 1u;
758757
imgViewInfo.subresourceRange.levelCount = 1u;
759758

760-
if(!useCascadeCreationParameters)
759+
if (!useCascadeCreationParameters)
760+
{
761+
imgViewInfo.subresourceRange.layerCount = 1u;
761762
imgViewInfo.viewType = IGPUImageView::ET_2D;
763+
}
762764
else
765+
{
766+
imgViewInfo.subresourceRange.layerCount = CascadeSize;
763767
imgViewInfo.viewType = IGPUImageView::ET_2D_ARRAY;
768+
}
764769

765770
return m_device->createImageView(std::move(imgViewInfo));
766771
};
@@ -1117,6 +1122,9 @@ class HLSLComputePathtracer final : public examples::SimpleWindowedApplication,
11171122
return m_device->updateDescriptorSets(writes, {});
11181123
}
11191124

1125+
// TODO: DON'T DO THAT! tansition layout once at the initialization stage
1126+
bool cascadeLayoutTransitioned = false;
1127+
11201128
inline void workLoopBody() override
11211129
{
11221130
// framesInFlight: ensuring safe execution of command buffers and acquires, `framesInFlight` only affect semaphore waits, don't use this to index your resources because it can change with swapchain recreation.
@@ -1191,6 +1199,36 @@ class HLSLComputePathtracer final : public examples::SimpleWindowedApplication,
11911199
cmdbuf->pipelineBarrier(E_DEPENDENCY_FLAGS::EDF_NONE, { .imgBarriers = imgBarriers });
11921200
}
11931201

1202+
// TODO: remove! we want to transition cascade layout only once right after its creation
1203+
if (!cascadeLayoutTransitioned)
1204+
{
1205+
cascadeLayoutTransitioned = true;
1206+
1207+
const IGPUCommandBuffer::SImageMemoryBarrier<IGPUCommandBuffer::SOwnershipTransferBarrier> cascadeBarrier[] = {
1208+
{
1209+
.barrier = {
1210+
.dep = {
1211+
.srcStageMask = PIPELINE_STAGE_FLAGS::NONE,
1212+
.srcAccessMask = ACCESS_FLAGS::NONE,
1213+
.dstStageMask = PIPELINE_STAGE_FLAGS::COMPUTE_SHADER_BIT,
1214+
.dstAccessMask = ACCESS_FLAGS::SHADER_WRITE_BITS
1215+
}
1216+
},
1217+
.image = m_cascadeView->getCreationParameters().image.get(),
1218+
.subresourceRange = {
1219+
.aspectMask = IImage::EAF_COLOR_BIT,
1220+
.baseMipLevel = 0u,
1221+
.levelCount = 1u,
1222+
.baseArrayLayer = 0u,
1223+
.layerCount = 6u
1224+
},
1225+
.oldLayout = IImage::LAYOUT::UNDEFINED,
1226+
.newLayout = IImage::LAYOUT::GENERAL
1227+
}
1228+
};
1229+
cmdbuf->pipelineBarrier(E_DEPENDENCY_FLAGS::EDF_NONE, { .imgBarriers = cascadeBarrier });
1230+
}
1231+
11941232
// cube envmap handle
11951233
{
11961234
IGPUComputePipeline* pipeline;
@@ -1211,31 +1249,33 @@ class HLSLComputePathtracer final : public examples::SimpleWindowedApplication,
12111249
cmdbuf->dispatch(1 + (WindowDimensions.x * WindowDimensions.y - 1) / DefaultWorkGroupSize, 1u, 1u);
12121250
}
12131251

1214-
// TODO: create it once outside of the loop?
1215-
const IGPUCommandBuffer::SImageMemoryBarrier<IGPUCommandBuffer::SOwnershipTransferBarrier> cascadeBarrier[] = {
1216-
{
1217-
.barrier = {
1218-
.dep = {
1219-
.srcStageMask = PIPELINE_STAGE_FLAGS::COMPUTE_SHADER_BIT,
1220-
.srcAccessMask = ACCESS_FLAGS::SHADER_WRITE_BITS,
1221-
.dstStageMask = PIPELINE_STAGE_FLAGS::FRAGMENT_SHADER_BIT,
1222-
.dstAccessMask = ACCESS_FLAGS::SHADER_READ_BITS
1223-
}
1224-
},
1225-
.image = m_cascadeView->getCreationParameters().image.get(),
1226-
.subresourceRange = {
1227-
.aspectMask = IImage::EAF_COLOR_BIT,
1228-
.baseMipLevel = 0u,
1229-
.levelCount = 1u,
1230-
.baseArrayLayer = 0u,
1231-
.layerCount = 6u
1232-
},
1233-
.oldLayout = IImage::LAYOUT::GENERAL,
1234-
.newLayout = IImage::LAYOUT::GENERAL
1235-
}
1236-
};
1237-
1238-
cmdbuf->pipelineBarrier(E_DEPENDENCY_FLAGS::EDF_NONE, { .imgBarriers = cascadeBarrier });
1252+
// m_cascadeView synchronization - wait for previous compute shader to write into the cascade
1253+
// TODO: create this and every other barrier once outside of the loop?
1254+
{
1255+
const IGPUCommandBuffer::SImageMemoryBarrier<IGPUCommandBuffer::SOwnershipTransferBarrier> cascadeBarrier[] = {
1256+
{
1257+
.barrier = {
1258+
.dep = {
1259+
.srcStageMask = PIPELINE_STAGE_FLAGS::COMPUTE_SHADER_BIT,
1260+
.srcAccessMask = ACCESS_FLAGS::SHADER_WRITE_BITS,
1261+
.dstStageMask = PIPELINE_STAGE_FLAGS::COMPUTE_SHADER_BIT,
1262+
.dstAccessMask = ACCESS_FLAGS::SHADER_READ_BITS
1263+
}
1264+
},
1265+
.image = m_cascadeView->getCreationParameters().image.get(),
1266+
.subresourceRange = {
1267+
.aspectMask = IImage::EAF_COLOR_BIT,
1268+
.baseMipLevel = 0u,
1269+
.levelCount = 1u,
1270+
.baseArrayLayer = 0u,
1271+
.layerCount = 6u
1272+
},
1273+
.oldLayout = IImage::LAYOUT::GENERAL,
1274+
.newLayout = IImage::LAYOUT::GENERAL
1275+
}
1276+
};
1277+
cmdbuf->pipelineBarrier(E_DEPENDENCY_FLAGS::EDF_NONE, { .imgBarriers = cascadeBarrier });
1278+
}
12391279

12401280
// reweighting
12411281
{
@@ -1283,6 +1323,34 @@ class HLSLComputePathtracer final : public examples::SimpleWindowedApplication,
12831323
cmdbuf->pipelineBarrier(E_DEPENDENCY_FLAGS::EDF_NONE, { .imgBarriers = imgBarriers });
12841324
}
12851325

1326+
// m_cascadeView synchronization - wait for previous compute shader to zero-out the cascade
1327+
// TODO: create this and every other barrier once outside of the loop?
1328+
{
1329+
const IGPUCommandBuffer::SImageMemoryBarrier<IGPUCommandBuffer::SOwnershipTransferBarrier> cascadeBarrier[] = {
1330+
{
1331+
.barrier = {
1332+
.dep = {
1333+
.srcStageMask = PIPELINE_STAGE_FLAGS::COMPUTE_SHADER_BIT,
1334+
.srcAccessMask = ACCESS_FLAGS::SHADER_WRITE_BITS,
1335+
.dstStageMask = PIPELINE_STAGE_FLAGS::COMPUTE_SHADER_BIT,
1336+
.dstAccessMask = ACCESS_FLAGS::SHADER_WRITE_BITS
1337+
}
1338+
},
1339+
.image = m_cascadeView->getCreationParameters().image.get(),
1340+
.subresourceRange = {
1341+
.aspectMask = IImage::EAF_COLOR_BIT,
1342+
.baseMipLevel = 0u,
1343+
.levelCount = 1u,
1344+
.baseArrayLayer = 0u,
1345+
.layerCount = 6u
1346+
},
1347+
.oldLayout = IImage::LAYOUT::GENERAL,
1348+
.newLayout = IImage::LAYOUT::GENERAL
1349+
}
1350+
};
1351+
cmdbuf->pipelineBarrier(E_DEPENDENCY_FLAGS::EDF_NONE, { .imgBarriers = cascadeBarrier });
1352+
}
1353+
12861354
// TODO: tone mapping and stuff
12871355
}
12881356

0 commit comments

Comments
 (0)