From 40a58f3516fa1b5f7af46ccbfa49e5f9db5fe558 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Tue, 8 Jun 2021 17:02:29 +0200 Subject: [PATCH] [#70] Implement initial voxelization --- include/vkcv/Core.hpp | 5 +- include/vkcv/Image.hpp | 2 +- .../resources/shaders/compile.bat | 2 + .../resources/shaders/voxelization.frag | 27 ++++ .../resources/shaders/voxelization.vert | 18 +++ .../resources/shaders/voxelization_frag.spv | Bin 0 -> 2284 bytes .../resources/shaders/voxelization_vert.spv | Bin 0 -> 1692 bytes projects/cmd_sync_test/src/main.cpp | 137 +++++++++++++----- projects/first_mesh/src/main.cpp | 2 +- src/vkcv/Context.cpp | 7 +- src/vkcv/Core.cpp | 17 ++- src/vkcv/DescriptorManager.cpp | 3 +- src/vkcv/DescriptorManager.hpp | 3 +- src/vkcv/Image.cpp | 4 +- src/vkcv/ImageManager.cpp | 8 +- src/vkcv/ImageManager.hpp | 2 +- 16 files changed, 184 insertions(+), 53 deletions(-) create mode 100644 projects/cmd_sync_test/resources/shaders/voxelization.frag create mode 100644 projects/cmd_sync_test/resources/shaders/voxelization.vert create mode 100644 projects/cmd_sync_test/resources/shaders/voxelization_frag.spv create mode 100644 projects/cmd_sync_test/resources/shaders/voxelization_vert.spv diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 8a165adf..c21ee3d6 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -203,7 +203,7 @@ namespace vkcv * @return Image-Object */ [[nodiscard]] - Image createImage(vk::Format format, uint32_t width, uint32_t height, uint32_t depth = 1); + Image createImage(vk::Format format, uint32_t width, uint32_t height, uint32_t depth = 1, bool supportStorage = false, bool supportColorAttachment = false); /** TODO: * @param setDescriptions @@ -211,7 +211,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; @@ -259,5 +259,6 @@ namespace vkcv void submitCommandStream(const CommandStreamHandle handle); void prepareSwapchainImageForPresent(const CommandStreamHandle handle); void prepareImageForSampling(const CommandStreamHandle cmdStream, const ImageHandle image); + void prepareImageForStorage(const CommandStreamHandle cmdStream, const ImageHandle image); }; } diff --git a/include/vkcv/Image.hpp b/include/vkcv/Image.hpp index a1219ce4..e1eb78ee 100644 --- a/include/vkcv/Image.hpp +++ b/include/vkcv/Image.hpp @@ -45,7 +45,7 @@ namespace vkcv { Image(ImageManager* manager, const ImageHandle& handle); - static Image create(ImageManager* manager, vk::Format format, uint32_t width, uint32_t height, uint32_t depth); + static Image create(ImageManager* manager, vk::Format format, uint32_t width, uint32_t height, uint32_t depth, bool supportStorage, bool supportColorAttachment); }; diff --git a/projects/cmd_sync_test/resources/shaders/compile.bat b/projects/cmd_sync_test/resources/shaders/compile.bat index 516c2f2f..9ffc664a 100644 --- a/projects/cmd_sync_test/resources/shaders/compile.bat +++ b/projects/cmd_sync_test/resources/shaders/compile.bat @@ -2,4 +2,6 @@ %VULKAN_SDK%\Bin32\glslc.exe shader.frag -o frag.spv %VULKAN_SDK%\Bin32\glslc.exe shadow.vert -o shadow_vert.spv %VULKAN_SDK%\Bin32\glslc.exe shadow.frag -o shadow_frag.spv +%VULKAN_SDK%\Bin32\glslc.exe voxelization.vert -o voxelization_vert.spv +%VULKAN_SDK%\Bin32\glslc.exe voxelization.frag -o voxelization_frag.spv pause \ No newline at end of file diff --git a/projects/cmd_sync_test/resources/shaders/voxelization.frag b/projects/cmd_sync_test/resources/shaders/voxelization.frag new file mode 100644 index 00000000..91575b03 --- /dev/null +++ b/projects/cmd_sync_test/resources/shaders/voxelization.frag @@ -0,0 +1,27 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 passPos; + +layout(set=0, binding=0, r8) uniform image3D voxelImage; +layout(set=0, binding=1) uniform voxelizationInfo{ + float extent; +} voxelInfo; + +vec3 worldToVoxelCoordinates(vec3 world, float voxelExtent){ + return world / voxelExtent + 0.5f; +} + +ivec3 voxelCoordinatesToUV(vec3 voxelCoordinates, ivec3 voxelImageResolution){ + return ivec3(voxelCoordinates * voxelImageResolution); +} + +void main() { + vec3 voxelCoordinates = worldToVoxelCoordinates(passPos, voxelInfo.extent); + ivec3 voxeImageSize = imageSize(voxelImage); + ivec3 UV = voxelCoordinatesToUV(voxelCoordinates, voxeImageSize); + if(any(lessThan(UV, ivec3(0))) || any(greaterThanEqual(UV, voxeImageSize))){ + //return; + } + imageStore(voxelImage, UV, vec4(1)); +} \ No newline at end of file diff --git a/projects/cmd_sync_test/resources/shaders/voxelization.vert b/projects/cmd_sync_test/resources/shaders/voxelization.vert new file mode 100644 index 00000000..6914e951 --- /dev/null +++ b/projects/cmd_sync_test/resources/shaders/voxelization.vert @@ -0,0 +1,18 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inNormal; +layout(location = 2) in vec2 inUV; + +layout(location = 0) out vec3 passPos; + +layout( push_constant ) uniform constants{ + mat4 mvp; + mat4 model; +}; + +void main() { + gl_Position = mvp * vec4(inPosition, 1.0); + passPos = (model * vec4(inPosition, 1)).xyz; +} \ No newline at end of file diff --git a/projects/cmd_sync_test/resources/shaders/voxelization_frag.spv b/projects/cmd_sync_test/resources/shaders/voxelization_frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..2093865dba17592a0d8ba5d4372e6fdf6f578b85 GIT binary patch literal 2284 zcmZQ(Qf6mhU}WH8;AIG7fB-=TCI&_Z1_lsq2&Ih}7#O%2*udiMKEXbE#U&|vCZ+}; z9efPTAPOwU&%nmO!oUE=xrv#1APG$d1_l8JX0RAL0|Nsy12Y2?0|Ub$MvyvA26vx$ z#~`Qp;?#n~qQsKa_~MMjl+>d5{G_bZ<dR~L8ZM9;cYl9(AJ_Qgf`a(slFFRa_?*nV z)cBOlqSWM)%(7IFIu0atnR&@Mr76e?SQ%KrZh*Oq73^yUhVuNPoRpCKu>6YD9OwM} zqLj?M#FErvjj}Xj>oh}a29Q2(2B<m)1_o9JRt6ph28J?_2G@#`)VvY~kXfQIF(gAm z@<YSG29;$RTZ8qoGYDf*2MQ-v1`Y-hn4D*BVtQ&&YH@x}X-Q^2I2>6S*csGe@<?_- z^s+F3!nq)^xHurcm;t0#3#K-+DiLIcXI@%9NG%%!D+5Rl#7>1cAM7U`n0lx}kiYd9 z7#Kj&k_&b_3j-*^5qvfVQ>Y%WbAvOhQo-t287!dUIbaD;m@zYe{2v+yVzV&VpqXoj z#CK<a_(cxnKn4Z|4<z?0L&e+~n8AJkr6Z7fklU5uax4rWz9IuCWiv2<<U#I1mIv`c z@*pk33{2qks0dD(3}Chx12Y2~0|SEs0|SFN0}BHv-Gca_l&-+Q!ob1602Tv@gZP|K zK1husI5j}zLFzzqq6{ny{7~~ic?)Ew00RS93}&Vv)C`a~$P6KHzF`2{1(MTdU;(>H z8sumO278db8c;ui++oeY!T{of(gDa0IcOMx+yqjq%>eNmDDFXOL3~g+fx-}EHpqRt z5VILT>OpxQBnQ$j$-v2A#=ro!A0!4<2BtuKkY11;bFc^lSS`p75FZrQAYl;(CI&|a z1_m7lHU^L%of#MyK=#2fC`?=!7{F>kVFKa@L+u2WDIhn3+!6vZjG@6^hk=~|Bp=Ga zzyK0M#%2tx;CKY-11SfY_k)3nft7)Q0pu=Fynyl&EZjhRP+EuaL2(93>o7hj{6T3Q znGZ_OFg{2>C{4roAoZX$4dUBE(~mv_12~V`F)%ZL>;mx}8CV%W;S4HYL2&^J3y^w{ zKaCj}7(n76^&q!^_?8T8;B;rgz`(%EzyLM}BnMIh@()NHq#qPlmJAHwe3-$&0uFC0 z1_lO@7)UM1FCachEyRrs;IaiI2l9t40|Ns{4ir!J3=H6W4w3`;3B(7v10?6bz`y`1 z_dt3;av(LJZ~=+K^gDsWoPl8@11ke4eq9+D7(im6_@BkV0*-Gt1_lO@_zEcBoq>S? zB=((wnZXkjfeZ``zZh5;K;j+@3}7)(e1h08d%U3b!1&%!cdv)q>%+jn08#@IhuQ1P zz`y_!|H;4vHxp#vR|a;lyZoT;0Hqs{T9ADpHw7TM38coKfq?-e267XK4KfeL2hkum zf#M_(8Ydt=DExw;Zcb)kVF1a2_@MOsmw}PNf`O3%l#W611Bz>qm0S!A4CV~X;4%SJ zCxO_Yv<j+^Kz8#%;|-)o99(BZ;t`adBp4XL^;Q5h4M{REFo48hxC2~kFfd4g%RB}K zkUUJS3<CoLsN8|!MyOg@28eo){67XJ1`r?SZjk>#X#?bLP+10YD=43U>OT-0lt)1I z9mw5cNbUxexga&LFanj+Aa(iBd;}`TL1L{?H-PE{kRFhD9yG11FfcHH#6fNXu|aME E0Jogg#{d8T literal 0 HcmV?d00001 diff --git a/projects/cmd_sync_test/resources/shaders/voxelization_vert.spv b/projects/cmd_sync_test/resources/shaders/voxelization_vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..bbccee7abd853e0f78d16fecf37dccefc2a13c00 GIT binary patch literal 1692 zcmZQ(Qf6mhU}WH8;AJpofB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!N<T1qQG+e z3|wF~3j+f~ZenI0h{Makz#z%Mz@Wmwz@X2-z+l9{z`)GF%)rFJz;K9>fq{jAlfm65 z-Z982zBsiYu_&=5HNH3_F(tJqK0hfdHMyi1q=pNm#@*lF-N!XPxu77vxTG>CH9jXZ zFEu_TvnVyWB(p3Pq>ckgU1nZ#PH76V0#*hV24uIfGO#glGcYiu=fnr37KNo2m84dH z+{^|Q2eCnN`Nf$fnfZAPYz*vR^`P(oi)ZGQ1ZP&Ig4Ds}K>kY4iFeM)EO5yzE=kNw zPKE0Og%n7xG$#ix$I8IW016|J8LSMf41x>{49WR<Ae|tuGq5qRfW<)axn%_mY)~~I zH{|B0q~<U%Fo4Vu1}OluS;66*nHK<aHUr4tpztq9EG`bnFJ=JQ1B#2xJiq*++(eKO zU^Sq)$;=B40~zJPzzX&&hz$xO5DgOp*$ol{(J(QPzd>RkKf=U7Y>*fz%-tE7!RCR~ zc_8_Tm4Sf)q#opNkR8e(0!@safq_8)ECvY+kiE$IKzxus2e2AQ7=pxL`apJr%m>-+ z&cFf=A33N!AU-H;kolmn0r5d*faF2p0^)=83o|f*)2<>o6*GX@Vhqd-Yzzzx3JeSk z;tVVdAbUZ4kiSJ4SQt2<av&?Up?ppTP)=iDkYQi}=NgcDkeD1a?ZM0d<tPwVU|?b3 z0p}f1USwdfhVnsa2NcdAd-$OCfZPqT2gK(GS<1k`Ai=-_4nvT+Aa}_@;{X({APh2J zh=G9t<OWb!fy@W-LFo!429g(n%7fH{{3*`B0QNV?evrHb)K4IBkbV#!l=oro0r^oH z?4AaDka|U^e?V>m@j-D2G7F|3#0SL<NDSs5Rj3^>^FeV1G9Tm~P=N%p0~Ajn^9-SC zLE<3wAU-HALF&yISix}z3JZ{vKz96KU}6BJD@O)a29RGx85kHq{s)DjEj0YZ7#J8p z;vhcAol?;9Esz0Jnt<YyfdM22G7}~y%K#Ar*$Wc`r6-U&kXr*7*uiN=o&lmCq#h&> z3ag0>tYA4%+5*`PQUh`yDD0FN7{Fx*$bEJU%nTqtNF7KX<bE}%`$1s_axW;})EO8U zK;j@i$o(2<?$=~sU;v3ByI%_`hU|WAs2H;Qbr={JK>9)ILGsA%*JWT}0ND*v<Iljs j0J2+;fq?-e4#FV&K<0zY1Nj9M?;!cV42%pG42%o_!H|6w literal 0 HcmV?d00001 diff --git a/projects/cmd_sync_test/src/main.cpp b/projects/cmd_sync_test/src/main.cpp index a0fb29fa..c6cde4f4 100644 --- a/projects/cmd_sync_test/src/main.cpp +++ b/projects/cmd_sync_test/src/main.cpp @@ -63,16 +63,16 @@ int main(int argc, const char** argv) { indexBuffer.fill(mesh.vertexGroups[0].indexBuffer.data); - auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes; + auto& vertexAttributes = mesh.vertexGroups[0].vertexBuffer.attributes; - std::sort(attributes.begin(), attributes.end(), [](const vkcv::VertexAttribute& x, const vkcv::VertexAttribute& y) { + std::sort(vertexAttributes.begin(), vertexAttributes.end(), [](const vkcv::VertexAttribute& x, const vkcv::VertexAttribute& y) { return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); }); const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { - vkcv::VertexBufferBinding(attributes[0].offset, vertexBuffer.getVulkanHandle()), - vkcv::VertexBufferBinding(attributes[1].offset, vertexBuffer.getVulkanHandle()), - vkcv::VertexBufferBinding(attributes[2].offset, vertexBuffer.getVulkanHandle()) }; + vkcv::VertexBufferBinding(vertexAttributes[0].offset, vertexBuffer.getVulkanHandle()), + vkcv::VertexBufferBinding(vertexAttributes[1].offset, vertexBuffer.getVulkanHandle()), + vkcv::VertexBufferBinding(vertexAttributes[2].offset, vertexBuffer.getVulkanHandle()) }; const vkcv::Mesh loadedMesh(vertexBufferBindings, indexBuffer.getVulkanHandle(), mesh.vertexGroups[0].numIndices); @@ -116,7 +116,7 @@ int main(int argc, const char** argv) { windowWidth, windowHeight, trianglePass, - attributes, + vertexAttributes, { core.getDescriptorSet(descriptorSet).layout }, true); vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition); @@ -147,30 +147,6 @@ int main(int argc, const char** argv) { const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - const vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); - - const std::vector<glm::vec3> instancePositions = { - glm::vec3( 0.f, -2.f, 0.f), - glm::vec3( 3.f, 0.f, 0.f), - glm::vec3(-3.f, 0.f, 0.f), - glm::vec3( 0.f, 2.f, 0.f), - glm::vec3( 0.f, -5.f, 0.f) - }; - - std::vector<glm::mat4> modelMatrices; - std::vector<vkcv::DrawcallInfo> drawcalls; - std::vector<vkcv::DrawcallInfo> shadowDrawcalls; - for (const auto& position : instancePositions) { - modelMatrices.push_back(glm::translate(glm::mat4(1.f), position)); - drawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, { descriptorUsage })); - shadowDrawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, {})); - } - - modelMatrices.back() *= glm::scale(glm::mat4(1.f), glm::vec3(10.f, 1.f, 10.f)); - - std::vector<std::array<glm::mat4, 2>> mainPassMatrices; - std::vector<glm::mat4> mvpLight; - vkcv::ShaderProgram shadowShader; shadowShader.addShader(vkcv::ShaderStage::VERTEX, "resources/shaders/shadow_vert.spv"); shadowShader.addShader(vkcv::ShaderStage::FRAGMENT, "resources/shaders/shadow_frag.spv"); @@ -191,7 +167,7 @@ int main(int argc, const char** argv) { shadowMapResolution, shadowMapResolution, shadowPass, - attributes, + vertexAttributes, {}, false); const vkcv::PipelineHandle shadowPipe = core.createGraphicsPipeline(shadowPipeConfig); @@ -212,7 +188,79 @@ 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); + + const uint32_t voxelResolution = 32; + vkcv::Image voxelImage = core.createImage(vk::Format::eR8Unorm, voxelResolution, voxelResolution, voxelResolution, true); + + const vk::Format voxelizationDummyFormat = vk::Format::eR8Unorm; + vkcv::Image voxelizationDummyRenderTarget = core.createImage(voxelizationDummyFormat, voxelResolution, voxelResolution, 1, false, true); + + vkcv::ShaderProgram voxelizationShader; + voxelizationShader.addShader(vkcv::ShaderStage::VERTEX, "resources/shaders/voxelization_vert.spv"); + voxelizationShader.addShader(vkcv::ShaderStage::FRAGMENT, "resources/shaders/voxelization_frag.spv"); + voxelizationShader.reflectShader(vkcv::ShaderStage::VERTEX); + voxelizationShader.reflectShader(vkcv::ShaderStage::FRAGMENT); + + vkcv::PassConfig voxelizationPassConfig({ + vkcv::AttachmentDescription(vkcv::AttachmentOperation::DONT_CARE, vkcv::AttachmentOperation::DONT_CARE, voxelizationDummyFormat)}); + vkcv::PassHandle voxelizationPass = core.createPass(voxelizationPassConfig); + + std::vector<vkcv::DescriptorBinding> voxelizationDescriptorBindings = { + vkcv::DescriptorBinding(vkcv::DescriptorType::IMAGE_STORAGE, 1, vkcv::ShaderStage::FRAGMENT), + vkcv::DescriptorBinding(vkcv::DescriptorType::UNIFORM_BUFFER, 1, vkcv::ShaderStage::FRAGMENT)}; + vkcv::DescriptorSetHandle voxelizationDescriptorSet = core.createDescriptorSet(voxelizationDescriptorBindings); + + const vkcv::PipelineConfig voxelizationPipeConfig( + voxelizationShader, + voxelResolution, + voxelResolution, + voxelizationPass, + vertexAttributes, + { core.getDescriptorSet(voxelizationDescriptorSet).layout }, + false); + const vkcv::PipelineHandle voxelizationPipe = core.createGraphicsPipeline(voxelizationPipeConfig); + + struct VoxelizationInfo { + float extent; + }; + vkcv::Buffer voxelizationInfoBuffer = core.createBuffer<VoxelizationInfo>(vkcv::BufferType::UNIFORM, sizeof(VoxelizationInfo)); + const float voxelizationExtent = 10.f; + VoxelizationInfo voxelizationInfo; + voxelizationInfo.extent = voxelizationExtent; + voxelizationInfoBuffer.fill({ voxelizationInfo }); + + vkcv::DescriptorWrites voxelizationDescriptorWrites; + voxelizationDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(0, voxelImage.getHandle()) }; + voxelizationDescriptorWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(1, voxelizationInfoBuffer.getHandle()) }; + core.writeDescriptorSet(voxelizationDescriptorSet, voxelizationDescriptorWrites); + + const std::vector<glm::vec3> instancePositions = { + glm::vec3(0.f, -2.f, 0.f), + glm::vec3(3.f, 0.f, 0.f), + glm::vec3(-3.f, 0.f, 0.f), + glm::vec3(0.f, 2.f, 0.f), + glm::vec3(0.f, -5.f, 0.f) + }; + + const vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); + const vkcv::DescriptorSetUsage voxelizationDescriptorUsage(0, core.getDescriptorSet(voxelizationDescriptorSet).vulkanHandle); + + std::vector<glm::mat4> modelMatrices; + std::vector<vkcv::DrawcallInfo> drawcalls; + std::vector<vkcv::DrawcallInfo> shadowDrawcalls; + std::vector<vkcv::DrawcallInfo> voxelizationDrawcalls; + for (const auto& position : instancePositions) { + modelMatrices.push_back(glm::translate(glm::mat4(1.f), position)); + drawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, { descriptorUsage })); + shadowDrawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, {})); + voxelizationDrawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, { voxelizationDescriptorUsage })); + } + modelMatrices.back() *= glm::scale(glm::mat4(1.f), glm::vec3(10.f, 1.f, 10.f)); + + std::vector<std::array<glm::mat4, 2>> mainPassMatrices; + std::vector<glm::mat4> mvpLight; + std::vector<std::array<glm::mat4, 2>> voxelizationMatrices; auto start = std::chrono::system_clock::now(); const auto appStartTime = start; @@ -247,7 +295,7 @@ int main(int argc, const char** argv) { shadowProjectionSize, -shadowProjectionSize, shadowProjectionSize); - + glm::mat4 vulkanCorrectionMatrix(1.f); vulkanCorrectionMatrix[2][2] = 0.5; vulkanCorrectionMatrix[3][2] = 0.5; @@ -260,17 +308,29 @@ int main(int argc, const char** argv) { const glm::mat4 viewProjectionCamera = cameraManager.getCamera().getProjection() * cameraManager.getCamera().getView(); + const float voxelizationHalfExtent = 0.5f * voxelizationExtent; + const glm::mat4 voxelizationProjection = vulkanCorrectionMatrix * glm::ortho( + -voxelizationHalfExtent, + voxelizationHalfExtent, + -voxelizationHalfExtent, + voxelizationHalfExtent, + -voxelizationHalfExtent, + voxelizationHalfExtent); + mainPassMatrices.clear(); mvpLight.clear(); + voxelizationMatrices.clear(); for (const auto& m : modelMatrices) { mainPassMatrices.push_back({ viewProjectionCamera * m, m }); mvpLight.push_back(lightInfo.lightMatrix* m); + voxelizationMatrices.push_back({ voxelizationProjection * m, m }); } vkcv::PushConstantData pushConstantData((void*)mainPassMatrices.data(), 2 * sizeof(glm::mat4)); const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; - vkcv::PushConstantData shadowPushConstantData((void*)mvpLight.data(), sizeof(glm::mat4)); + const vkcv::PushConstantData shadowPushConstantData((void*)mvpLight.data(), sizeof(glm::mat4)); + const vkcv::PushConstantData voxelizationPushConstantData((void*)voxelizationMatrices.data(), 2 * sizeof(glm::mat4)); auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); @@ -282,6 +342,15 @@ int main(int argc, const char** argv) { shadowDrawcalls, { shadowMap.getHandle() }); + core.prepareImageForStorage(cmdStream, voxelImage.getHandle()); + core.recordDrawcallsToCmdStream( + cmdStream, + voxelizationPass, + voxelizationPipe, + voxelizationPushConstantData, + voxelizationDrawcalls, + { voxelizationDummyRenderTarget.getHandle() }); + core.prepareImageForSampling(cmdStream, shadowMap.getHandle()); core.recordDrawcallsToCmdStream( diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index 599eae46..bf296710 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -133,7 +133,7 @@ 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); + core.writeDescriptorSet(descriptorSet, setWrites); vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight).getHandle(); diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp index b53a1a2c..a0b2e0a3 100644 --- a/src/vkcv/Context.cpp +++ b/src/vkcv/Context.cpp @@ -275,7 +275,12 @@ namespace vkcv deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size()); deviceCreateInfo.ppEnabledLayerNames = validationLayers.data(); #endif - + + // FIXME: check if device feature is supported + vk::PhysicalDeviceFeatures deviceFeatures; + deviceFeatures.fragmentStoresAndAtomics = true; + deviceCreateInfo.pEnabledFeatures = &deviceFeatures; + // Ablauf // qCreateInfos erstellen --> braucht das Device // device erstellen diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 9ed83d2a..b7fc5aa9 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -217,7 +217,7 @@ namespace vkcv targetHandle = m_ImageManager->getVulkanImageView(handle); const bool isDepthImage = isDepthFormat(m_ImageManager->getImageFormat(handle)); const vk::ImageLayout targetLayout = - isDepthFormat ? vk::ImageLayout::eDepthStencilAttachmentOptimal : vk::ImageLayout::eColorAttachmentOptimal; + isDepthImage ? vk::ImageLayout::eDepthStencilAttachmentOptimal : vk::ImageLayout::eColorAttachmentOptimal; m_ImageManager->recordImageLayoutTransition(handle, targetLayout, cmdBuffer); } attachmentsViews.push_back(targetHandle); @@ -392,9 +392,9 @@ namespace vkcv return m_SamplerManager->createSampler(magFilter, minFilter, mipmapMode, addressMode); } - Image Core::createImage(vk::Format format, uint32_t width, uint32_t height, uint32_t depth) + Image Core::createImage(vk::Format format, uint32_t width, uint32_t height, uint32_t depth, bool supportStorage, bool supportColorAttachment) { - return Image::create(m_ImageManager.get(), format, width, height, depth); + return Image::create(m_ImageManager.get(), format, width, height, depth, supportStorage, supportColorAttachment); } DescriptorSetHandle Core::createDescriptorSet(const std::vector<DescriptorBinding>& bindings) @@ -402,10 +402,9 @@ namespace vkcv return m_DescriptorManager->createDescriptorSet(bindings); } - void Core::writeResourceDescription(DescriptorSetHandle handle, size_t setIndex, const DescriptorWrites &writes) { - m_DescriptorManager->writeResourceDescription( + void Core::writeDescriptorSet(DescriptorSetHandle handle, const DescriptorWrites &writes) { + m_DescriptorManager->writeDescriptorSet( handle, - setIndex, writes, *m_ImageManager, *m_BufferManager, @@ -465,4 +464,10 @@ namespace vkcv m_ImageManager->recordImageLayoutTransition(image, vk::ImageLayout::eShaderReadOnlyOptimal, cmdBuffer); }, nullptr); } + + void Core::prepareImageForStorage(const CommandStreamHandle cmdStream, const ImageHandle image) { + recordCommandsToStream(cmdStream, [image, this](const vk::CommandBuffer cmdBuffer) { + m_ImageManager->recordImageLayoutTransition(image, vk::ImageLayout::eGeneral, cmdBuffer); + }, nullptr); + } } diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index a2efecbe..7d3ebe6a 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 d8607b93..d18be64f 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, diff --git a/src/vkcv/Image.cpp b/src/vkcv/Image.cpp index f861daeb..9f7fdadc 100644 --- a/src/vkcv/Image.cpp +++ b/src/vkcv/Image.cpp @@ -19,9 +19,9 @@ namespace vkcv{ } } - Image Image::create(ImageManager* manager, vk::Format format, uint32_t width, uint32_t height, uint32_t depth) + Image Image::create(ImageManager* manager, vk::Format format, uint32_t width, uint32_t height, uint32_t depth, bool supportStorage, bool supportColorAttachment) { - return Image(manager, manager->createImage(width, height, depth, format)); + return Image(manager, manager->createImage(width, height, depth, format, supportStorage, supportColorAttachment)); } vk::Format Image::getFormat() const { diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp index cdfd32b0..80849375 100644 --- a/src/vkcv/ImageManager.cpp +++ b/src/vkcv/ImageManager.cpp @@ -80,7 +80,7 @@ namespace vkcv { } } - ImageHandle ImageManager::createImage(uint32_t width, uint32_t height, uint32_t depth, vk::Format format) + ImageHandle ImageManager::createImage(uint32_t width, uint32_t height, uint32_t depth, vk::Format format, bool supportStorage, bool supportColorAttachment) { const vk::PhysicalDevice& physicalDevice = m_core->getContext().getPhysicalDevice(); @@ -90,6 +90,12 @@ namespace vkcv { vk::ImageUsageFlags imageUsageFlags = ( vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst ); + if (supportStorage) { + imageUsageFlags |= vk::ImageUsageFlagBits::eStorage; + } + if (supportColorAttachment) { + imageUsageFlags |= vk::ImageUsageFlagBits::eColorAttachment; + } const bool isDepthFormat = isDepthImageFormat(format); diff --git a/src/vkcv/ImageManager.hpp b/src/vkcv/ImageManager.hpp index b9fccb25..316ad231 100644 --- a/src/vkcv/ImageManager.hpp +++ b/src/vkcv/ImageManager.hpp @@ -67,7 +67,7 @@ namespace vkcv { ImageManager& operator=(ImageManager&& other) = delete; ImageManager& operator=(const ImageManager& other) = delete; - ImageHandle createImage(uint32_t width, uint32_t height, uint32_t depth, vk::Format format); + ImageHandle createImage(uint32_t width, uint32_t height, uint32_t depth, vk::Format format, bool supportStorage, bool supportColorAttachment); ImageHandle createSwapchainImage(); -- GitLab