From e04c0843123b1b7a4121d01ff27fd7b40a899dde Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Fri, 21 Aug 2020 17:27:54 +0200 Subject: [PATCH] Use push constants for fixed object data, some minor code cleanup --- data/shaders/glsl/oit/geometry.frag | 19 ++- data/shaders/glsl/oit/geometry.frag.spv | Bin 2156 -> 2140 bytes data/shaders/glsl/oit/geometry.vert | 9 +- data/shaders/glsl/oit/geometry.vert.spv | Bin 1656 -> 1640 bytes data/shaders/hlsl/oit/geometry.frag | 22 ++-- data/shaders/hlsl/oit/geometry.frag.spv | Bin 2080 -> 2012 bytes data/shaders/hlsl/oit/geometry.vert | 12 +- data/shaders/hlsl/oit/geometry.vert.spv | Bin 1304 -> 1224 bytes examples/oit/oit.cpp | 146 +++++++++--------------- 9 files changed, 80 insertions(+), 128 deletions(-) diff --git a/data/shaders/glsl/oit/geometry.frag b/data/shaders/glsl/oit/geometry.frag index a8fff040..9a582043 100644 --- a/data/shaders/glsl/oit/geometry.frag +++ b/data/shaders/glsl/oit/geometry.frag @@ -11,25 +11,24 @@ struct Node uint next; }; -layout (set = 0, binding = 1) uniform ObjectUBO -{ - mat4 model; - vec4 color; -} objectUBO; - -layout (set = 0, binding = 2) buffer GeometrySBO +layout (set = 0, binding = 1) buffer GeometrySBO { uint count; uint maxNodeCount; }; -layout (set = 0, binding = 3, r32ui) uniform uimage2D headIndexImage; +layout (set = 0, binding = 2, r32ui) uniform uimage2D headIndexImage; -layout (set = 0, binding = 4) buffer LinkedListSBO +layout (set = 0, binding = 3) buffer LinkedListSBO { Node nodes[]; }; +layout(push_constant) uniform PushConsts { + mat4 model; + vec4 color; +} pushConsts; + void main() { // Increase the node count @@ -42,7 +41,7 @@ void main() uint prevHeadIdx = imageAtomicExchange(headIndexImage, ivec2(gl_FragCoord.xy), nodeIdx); // Store node data - nodes[nodeIdx].color = objectUBO.color; + nodes[nodeIdx].color = pushConsts.color; nodes[nodeIdx].depth = gl_FragCoord.z; nodes[nodeIdx].next = prevHeadIdx; } diff --git a/data/shaders/glsl/oit/geometry.frag.spv b/data/shaders/glsl/oit/geometry.frag.spv index ddc2d691fc34a3ec4391d9b295d8f6d37acd384f..f7563e991303a37f219b7c4afb295357b9fc1ba4 100644 GIT binary patch delta 393 zcmYL@KTZN+6vXF!AM36g*Fa)oL4nau8{;3MAjk?@tBI8tuu_winhV&Nue9O>#&8Eu z!40(V2+jbD#V>DW-uq_vr#h`>-tEMIAw`0#&+Nm}>tXTGe|julituFz>GQvJ?$#{a zxrVtgbnoUv&EHR6{jZHy0UVMxDmdaiCd#(xn@c_Sr}S>N1NOLIp*~w?6?CYLG>G2! zICU?t`!&w~B5NYjZt@+CEmCnSyv3WN7S##qEb80T3CVe``Yzcf`mAnLeNL3;h-aV7 tsrN}n^nQbM;klpRmfaWh>Ms2N*hQUziq<(VNm-<0{kw{k55i4S{{x)(Cv*S+ delta 393 zcmYL@Jx;?w6olvP+SrOP3KCL^2!)>x8pKaT5)xtuL>UPw6%`-~XlS5DoMB525ux0H zjvH_UIxfJB6(_bny_vV;S^w03>zQ}E31CS1UVdg%tBvoT9`0Wz#Tens4r|X#>)f@u zFmWyO;njUu6xRLC<`p8G0N5dVD!)x_vq%4Dw~q3N^cX$nR9w3)`u0Kt`}8aHy~QrV z8MToXQT}{>Ca?S|XEFPZrxvTK6W)`?TZihD^yh_L>XhV&%fddj{#O?%qq0G%l}XA= thV%y{Bl>=W4B#;==dwGeS9f*S2-riD3l*(#UXZFt;ex10`%%c#=06soCBFaw diff --git a/data/shaders/glsl/oit/geometry.vert b/data/shaders/glsl/oit/geometry.vert index 4ed12046..e53b0c75 100644 --- a/data/shaders/glsl/oit/geometry.vert +++ b/data/shaders/glsl/oit/geometry.vert @@ -8,14 +8,13 @@ layout (set = 0, binding = 0) uniform RenderPassUBO mat4 view; } renderPassUBO; -layout (set = 0, binding = 1) uniform ObjectUBO -{ - mat4 model; +layout(push_constant) uniform PushConsts { + mat4 model; vec4 color; -} objectUBO; +} pushConsts; void main() { - mat4 PVM = renderPassUBO.projection * renderPassUBO.view * objectUBO.model; + mat4 PVM = renderPassUBO.projection * renderPassUBO.view * pushConsts.model; gl_Position = PVM * vec4(inPos, 1.0); } diff --git a/data/shaders/glsl/oit/geometry.vert.spv b/data/shaders/glsl/oit/geometry.vert.spv index a7d75996acb42664a8445e44bba7732445e7eddb..1784d170012999c986556b2f8348fe27067a70f7 100644 GIT binary patch delta 701 zcmX|8O-lk%6ur+GKQbjE%F2(Ntjx@;RzXxmglz&N5L&q!N(c=gV)J z+O%oYs!h~6&o_=7&pYRxx%a*|KZ(yo(h3!#B1+;ClN~Qv3l~JB=v_U>>x16SNvGZG z_q^}j(%o2zge4*lV%N9Ly4!8I-M)Jd2^YS9u2Nav?zpKB>8P zW(tK?!7N10LDs+upwB_6i^k(1%$5L=$0O#e{+Ina( ehr-<30@$3HV|Z2YHo&XmfjBHRbHBKtJ>VZx6*>6; literal 1656 zcmZ9M*-jKu5QYy7GvWp!vZx3RC@v^^p~l3xo4^HzQ6jenp<~(%(`05`;+3zUkK|K% zW8(L9_aUukQe9Plt^J?QG=`Utg)kIG`P~WSnFzxmA)E}YLa%RbZ?5$R`)haa6)9t( zQ6!o(9w_IGAP2iyS9=LrK^pvq(Z5J+l2OlT5<5Yxz4MA#i&-JONxS=Luf5yvzkR-i z->PuTaM;T~rh9`dXF`h#^PT@WOTQSm$7yu$zaC8@GvHhAEsuRm%({boKkcCHX`Vgz z@=o4ETYDaz*J_=UfPLt^Yp1=Pv^Pk<;)0gAwz0gQ70b5ZCjql>foI*pcJ?jBrJ{_< z5wRDY?C@pQAMAGb(xaG68~fDh9L3~Ljy>`!*IAd5=nZ_i@idVQp3z?}(0?&+?@W(<%D{=UOHv%Q13Tl5#fJnkmPo;V}=_1z*CXE-5i>4U&$Fjk1BrRsVt&KUPSA0-{LdqvNl@`ca;(vw#%iGxWQGpD zm%hDbd5)sR^b?-PD_?vb-?`d~@l)uyY8 zn7my^+o#MK30JU(5OMSMS1Qas%)N$$@coJX*RZU0_I#xQSSAzHxc|L0@CH5NDg? V`^fWc#Jlr-+*RMaKit>@ geometrySBO : register(u2); +RWStructuredBuffer geometrySBO : register(u1); -RWTexture2D headIndexImage : register(u3); +RWTexture2D headIndexImage : register(u2); -RWStructuredBuffer nodes : register(u4); +RWStructuredBuffer nodes : register(u3); + +struct PushConsts { + float4x4 model; + float4 color; +}; +[[vk::push_constant]] PushConsts pushConsts; [earlydepthstencil] void main(VSOutput input) @@ -49,7 +47,7 @@ void main(VSOutput input) InterlockedExchange(headIndexImage[uint2(input.Pos.xy)], nodeIdx, prevHeadIdx); // Store node data - nodes[nodeIdx].color = objectUBO.color; + nodes[nodeIdx].color = pushConsts.color; nodes[nodeIdx].depth = input.Pos.z; nodes[nodeIdx].next = prevHeadIdx; } diff --git a/data/shaders/hlsl/oit/geometry.frag.spv b/data/shaders/hlsl/oit/geometry.frag.spv index 3fd22787f3fca4d56895ba8e37c572c85d032a96..01fd554d80b3f81881c03d2980869acc253a115a 100644 GIT binary patch literal 2012 zcmZvbSx*yT6o$X9XjK+j#08udceE-hqNriHsN9Ikh1az+P!c+A+G$e$m4C_`|A0$k z;`_|ZX-4Bm4(EH{v!8ET$gfN|mvhcdx=sD(%(#5Y6k?2Z%9UMFntP{t9Ad~zrd=WC zlw^EAt9wCzCF##{D!Fq)&PAuap#JgGLDV0%qG3PqcZP?DLBHMzx}6~EpC0V&%eNHQ z$#UhCQwrDW4#P;g>?Sh(jNWzqU^g|zIjDW~SKhK>(jM0Q`f;au6bP5%OwP4~roR{Z z!Dufrlw8G~G5`PcOhK9B&Y0IQy@ENd?n$>VZ5+GvgI?6maO^M)MvN5as(_Vy5aWtA zm-hUAIB4&7!$H&xqxu-&7U##0(^2e+G&SLJ8@v%K5GYKCl7XJ%G$x$`6k}R9q6L7lBh99emK56@?4PS4S5&hi04>bLkt{( z-QL0M##!F!j32$?Hz%Riq%^fW331fqST1V8SuNYY*@-bO`E8J=IOdqie5{`>apWbA ze&*%R8+a1VYKrNbgMCKYlaK>D_@abk{>O@ccV-29 zViu%{fxE0tvnyiA3vY*eRYJ_Al*D&Ik&7|!#21yr#W<;zyq$5@3va@k(hIu>llO`= zb>J3-uSye}V#66{~(QI)Ps$OZphdw(d+`6YjBk0fyP%6(t;YtoM;^owwqtD_j+U`>MkmA*{g z;E9C2!PD#4bcUz8W3w6PV_SXkPR}Il(t2k<>nYEiyxnsN`)4o2qTgr+czi!77jL;C n$?leSej&-mQioW0{B4&n|MBDZiXS}v|I}V=Kj`1u#D?S#dWMEo literal 2080 zcmZvb*-leY6owB&>ntFn1GNQb6z35&f)~h*M2Ybl=m9mhCACf9t$ZnOd;y2V#P2&j z%N&TiSzUYm|C;vN`waBY9!iqFBuP#t3;erAlKvbS$ZXl6q?`<*-8a@hHYNIz;bb7g zNb+xgg#7@&5_$ut5lImh&EwCd?+ zbYS+g+4|gSqpf01OO%ph_~bR;zF+IKyPKVEJFPEux3<#u{BqiAq@DKO8da@n|3%FF zVy?|rx7k6LLBx79*nLeaFLNr(aTsoUU*2-!EV6Uosn36GtZ%2-B{CgFe@NHsE6sYk zyV4^{pvS`hKRsIzn)t!wI67>5)po@!0<+h8y3_f94$OONrn?>~%XLDV++T9Lc*o1s z(%-&@5N&5XgSf)3u{TcJITU$qdGpA7_9Cw>?;DY~pCYd<@4I-FbX037j%~eHQbGbdzGc*1a`zm5>dF@fe75>&P^5X~W z32ghEpz0*LicFGgD$~6?n8H4dE#}-R{Hp`25Npq3RsPSQ%_*jD+^y%C26g6Q#yJmd zm3-mDkjgR#?K<`UDcpsi*6D9m|u zjhHIhy*@RxG3Fj)H-mOw-l6l8)4qV#N87lIXzPe+UqZ`SOZ#$en_~gn8T!5IqwQ>b zqhWh)zdx6}XYqRr-m|#xLmrUH{@uH($WPcS=x4;*!&OB8MQ)~szJ^%O_vD*Xe}}XG zIYi#KC8v(K>+FkhzBg+acLS0CNpMdv(7`edl}|v0ugI zxf;Yc^E-(AQ(loXzl%60aeMuipWz;Rxj2J;EE40r+((?fXO8}z(E~)zv+DN{apw9N zuYS%s#Pxkc7Vq;BQk<`M{TM06TE|#%{bQa_4*2=K>L>0QeleSvk@^qQc!c}~vJ8W` diff --git a/data/shaders/hlsl/oit/geometry.vert b/data/shaders/hlsl/oit/geometry.vert index f4b5c940..c1d114f3 100644 --- a/data/shaders/hlsl/oit/geometry.vert +++ b/data/shaders/hlsl/oit/geometry.vert @@ -13,13 +13,11 @@ struct RenderPassUBO cbuffer renderPassUBO : register(b0) { RenderPassUBO renderPassUBO; } -struct ObjectUBO -{ - float4x4 model; - float4 color; +struct PushConsts { + float4x4 model; + float4 color; }; - -cbuffer objectUBO : register(b1) { ObjectUBO objectUBO; } +[[vk::push_constant]] PushConsts pushConsts; struct VSOutput { @@ -29,6 +27,6 @@ struct VSOutput VSOutput main(VSInput input) { VSOutput output = (VSOutput)0; - output.Pos = mul(renderPassUBO.projection, mul(renderPassUBO.view, mul(objectUBO.model, input.Pos))); + output.Pos = mul(renderPassUBO.projection, mul(renderPassUBO.view, mul(pushConsts.model, input.Pos))); return output; } diff --git a/data/shaders/hlsl/oit/geometry.vert.spv b/data/shaders/hlsl/oit/geometry.vert.spv index 9ff7f93aaaa514af553d188fced6a858401c5a82..d7b082611a78bc30541b6dc3832330a1cf1758af 100644 GIT binary patch literal 1224 zcmZva+fEZv6o$7g6h#FQIe4m5xHM_JA|^&7dI8+n#=`?tn1mXfX=VzBx8QNTA@TdB zv&~T5WX)Rtzs`%cTf0jk+zKJAgdM)Vwa}`Wc7^q>2EusSKS$$CyM-9h=5G=G9b%EV z1?=hNB<&Yzc9IsuQCWWbFbJVj`*4Rj7kQnk#^;+UuruDANs<3ZkEi3D?y~lDo{Mq% zOTRTb=znW3SJPKB4bRKdk9k&3N7=Oh7nJ5(bG9Wr<|pY{gR{?ZewG(#JKsi6VkxrC z^d94^e=#ch!@-xMuSbJVub}WP+_>8T*t^};$rGE~t^tZL z*`nJrT5RqHU+wV-Be5+_@h_TKT^YwdQ zXOS1Lq3vUR@k4aG#_LpC$L_&ALTekdfwqTr#hYkrir;{p!QX)~Vte|#Ge&GrefAZ{ zp7z~iJNxMK+4ncmTj;mMI_EZG{ytrtSjOEKd-9G43gLjPt%R?iseeeR{jg qbHsU@wfv3CUlHRBFA(RDk6eN+Z@tL%uoJ{t-f>5Fl)Glb*T^4%fKVp@ literal 1304 zcmZvbT~8BH5QYye6h#FQ`S7c5<};>QmtuoorJB@4m$FZ{XQnD9K? zow#j0WI8kNyl3V;)6#BjFQzn?Qd&;$`1Gu%R*kf)-0Dh##xcGcj>g6q3 z?ne1f>-Om2|JPgfm8Rm<9+UX&=JAGu4WA2{2RW`|eV|-WE&3lcy^P6>Z z>*_qJ6cTW@CvFOJA5XC(`nq3_-)G#jhxb0uV6*q+#XY?z<{k1vG2dn1*lX0AShH{N zqHpZJsVBbA=;bUiXKfHK;WKO#1@73~e(QWb#%Gw?-`DvQVo&7D#MZZ{ui)+B{Vt#G zOHAw5ZxqX@xl=U+SM70Mt{TPUuHxm2nLooj(^=+g_;#JI!F*2K16ju#%h|x&!xe|A*zt0qBzrdX5{xo@Nd5KvI z-YeqZx!d5qCbky5H^l0l?dSi6wclt|$6HJ-;(=wv;`R)zN1S2m`NZygr`TU!xrf~Y DwHi^W diff --git a/examples/oit/oit.cpp b/examples/oit/oit.cpp index 8fcb6fc5..98641deb 100644 --- a/examples/oit/oit.cpp +++ b/examples/oit/oit.cpp @@ -13,8 +13,6 @@ #include "VulkanglTFModel.h" #define ENABLE_VALIDATION false -#define SPHERE_COUNT 5 * 5 * 5 -#define CUBE_COUNT 2 #define NODE_COUNT 20 class VulkanExample : public VulkanExampleBase @@ -27,7 +25,6 @@ public: struct { vks::Buffer renderPass; - vks::Buffer objects; } uniformBuffers; struct Node { @@ -54,10 +51,10 @@ public: glm::mat4 view; } renderPassUBO; - struct { + struct ObjectData { glm::mat4 model; glm::vec4 color; - } objectUBO; + }; struct { VkDescriptorSetLayout geometry; @@ -103,7 +100,6 @@ public: destroyGeometryPass(); uniformBuffers.renderPass.destroy(); - uniformBuffers.objects.destroy(); } void getEnabledFeatures() override @@ -171,49 +167,6 @@ private: sizeof(renderPassUBO))); VK_CHECK_RESULT(uniformBuffers.renderPass.map()); - - // This example has many object and the information of objects will be stored in one buffer. - // This buffer will be used for the uniform buffer dynamic. - // So we need to calculate a object uniform buffer size based on minUniformBufferOffsetAlignment. - objectUniformBufferSize = - (sizeof(objectUBO) + deviceProperties.limits.minUniformBufferOffsetAlignment) & ~(deviceProperties.limits.minUniformBufferOffsetAlignment - 1); - - // Create an uniform buffer for objects. - VK_CHECK_RESULT(vulkanDevice->createBuffer( - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - &uniformBuffers.objects, - objectUniformBufferSize * (SPHERE_COUNT + CUBE_COUNT))); - - VK_CHECK_RESULT(uniformBuffers.objects.map()); - - // Set up the scene. - uint8_t* objectUniformBufferData = static_cast(uniformBuffers.objects.mapped); - assert(SPHERE_COUNT == 5 * 5 * 5); - for (int i = 0; i != 5; i++) - { - for (int j = 0; j != 5; j++) - { - for (int k = 0; k != 5; k++) - { - auto T = glm::translate(glm::mat4(1.0f), glm::vec3(i - 2, j - 2, k - 2)); - auto S = glm::scale(glm::mat4(1.0f), glm::vec3(0.3f)); - objectUBO.model = T * S; - objectUBO.color = glm::vec4(1.0f, 0.0f, 0.0f, 0.5f); - memcpy(objectUniformBufferData, &objectUBO, sizeof(objectUBO)); - objectUniformBufferData += objectUniformBufferSize; - } - } - } - for (auto i = 0; i != CUBE_COUNT; ++i) - { - auto T = glm::translate(glm::mat4(1.0f), glm::vec3(3.0f * i - 1.5f, 0.0f, 0.0f)); - auto S = glm::scale(glm::mat4(1.0f), glm::vec3(0.2f)); - objectUBO.model = T * S; - objectUBO.color = glm::vec4(0.0f, 0.0f, 1.0f, 0.5f); - memcpy(objectUniformBufferData, &objectUBO, sizeof(objectUBO)); - objectUniformBufferData += objectUniformBufferSize; - } } void prepareGeometryPass() @@ -222,14 +175,14 @@ private: subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; // Geometry render pass doesn't need any output attachment. - auto renderPassInfo = vks::initializers::renderPassCreateInfo(); + VkRenderPassCreateInfo renderPassInfo = vks::initializers::renderPassCreateInfo(); renderPassInfo.attachmentCount = 0; renderPassInfo.subpassCount = 1; renderPassInfo.pSubpasses = &subpassDescription; VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassInfo, nullptr, &geometryPass.renderPass)); - // Geometry framebuffer doesn't need any output attachment. + // Geometry frame buffer doesn't need any output attachment. VkFramebufferCreateInfo fbufCreateInfo = vks::initializers::framebufferCreateInfo(); fbufCreateInfo.renderPass = geometryPass.renderPass; fbufCreateInfo.attachmentCount = 0; @@ -314,8 +267,8 @@ private: VK_CHECK_RESULT(geometryPass.linkedList.map()); - // Change HeadInex image's layout from UNDEFINED to GENERAL - auto cmdBufAllocInfo = vks::initializers::commandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1); + // Change HeadIndex image's layout from UNDEFINED to GENERAL + VkCommandBufferAllocateInfo cmdBufAllocInfo = vks::initializers::commandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1); VkCommandBuffer cmdBuf; VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocInfo, &cmdBuf)); @@ -323,7 +276,7 @@ private: VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo(); VK_CHECK_RESULT(vkBeginCommandBuffer(cmdBuf, &cmdBufInfo)); - auto barrier = vks::initializers::imageMemoryBarrier(); + VkImageMemoryBarrier barrier = vks::initializers::imageMemoryBarrier(); barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -336,7 +289,7 @@ private: VK_CHECK_RESULT(vkEndCommandBuffer(cmdBuf)); - auto submitInfo = vks::initializers::submitInfo(); + VkSubmitInfo submitInfo = vks::initializers::submitInfo(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cmdBuf; @@ -353,37 +306,33 @@ private: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0), - // ObjectUBO - vks::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, - 1), // AtomicSBO vks::initializers::descriptorSetLayoutBinding( VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT, - 2), + 1), // headIndexImage vks::initializers::descriptorSetLayoutBinding( VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT, - 3), + 2), // LinkedListSBO vks::initializers::descriptorSetLayoutBinding( VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT, - 4), + 3), }; - auto descriptorLayoutCreateInfo = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); - - VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayoutCreateInfo, nullptr, &descriptorSetLayouts.geometry)); + VkDescriptorSetLayoutCreateInfo descriptorLayoutCI = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); + VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayoutCI, nullptr, &descriptorSetLayouts.geometry)); // Create a geometry pipeline layout. - auto pipelineLayoutCreateInfo = - vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.geometry, 1); - - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayouts.geometry)); + VkPipelineLayoutCreateInfo pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.geometry, 1); + // Static object data passed using push constants + VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(ObjectData), 0); + pipelineLayoutCI.pushConstantRangeCount = 1; + pipelineLayoutCI.pPushConstantRanges = &pushConstantRange; + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayouts.geometry)); // Create a color descriptor set layout. setLayoutBindings = { @@ -399,15 +348,12 @@ private: 1), }; - descriptorLayoutCreateInfo = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); - - VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayoutCreateInfo, nullptr, &descriptorSetLayouts.color)); + descriptorLayoutCI = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); + VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayoutCI, nullptr, &descriptorSetLayouts.color)); // Create a color pipeline layout. - pipelineLayoutCreateInfo = - vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.color, 1); - - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayouts.color)); + pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.color, 1); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayouts.color)); } void preparePipelines() @@ -503,29 +449,23 @@ private: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.renderPass.descriptor), - // Binding 1: ObjectUBO - vks::initializers::writeDescriptorSet( - descriptorSets.geometry, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - 1, - &uniformBuffers.objects.descriptor), // Binding 2: GeometrySBO vks::initializers::writeDescriptorSet( descriptorSets.geometry, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - 2, + 1, &geometryPass.geometry.descriptor), // Binding 3: headIndexImage vks::initializers::writeDescriptorSet( descriptorSets.geometry, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - 3, + 2, &geometryPass.headIndex.descriptor), // Binding 4: LinkedListSBO vks::initializers::writeDescriptorSet( descriptorSets.geometry, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - 4, + 3, &geometryPass.linkedList.descriptor) }; @@ -609,19 +549,37 @@ private: vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.geometry); uint32_t dynamicOffset = 0; models.sphere.bindBuffers(drawCmdBuffers[i]); - for (auto j = 0; j != SPHERE_COUNT; ++j) + + // Render the scene + ObjectData objectData; + + vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.geometry, 0, 1, &descriptorSets.geometry, 0, nullptr); + objectData.color = glm::vec4(1.0f, 0.0f, 0.0f, 0.5f); + for (int32_t x = 0; x < 5; x++) { - vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.geometry, 0, 1, &descriptorSets.geometry, 1, &dynamicOffset); - models.sphere.draw(drawCmdBuffers[i]); - dynamicOffset += objectUniformBufferSize; + for (int32_t y = 0; y < 5; y++) + { + for (int32_t z = 0; z < 5; z++) + { + glm::mat4 T = glm::translate(glm::mat4(1.0f), glm::vec3(x - 2, y - 2, z - 2)); + glm::mat4 S = glm::scale(glm::mat4(1.0f), glm::vec3(0.3f)); + objectData.model = T * S; + vkCmdPushConstants(drawCmdBuffers[i], pipelineLayouts.geometry, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(ObjectData), &objectData); + models.sphere.draw(drawCmdBuffers[i]); + } + } } - models.cube.bindBuffers(drawCmdBuffers[i]); - for (auto j = 0; j != CUBE_COUNT; ++j) + + objectData.color = glm::vec4(0.0f, 0.0f, 1.0f, 0.5f); + for (uint32_t x = 0; x < 2; x++) { - vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.geometry, 0, 1, &descriptorSets.geometry, 1, &dynamicOffset); + glm::mat4 T = glm::translate(glm::mat4(1.0f), glm::vec3(3.0f * x - 1.5f, 0.0f, 0.0f)); + glm::mat4 S = glm::scale(glm::mat4(1.0f), glm::vec3(0.2f)); + objectData.model = T * S; + vkCmdPushConstants(drawCmdBuffers[i], pipelineLayouts.geometry, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(ObjectData), &objectData); models.cube.draw(drawCmdBuffers[i]); - dynamicOffset += objectUniformBufferSize; } + vkCmdEndRenderPass(drawCmdBuffers[i]); // Make a pipeline barrier to guarantee the geometry pass is done