diff --git a/projects/indirect_dispatch/resources/shaders/motionBlur.comp b/projects/indirect_dispatch/resources/shaders/motionBlur.comp index 503a7afa77249b1183e03e808d4879f63b20b24e..7d71df17db177718a211120ab951975825ddd7e6 100644 --- a/projects/indirect_dispatch/resources/shaders/motionBlur.comp +++ b/projects/indirect_dispatch/resources/shaders/motionBlur.comp @@ -1,6 +1,8 @@ #version 440 #extension GL_GOOGLE_include_directive : enable + #include "motionBlurConfig.inc" +#include "motionBlurWorkTile.inc" layout(set=0, binding=0) uniform texture2D inColor; layout(set=0, binding=1) uniform texture2D inDepth; @@ -9,7 +11,11 @@ layout(set=0, binding=3) uniform texture2D inMotionNeighbou layout(set=0, binding=4) uniform sampler nearestSampler; layout(set=0, binding=5, r11f_g11f_b10f) uniform image2D outImage; -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; +layout(set=0, binding=6) buffer copyPathTileBuffer { + WorkTiles workTiles; +}; + +layout(local_size_x = motionTileSize, local_size_y = motionTileSize, local_size_z = 1) in; layout( push_constant ) uniform constants{ // computed from delta time and shutter speed @@ -127,11 +133,14 @@ float dither(ivec2 coord){ void main(){ - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))) + uint tileIndex = gl_WorkGroupID.x; + ivec2 tileCoordinates = workTiles.tileXY[tileIndex]; + ivec2 coord = ivec2(tileCoordinates * motionTileSize + gl_LocalInvocationID.xy); + + if(any(greaterThanEqual(coord, imageSize(outImage)))) return; ivec2 textureRes = textureSize(sampler2D(inColor, nearestSampler), 0); - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); vec2 uv = vec2(coord + 0.5) / textureRes; // + 0.5 to shift uv into pixel center // the motion tile lookup is jittered, so the hard edges in the blur are replaced by noise diff --git a/projects/indirect_dispatch/resources/shaders/motionBlurColorCopy.comp b/projects/indirect_dispatch/resources/shaders/motionBlurColorCopy.comp index 890b814e0feadb646971148978d1b91952904ca9..3afbe9f3a7d027cc253223de91b4ed30285479f3 100644 --- a/projects/indirect_dispatch/resources/shaders/motionBlurColorCopy.comp +++ b/projects/indirect_dispatch/resources/shaders/motionBlurColorCopy.comp @@ -1,20 +1,29 @@ #version 440 #extension GL_GOOGLE_include_directive : enable + #include "motionBlurConfig.inc" +#include "motionBlurWorkTile.inc" layout(set=0, binding=0) uniform texture2D inColor; layout(set=0, binding=1) uniform sampler nearestSampler; layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D outImage; -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; +layout(set=0, binding=3) buffer copyPathTileBuffer { + WorkTiles workTiles; +}; + +layout(local_size_x = motionTileSize, local_size_y = motionTileSize, local_size_z = 1) in; void main(){ - if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))) + uint tileIndex = gl_WorkGroupID.x; + ivec2 tileCoordinates = workTiles.tileXY[tileIndex]; + ivec2 coordinate = ivec2(tileCoordinates * motionTileSize + gl_LocalInvocationID.xy); + + if(any(greaterThanEqual(coordinate, imageSize(outImage)))) return; - - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - vec3 color = texelFetch(sampler2D(inColor, nearestSampler), coord, 0).rgb; - imageStore(outImage, coord, vec4(color, 0.f)); + vec3 color = texelFetch(sampler2D(inColor, nearestSampler), coordinate, 0).rgb; + + imageStore(outImage, coordinate, vec4(color, 0.f)); } \ No newline at end of file diff --git a/projects/indirect_dispatch/resources/shaders/motionBlurConfig.inc b/projects/indirect_dispatch/resources/shaders/motionBlurConfig.inc index fdd915c8aa857ee3bf91fe31d8f6a224bfe85612..25e647d091c4463883fec665f9fab04b95a28907 100644 --- a/projects/indirect_dispatch/resources/shaders/motionBlurConfig.inc +++ b/projects/indirect_dispatch/resources/shaders/motionBlurConfig.inc @@ -1 +1,8 @@ -const int motionTileSize = 20; \ No newline at end of file +#ifndef MOTION_BLUR_CONFIG +#define MOTION_BLUR_CONFIG + +const int motionTileSize = 24; +const int maxMotionBlurWidth = 3840; +const int maxMotionBlurHeight = 2160; + +#endif // #ifndef MOTION_BLUR_CONFIG \ No newline at end of file diff --git a/projects/indirect_dispatch/resources/shaders/motionBlurIndirectArguments.comp b/projects/indirect_dispatch/resources/shaders/motionBlurIndirectArguments.comp deleted file mode 100644 index 1d225cf864c979ddf902b33201b5e00a1783ae56..0000000000000000000000000000000000000000 --- a/projects/indirect_dispatch/resources/shaders/motionBlurIndirectArguments.comp +++ /dev/null @@ -1,20 +0,0 @@ -#version 440 -#extension GL_GOOGLE_include_directive : enable - -layout(set=0, binding=0) buffer indirectArgumentBuffer { - uint dispatchArgs[3]; -}; - -layout( push_constant ) uniform constants{ - uint width; - uint height; -}; - -layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; - -void main(){ - - dispatchArgs[0] = (width + 7) / 8; - dispatchArgs[1] = (height + 7) / 8; - dispatchArgs[2] = 1; -} \ No newline at end of file diff --git a/projects/indirect_dispatch/resources/shaders/motionBlurTileClassification.comp b/projects/indirect_dispatch/resources/shaders/motionBlurTileClassification.comp new file mode 100644 index 0000000000000000000000000000000000000000..a7be26b830d52d244354501353cf34366145398c --- /dev/null +++ b/projects/indirect_dispatch/resources/shaders/motionBlurTileClassification.comp @@ -0,0 +1,43 @@ +#version 440 +#extension GL_GOOGLE_include_directive : enable + +#include "motionBlurWorkTile.inc" + +layout(set=0, binding=0) uniform texture2D inVelocityTile; +layout(set=0, binding=1) uniform sampler nearestSampler; + +layout(set=0, binding=2) buffer fullPathTileBuffer { + WorkTiles fullPathTiles; +}; + +layout(set=0, binding=3) buffer copyPathTileBuffer { + WorkTiles copyPathTiles; +}; + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +layout( push_constant ) uniform constants{ + uint width; + uint height; +}; + +void main(){ + + ivec2 tileCoord = ivec2(gl_GlobalInvocationID.xy); + + if(any(greaterThanEqual(gl_GlobalInvocationID.xy, textureSize(sampler2D(inVelocityTile, nearestSampler), 0)))) + return; + + vec2 motion = texelFetch(sampler2D(inVelocityTile, nearestSampler), tileCoord, 0).rg; + vec2 motionPixel = motion * vec2(width, height); + float velocityPixel = length(motionPixel); + + if(velocityPixel > 0.5){ + uint index = atomicAdd(fullPathTiles.tileCount, 1); + fullPathTiles.tileXY[index] = tileCoord; + } + else{ + uint index = atomicAdd(copyPathTiles.tileCount, 1); + copyPathTiles.tileXY[index] = tileCoord; + } +} \ No newline at end of file diff --git a/projects/indirect_dispatch/resources/shaders/motionBlurTileClassificationVis.comp b/projects/indirect_dispatch/resources/shaders/motionBlurTileClassificationVis.comp new file mode 100644 index 0000000000000000000000000000000000000000..7889f454ee8a8a5d9f3026da2b34012f38a3f4b6 --- /dev/null +++ b/projects/indirect_dispatch/resources/shaders/motionBlurTileClassificationVis.comp @@ -0,0 +1,47 @@ +#version 440 +#extension GL_GOOGLE_include_directive : enable + +#include "motionBlurConfig.inc" +#include "motionBlurWorkTile.inc" + +layout(set=0, binding=0) uniform texture2D inColor; +layout(set=0, binding=1) uniform sampler nearestSampler; +layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D outImage; + +layout(set=0, binding=3) buffer fullPathTileBuffer { + WorkTiles fullPathTiles; +}; + +layout(set=0, binding=4) buffer copyPathTileBuffer { + WorkTiles copyPathTiles; +}; + +layout(local_size_x = motionTileSize, local_size_y = motionTileSize, local_size_z = 1) in; + +void main(){ + + uint tileIndexFullPath = gl_WorkGroupID.x; + uint tileIndexCopyPath = gl_WorkGroupID.x - fullPathTiles.tileCount; + + vec3 debugColor; + ivec2 tileCoordinates; + + if(tileIndexFullPath < fullPathTiles.tileCount){ + debugColor = vec3(1, 0, 0); + tileCoordinates = fullPathTiles.tileXY[tileIndexFullPath]; + } + else if(tileIndexCopyPath < copyPathTiles.tileCount){ + debugColor = vec3(0, 1, 0); + tileCoordinates = copyPathTiles.tileXY[tileIndexCopyPath]; + } + else{ + return; + } + + ivec2 coordinate = ivec2(tileCoordinates * motionTileSize + gl_LocalInvocationID.xy); + vec3 color = texelFetch(sampler2D(inColor, nearestSampler), coordinate, 0).rgb; + + color = mix(color, debugColor, 0.5); + + imageStore(outImage, coordinate, vec4(color, 0)); +} \ No newline at end of file diff --git a/projects/indirect_dispatch/resources/shaders/motionBlurWorkTile.inc b/projects/indirect_dispatch/resources/shaders/motionBlurWorkTile.inc new file mode 100644 index 0000000000000000000000000000000000000000..8577f100aac524b93eecac406606a962bc52d222 --- /dev/null +++ b/projects/indirect_dispatch/resources/shaders/motionBlurWorkTile.inc @@ -0,0 +1,19 @@ +#ifndef MOTION_BLUR_WORK_TILE +#define MOTION_BLUR_WORK_TILE + +#include "motionBlurConfig.inc" + +const int maxTileCount = + (maxMotionBlurWidth + motionTileSize - 1) / motionTileSize * + (maxMotionBlurHeight + motionTileSize - 1) / motionTileSize; + +struct WorkTiles{ + uint tileCount; + // dispatch Y/Z are here so the buffer can be used directly as an indirect dispatch argument buffer + uint dispatchY; + uint dispatchZ; + + ivec2 tileXY[maxTileCount]; +}; + +#endif // #ifndef MOTION_BLUR_WORK_TILE \ No newline at end of file diff --git a/projects/indirect_dispatch/resources/shaders/motionBlurWorkTileReset.comp b/projects/indirect_dispatch/resources/shaders/motionBlurWorkTileReset.comp new file mode 100644 index 0000000000000000000000000000000000000000..916a4e4d752061e3662e05ce1188be3e3d4c262c --- /dev/null +++ b/projects/indirect_dispatch/resources/shaders/motionBlurWorkTileReset.comp @@ -0,0 +1,24 @@ +#version 440 +#extension GL_GOOGLE_include_directive : enable + +#include "motionBlurWorkTile.inc" + +layout(set=0, binding=0) buffer fullPathTileBuffer { + WorkTiles fullPathTiles; +}; + +layout(set=0, binding=1) buffer copyPathTileBuffer { + WorkTiles copyPathTiles; +}; + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +void main(){ + fullPathTiles.tileCount = 0; + fullPathTiles.dispatchY = 1; + fullPathTiles.dispatchZ = 1; + + copyPathTiles.tileCount = 0; + copyPathTiles.dispatchY = 1; + copyPathTiles.dispatchZ = 1; +} \ No newline at end of file diff --git a/projects/indirect_dispatch/src/MotionBlur.cpp b/projects/indirect_dispatch/src/MotionBlur.cpp index 3a8594f68871139ce3eeb7d9e3d8ec2fb1058dcd..223b74ca262664eb4cfeb4106b47f92ede70931a 100644 --- a/projects/indirect_dispatch/src/MotionBlur.cpp +++ b/projects/indirect_dispatch/src/MotionBlur.cpp @@ -10,8 +10,8 @@ std::array<uint32_t, 3> computeFullscreenDispatchSize( // optimized divide and ceil return std::array<uint32_t, 3>{ - static_cast<uint32_t>(imageWidth + (localGroupSize - 1) / localGroupSize), - static_cast<uint32_t>(imageHeight + (localGroupSize - 1) / localGroupSize), + static_cast<uint32_t>(imageWidth + (localGroupSize - 1)) / localGroupSize, + static_cast<uint32_t>(imageHeight + (localGroupSize - 1)) / localGroupSize, static_cast<uint32_t>(1) }; } @@ -36,18 +36,42 @@ bool MotionBlur::initialize(vkcv::Core* corePtr, const uint32_t targetWidth, con if (!loadComputePass(*m_core, "resources/shaders/motionVectorVisualisation.comp", &m_motionVectorVisualisationPass)) return false; - if (!loadComputePass(*m_core, "resources/shaders/motionBlurIndirectArguments.comp", &m_indirectArgumentPass)) + if (!loadComputePass(*m_core, "resources/shaders/motionBlurColorCopy.comp", &m_colorCopyPass)) return false; - if (!loadComputePass(*m_core, "resources/shaders/motionBlurColorCopy.comp", &m_colorCopyPass)) + if (!loadComputePass(*m_core, "resources/shaders/motionBlurTileClassification.comp", &m_tileClassificationPass)) + return false; + + if (!loadComputePass(*m_core, "resources/shaders/motionBlurWorkTileReset.comp", &m_tileResetPass)) + return false; + + if (!loadComputePass(*m_core, "resources/shaders/motionBlurTileClassificationVis.comp", &m_tileVisualisationPass)) return false; - m_indirectArgumentBuffer = m_core->createBuffer<uint32_t>(vkcv::BufferType::STORAGE, 3, vkcv::BufferMemoryType::DEVICE_LOCAL, true).getHandle(); + // work tile buffers and descriptors + const uint32_t workTileBufferSize = static_cast<uint32_t>(2 * sizeof(uint32_t)) * (3 + + ((MotionBlurConfig::maxWidth + MotionBlurConfig::maxMotionTileSize - 1) / MotionBlurConfig::maxMotionTileSize) * + ((MotionBlurConfig::maxHeight + MotionBlurConfig::maxMotionTileSize - 1) / MotionBlurConfig::maxMotionTileSize)); + + m_copyPathWorkTileBuffer = m_core->createBuffer<uint32_t>( + vkcv::BufferType::STORAGE, + workTileBufferSize, + vkcv::BufferMemoryType::DEVICE_LOCAL, + true).getHandle(); + + m_fullPathWorkTileBuffer = m_core->createBuffer<uint32_t>( + vkcv::BufferType::STORAGE, + workTileBufferSize, + vkcv::BufferMemoryType::DEVICE_LOCAL, + true).getHandle(); + + vkcv::DescriptorWrites tileResetDescriptorWrites; + tileResetDescriptorWrites.storageBufferWrites = { + vkcv::BufferDescriptorWrite(0, m_fullPathWorkTileBuffer), + vkcv::BufferDescriptorWrite(1, m_copyPathWorkTileBuffer) }; + + m_core->writeDescriptorSet(m_tileResetPass.descriptorSet, tileResetDescriptorWrites); - vkcv::DescriptorWrites indirectArgumentDescriptorWrites; - indirectArgumentDescriptorWrites.storageBufferWrites = - { vkcv::BufferDescriptorWrite(0, m_indirectArgumentBuffer) }; - m_core->writeDescriptorSet(m_indirectArgumentPass.descriptorSet, indirectArgumentDescriptorWrites); m_renderTargets = MotionBlurSetup::createRenderTargets(targetWidth, targetHeight, *m_core); @@ -79,25 +103,57 @@ vkcv::ImageHandle MotionBlur::render( computeMotionTiles(cmdStream, motionBufferFullRes); - // write indirect dispatch argument buffer - struct IndirectArgumentConstants { + // work tile reset + const uint32_t dispatchSizeOne[3] = { 1, 1, 1 }; + + m_core->recordComputeDispatchToCmdStream( + cmdStream, + m_tileResetPass.pipeline, + dispatchSizeOne, + { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_tileResetPass.descriptorSet).vulkanHandle) }, + vkcv::PushConstants(0)); + + m_core->recordBufferMemoryBarrier(cmdStream, m_fullPathWorkTileBuffer); + m_core->recordBufferMemoryBarrier(cmdStream, m_copyPathWorkTileBuffer); + + // work tile classification + vkcv::DescriptorWrites tileClassificationDescriptorWrites; + tileClassificationDescriptorWrites.sampledImageWrites = { + vkcv::SampledImageDescriptorWrite(0, m_renderTargets.motionMaxNeighbourhood) }; + tileClassificationDescriptorWrites.samplerWrites = { + vkcv::SamplerDescriptorWrite(1, m_nearestSampler) }; + tileClassificationDescriptorWrites.storageBufferWrites = { + vkcv::BufferDescriptorWrite(2, m_fullPathWorkTileBuffer), + vkcv::BufferDescriptorWrite(3, m_copyPathWorkTileBuffer) }; + + m_core->writeDescriptorSet(m_tileClassificationPass.descriptorSet, tileClassificationDescriptorWrites); + + const auto tileClassificationDispatch = computeFullscreenDispatchSize( + m_core->getImageWidth(m_renderTargets.motionMaxNeighbourhood), + m_core->getImageHeight(m_renderTargets.motionMaxNeighbourhood), + 8); + + struct ResolutionConstants { uint32_t width; uint32_t height; }; - vkcv::PushConstants indirectArgumentPassPushConstants(sizeof(IndirectArgumentConstants)); - IndirectArgumentConstants indirectArgumentConstants; - indirectArgumentConstants.width = m_core->getImageWidth( m_renderTargets.outputColor); - indirectArgumentConstants.height = m_core->getImageHeight(m_renderTargets.outputColor); - indirectArgumentPassPushConstants.appendDrawcall(indirectArgumentConstants); + vkcv::PushConstants resolutionPushConstants(sizeof(ResolutionConstants)); + ResolutionConstants resolutionConstants; + resolutionConstants.width = m_core->getImageWidth(m_renderTargets.outputColor); + resolutionConstants.height = m_core->getImageHeight(m_renderTargets.outputColor); + resolutionPushConstants.appendDrawcall(resolutionConstants); - const uint32_t dispatchSizeOne[3] = { 1, 1, 1 }; + m_core->prepareImageForSampling(cmdStream, m_renderTargets.motionMaxNeighbourhood); m_core->recordComputeDispatchToCmdStream( cmdStream, - m_indirectArgumentPass.pipeline, - dispatchSizeOne, - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_indirectArgumentPass.descriptorSet).vulkanHandle) }, - indirectArgumentPassPushConstants); + m_tileClassificationPass.pipeline, + tileClassificationDispatch.data(), + { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_tileClassificationPass.descriptorSet).vulkanHandle) }, + resolutionPushConstants); + + m_core->recordBufferMemoryBarrier(cmdStream, m_fullPathWorkTileBuffer); + m_core->recordBufferMemoryBarrier(cmdStream, m_copyPathWorkTileBuffer); // usually this is the neighbourhood max, but other modes can be used for comparison/debugging vkcv::ImageHandle inputMotionTiles; @@ -122,6 +178,8 @@ vkcv::ImageHandle MotionBlur::render( vkcv::SamplerDescriptorWrite(4, m_nearestSampler) }; motionBlurDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(5, m_renderTargets.outputColor) }; + motionBlurDescriptorWrites.storageBufferWrites = { + vkcv::BufferDescriptorWrite(6, m_fullPathWorkTileBuffer)}; m_core->writeDescriptorSet(m_motionBlurPass.descriptorSet, motionBlurDescriptorWrites); @@ -133,6 +191,8 @@ vkcv::ImageHandle MotionBlur::render( vkcv::SamplerDescriptorWrite(1, m_nearestSampler) }; colorCopyDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(2, m_renderTargets.outputColor) }; + colorCopyDescriptorWrites.storageBufferWrites = { + vkcv::BufferDescriptorWrite(3, m_copyPathWorkTileBuffer) }; m_core->writeDescriptorSet(m_colorCopyPass.descriptorSet, colorCopyDescriptorWrites); @@ -164,30 +224,57 @@ vkcv::ImageHandle MotionBlur::render( m_core->recordComputeIndirectDispatchToCmdStream( cmdStream, m_motionBlurPass.pipeline, - m_indirectArgumentBuffer, + m_fullPathWorkTileBuffer, 0, { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_motionBlurPass.descriptorSet).vulkanHandle) }, motionBlurPushConstants); - } - else if(mode == eMotionBlurMode::Disabled) { + m_core->recordComputeIndirectDispatchToCmdStream( cmdStream, m_colorCopyPass.pipeline, - m_indirectArgumentBuffer, + m_copyPathWorkTileBuffer, 0, { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_colorCopyPass.descriptorSet).vulkanHandle) }, vkcv::PushConstants(0)); } - else { - vkcv_log(vkcv::LogLevel::ERROR, "Unknown eMotionBlurMode enum option"); - m_core->recordComputeIndirectDispatchToCmdStream( + else if(mode == eMotionBlurMode::Disabled) { + return colorBuffer; + } + else if (mode == eMotionBlurMode::TileVisualisation) { + + vkcv::DescriptorWrites visualisationDescriptorWrites; + visualisationDescriptorWrites.sampledImageWrites = { + vkcv::SampledImageDescriptorWrite(0, colorBuffer) }; + visualisationDescriptorWrites.samplerWrites = { + vkcv::SamplerDescriptorWrite(1, m_nearestSampler) }; + visualisationDescriptorWrites.storageImageWrites = { + vkcv::StorageImageDescriptorWrite(2, m_renderTargets.outputColor)}; + visualisationDescriptorWrites.storageBufferWrites = { + vkcv::BufferDescriptorWrite(3, m_fullPathWorkTileBuffer), + vkcv::BufferDescriptorWrite(4, m_copyPathWorkTileBuffer)}; + + m_core->writeDescriptorSet(m_tileVisualisationPass.descriptorSet, visualisationDescriptorWrites); + + const uint32_t tileCount = + (m_core->getImageWidth(m_renderTargets.outputColor) + MotionBlurConfig::maxMotionTileSize - 1) / MotionBlurConfig::maxMotionTileSize * + (m_core->getImageHeight(m_renderTargets.outputColor) + MotionBlurConfig::maxMotionTileSize - 1) / MotionBlurConfig::maxMotionTileSize; + + const uint32_t dispatchCounts[3] = { + tileCount, + 1, + 1 }; + + m_core->recordComputeDispatchToCmdStream( cmdStream, - m_colorCopyPass.pipeline, - m_indirectArgumentBuffer, - 0, - { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_colorCopyPass.descriptorSet).vulkanHandle) }, + m_tileVisualisationPass.pipeline, + dispatchCounts, + { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_tileVisualisationPass.descriptorSet).vulkanHandle) }, vkcv::PushConstants(0)); } + else { + vkcv_log(vkcv::LogLevel::ERROR, "Unknown eMotionBlurMode enum option"); + return colorBuffer; + } return m_renderTargets.outputColor; } diff --git a/projects/indirect_dispatch/src/MotionBlur.hpp b/projects/indirect_dispatch/src/MotionBlur.hpp index 0158f328e82895d462d3dd87f82de60e5aee1052..13eff13b18ee186564e68f6a3790dceb2eaacae1 100644 --- a/projects/indirect_dispatch/src/MotionBlur.hpp +++ b/projects/indirect_dispatch/src/MotionBlur.hpp @@ -16,13 +16,15 @@ static const char* MotionVectorModeLabels[3] = { "Tile neighbourhood max" }; enum class eMotionBlurMode : int { - Default = 0, - Disabled = 1, - OptionCount = 2 }; + Default = 0, + Disabled = 1, + TileVisualisation = 2, + OptionCount = 3 }; -static const char* MotionBlurModeLabels[2] = { +static const char* MotionBlurModeLabels[3] = { "Default", - "Disabled" }; + "Disabled", + "Tile visualisation" }; class MotionBlur { public: @@ -64,8 +66,11 @@ private: ComputePassHandles m_motionVectorMaxPass; ComputePassHandles m_motionVectorMaxNeighbourhoodPass; ComputePassHandles m_motionVectorVisualisationPass; - ComputePassHandles m_indirectArgumentPass; ComputePassHandles m_colorCopyPass; + ComputePassHandles m_tileClassificationPass; + ComputePassHandles m_tileResetPass; + ComputePassHandles m_tileVisualisationPass; - vkcv::BufferHandle m_indirectArgumentBuffer; + vkcv::BufferHandle m_fullPathWorkTileBuffer; + vkcv::BufferHandle m_copyPathWorkTileBuffer; }; \ No newline at end of file diff --git a/projects/indirect_dispatch/src/MotionBlurConfig.hpp b/projects/indirect_dispatch/src/MotionBlurConfig.hpp index bdeb8acf988118fbc084595cc880f281594c62b1..c8201b256bae5169c1b80394e3067060eaacb00e 100644 --- a/projects/indirect_dispatch/src/MotionBlurConfig.hpp +++ b/projects/indirect_dispatch/src/MotionBlurConfig.hpp @@ -4,5 +4,7 @@ namespace MotionBlurConfig { const vk::Format motionVectorTileFormat = vk::Format::eR16G16Sfloat; const vk::Format outputColorFormat = vk::Format::eB10G11R11UfloatPack32; - const uint32_t maxMotionTileSize = 20; // must match "motionTileSize" in motionBlurConfig.inc + const uint32_t maxMotionTileSize = 24; // must match "motionTileSize" in motionBlurConfig.inc + const uint32_t maxWidth = 3840; + const uint32_t maxHeight = 2160; } \ No newline at end of file