diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index d44c50161db32ba386ad21926269dea907e35352..4a51b24f5c978daebc5116e20b527252c8063d61 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -224,7 +224,7 @@ namespace vkcv */ [[nodiscard]] DescriptorSetHandle createDescriptorSet(const std::vector<DescriptorBinding> &bindings); - void writeResourceDescription(DescriptorSetHandle handle, size_t setIndex, const DescriptorWrites& writes); + void writeDescriptorSet(DescriptorSetHandle handle, const DescriptorWrites& writes); DescriptorSet getDescriptorSet(const DescriptorSetHandle handle) const; @@ -241,6 +241,13 @@ namespace vkcv const std::vector<DrawcallInfo> &drawcalls, const std::vector<ImageHandle> &renderTargets); + void recordComputeDispatchToCmdStream( + CommandStreamHandle cmdStream, + PipelineHandle computePipeline, + const uint32_t dispatchCount[3], + const std::vector<DescriptorSetUsage> &descriptorSetUsages, + const PushConstantData& pushConstantData); + /** * @brief end recording and present image */ diff --git a/projects/cmd_sync_test/src/main.cpp b/projects/cmd_sync_test/src/main.cpp index 3886a53d4127c983e7525c0f6e4ad467129f9ed0..2494793f3b4aff3dfa412ff9bbe27e4550ca8fe0 100644 --- a/projects/cmd_sync_test/src/main.cpp +++ b/projects/cmd_sync_test/src/main.cpp @@ -207,7 +207,7 @@ int main(int argc, const char** argv) { vkcv::SamplerDescriptorWrite(1, sampler), vkcv::SamplerDescriptorWrite(4, shadowSampler) }; setWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(2, lightBuffer.getHandle()) }; - core.writeResourceDescription(descriptorSet, 0, setWrites); + core.writeDescriptorSet(descriptorSet, setWrites); auto start = std::chrono::system_clock::now(); const auto appStartTime = start; diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index 00a77c761e8fe3d67b4724cd0f1ddfa28f3edcb3..15bb872ce21d9042a6e606e791daab54344d128d 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -130,9 +130,9 @@ int main(int argc, const char** argv) { }; vkcv::DescriptorWrites setWrites; - setWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, texture.getHandle()) }; - setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, sampler) }; - core.writeResourceDescription(descriptorSet, 0, setWrites); + setWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, texture.getHandle()) }; + setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, sampler) }; + core.writeDescriptorSet(descriptorSet, setWrites); vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight).getHandle(); diff --git a/projects/first_triangle/shaders/comp.spv b/projects/first_triangle/shaders/comp.spv index 622ced351097932ea7f7eb1451e9433bc017812d..b414e36b2bea66dab00746298e536d029091e0fd 100644 Binary files a/projects/first_triangle/shaders/comp.spv and b/projects/first_triangle/shaders/comp.spv differ diff --git a/projects/first_triangle/shaders/compile.bat b/projects/first_triangle/shaders/compile.bat index b4521235c40fe5fb163bab874560c2f219b7517f..17743a7c49cdfc6e091c43a42a0adb755a731682 100644 --- a/projects/first_triangle/shaders/compile.bat +++ b/projects/first_triangle/shaders/compile.bat @@ -1,3 +1,4 @@ %VULKAN_SDK%\Bin32\glslc.exe shader.vert -o vert.spv %VULKAN_SDK%\Bin32\glslc.exe shader.frag -o frag.spv +%VULKAN_SDK%\Bin32\glslc.exe shader.comp -o comp.spv pause \ No newline at end of file diff --git a/projects/first_triangle/shaders/shader.comp b/projects/first_triangle/shaders/shader.comp index c63870daa744a7a8d533ad27d2ef18978e527093..fad6cd0815f2f09bf92dcc3171e2e3723f5466df 100644 --- a/projects/first_triangle/shaders/shader.comp +++ b/projects/first_triangle/shaders/shader.comp @@ -1,21 +1,25 @@ #version 440 -layout(local_size_x_id = 0, local_size_y_id = 1) in; // workgroup size defined with specialization constants. On cpp side there is associated SpecializationInfo entry in PipelineShaderStageCreateInfo -layout(push_constant) uniform Parameters { // specify push constants. on cpp side its layout is fixed at PipelineLayout, and values are provided via vk::CommandBuffer::pushConstants() - uint Width; - uint Height; - float a; -} params; +layout(std430, binding = 0) buffer testBuffer +{ + float test1[10]; + float test2[10]; + float test3[10]; +}; -layout(std430, binding = 0) buffer lay0 { float arr_y[]; }; -layout(std430, binding = 1) buffer lay1 { float arr_x[]; }; +layout( push_constant ) uniform constants{ + float pushConstant; +}; + +layout(local_size_x = 5) in; void main(){ - // drop threads outside the buffer dimensions. - if(params.Width <= gl_GlobalInvocationID.x || params.Height <= gl_GlobalInvocationID.y){ + + if(gl_GlobalInvocationID.x >= 10){ return; } - const uint id = params.Width*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x; // current offset - arr_y[id] += params.a*arr_x[id]; // saxpy + test1[gl_GlobalInvocationID.x] = gl_GlobalInvocationID.x; + test2[gl_GlobalInvocationID.x] = 69; // nice! + test3[gl_GlobalInvocationID.x] = pushConstant; } \ No newline at end of file diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index d79ece30d83bdbba7dd8570c0363c0da395be90e..ca10434bb9e486649411bcaac54c432744a914bb 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -128,6 +128,18 @@ int main(int argc, const char** argv) { computeShaderProgram, { core.getDescriptorSet(computeDescriptorSet).layout }); + struct ComputeTestBuffer { + float test1[10]; + float test2[10]; + float test3[10]; + }; + + vkcv::Buffer computeTestBuffer = core.createBuffer<ComputeTestBuffer>(vkcv::BufferType::STORAGE, 1); + + vkcv::DescriptorWrites computeDescriptorWrites; + computeDescriptorWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(0, computeTestBuffer.getHandle()) }; + core.writeDescriptorSet(computeDescriptorSet, computeDescriptorWrites); + /* * BufferHandle triangleVertices = core.createBuffer(vertices); * BufferHandle triangleIndices = core.createBuffer(indices); @@ -177,6 +189,17 @@ int main(int argc, const char** argv) { pushConstantData, { drawcall }, { swapchainInput }); + + const uint32_t dispatchSize[3] = { 2, 1, 1 }; + const float theMeaningOfLife = 42; + + core.recordComputeDispatchToCmdStream( + cmdStream, + computePipeline, + dispatchSize, + { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(computeDescriptorSet).vulkanHandle) }, + vkcv::PushConstantData((void*)&theMeaningOfLife, sizeof(theMeaningOfLife))); + core.prepareSwapchainImageForPresent(cmdStream); core.submitCommandStream(cmdStream); diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index afa450065a0bf26fe6ed2cab55e83e56b97b01cb..339f107252c20e1d22d9d5b4983016024ede45f1 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -305,6 +305,40 @@ namespace vkcv recordCommandsToStream(cmdStreamHandle, submitFunction, finishFunction); } + void Core::recordComputeDispatchToCmdStream( + CommandStreamHandle cmdStreamHandle, + PipelineHandle computePipeline, + const uint32_t dispatchCount[3], + const std::vector<DescriptorSetUsage>& descriptorSetUsages, + const PushConstantData& pushConstantData) { + + auto submitFunction = [&](const vk::CommandBuffer& cmdBuffer) { + + const auto pipelineLayout = m_PipelineManager->getVkPipelineLayout(computePipeline); + + cmdBuffer.bindPipeline(vk::PipelineBindPoint::eCompute, m_PipelineManager->getVkPipeline(computePipeline)); + for (const auto& usage : descriptorSetUsages) { + cmdBuffer.bindDescriptorSets( + vk::PipelineBindPoint::eCompute, + pipelineLayout, + usage.setLocation, + { usage.vulkanHandle }, + {}); + } + if (pushConstantData.sizePerDrawcall > 0) { + cmdBuffer.pushConstants( + pipelineLayout, + vk::ShaderStageFlagBits::eCompute, + 0, + pushConstantData.sizePerDrawcall, + pushConstantData.data); + } + cmdBuffer.dispatch(dispatchCount[0], dispatchCount[1], dispatchCount[2]); + }; + + recordCommandsToStream(cmdStreamHandle, submitFunction, nullptr); + } + void Core::endFrame() { if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) { return; @@ -409,10 +443,9 @@ namespace vkcv return m_DescriptorManager->createDescriptorSet(bindings); } - void Core::writeResourceDescription(DescriptorSetHandle handle, size_t setIndex, const DescriptorWrites &writes) { - m_DescriptorManager->writeResourceDescription( - handle, - setIndex, + void Core::writeDescriptorSet(DescriptorSetHandle handle, const DescriptorWrites &writes) { + m_DescriptorManager->writeDescriptorSet( + handle, writes, *m_ImageManager, *m_BufferManager, diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index 99e9928d21ad7e501634c93b59694d3c5faeaf6c..5c14b928d1d3a8cf435564c2f95cc379b10f1650 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -90,9 +90,8 @@ namespace vkcv vk::DescriptorType type; }; - void DescriptorManager::writeResourceDescription( + void DescriptorManager::writeDescriptorSet( const DescriptorSetHandle &handle, - size_t setIndex, const DescriptorWrites &writes, const ImageManager &imageManager, const BufferManager &bufferManager, diff --git a/src/vkcv/DescriptorManager.hpp b/src/vkcv/DescriptorManager.hpp index d8607b9312b25e71c7eb4af009efd92b834b40ec..d18be64f3b069af68cecce68f6fa623c81f8dfa4 100644 --- a/src/vkcv/DescriptorManager.hpp +++ b/src/vkcv/DescriptorManager.hpp @@ -23,9 +23,8 @@ namespace vkcv DescriptorSetHandle createDescriptorSet(const std::vector<DescriptorBinding> &descriptorBindings); - void writeResourceDescription( + void writeDescriptorSet( const DescriptorSetHandle &handle, - size_t setIndex, const DescriptorWrites &writes, const ImageManager &imageManager, const BufferManager &bufferManager,