From 526ed2da0e5ff1c8441ee2b22d64bbc2b22ee0d3 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 27 Oct 2019 17:53:31 +0100 Subject: [PATCH 1/9] Simplified offscreen sample --- data/shaders/offscreen/mirror.frag | 6 ++--- data/shaders/offscreen/mirror.frag.spv | Bin 2660 -> 2376 bytes examples/offscreen/offscreen.cpp | 29 ------------------------- 3 files changed, 2 insertions(+), 33 deletions(-) diff --git a/data/shaders/offscreen/mirror.frag b/data/shaders/offscreen/mirror.frag index 396f43db..9c784dc2 100644 --- a/data/shaders/offscreen/mirror.frag +++ b/data/shaders/offscreen/mirror.frag @@ -1,7 +1,6 @@ #version 450 layout (binding = 1) uniform sampler2D samplerColor; -layout (binding = 2) uniform sampler2D samplerColorMap; layout (location = 0) in vec2 inUV; layout (location = 1) in vec4 inPos; @@ -21,8 +20,7 @@ void main() // For demonstration purposes only const float blurSize = 1.0 / 512.0; - vec4 color = texture(samplerColorMap, inUV); - outFragColor = color * 0.25; + outFragColor = vec4(vec3(0.0), 1.); if (gl_FrontFacing) { @@ -35,6 +33,6 @@ void main() reflection += texture(samplerColor, vec2(projCoord.s + x * blurSize, projCoord.t + y * blurSize)) / 49.0; } } - outFragColor += reflection * 1.5 * (color.r); + outFragColor += reflection; }; } \ No newline at end of file diff --git a/data/shaders/offscreen/mirror.frag.spv b/data/shaders/offscreen/mirror.frag.spv index abfc8dd81598959534d8e5b694d150a3cedaab8d..dfe1a34bf31a8e121d247844b7b93b260a737bd8 100644 GIT binary patch literal 2376 zcmZ9NX-`#G6oxm`#i14Fp|*N(9)>`kH_OLeebnop?sVnuTRq1u=d>c|XOiF80t&kIw_a}#z+p|Nb z&-`e_y3|ty8Z(eqr(UF3tT&oEz5yB759Yvn;`P%At%vF<{YP>iY&EYB-)emA#ihb$ zoknviUq<%vvl+S6%HNFTd26=dYDJ&?kM?-0K0lT(+S)5#%m9P$oI^w=eLQ|>P8M0CzlF+D|!ts1KY^=T(v#R zjNhw}a^fhqzBM4Fwc0W379PD%RN!>`_JZ z-U-h)60zT7$W>w8-Ej7Zb!lfM7qtel{i2rVC>OB*W=?4@(wh5_T|nEtYI`4YQR4`D z2caSZf_acFweOF8YVS=arQe*Qb33xQ87~@(9v1GQawTy_3jGIE=IYQ)lr4 zJ=}|LO8y^Wv^N50Kz@pB^EUzcDlW2O*Qd`~#%%%C4|^-RF@IBA|2ANZy!q}&F5-8f z%e^b(zeAVvZA83W#Q%V9eAM^N%lSScUQRtj?g8dH%LjmS{2t#Sq~9le@&|#O_n~gS zXYHJ;d(O`7NBk#{#wq_N|0m>0;HUo-QoqvP&d6zCjepsvYdKqT&c18V_8*0{%vHCq z_ZfZ9l|H3?e?bldKl}cQG*=mYFQ8i^`d%!2oi}G+?eoA|=Bk@}2{{HvfwSbh83&%d z@5vZvX9CDazia63GcWzu(dE1^<8J~v-<)?YHwmnxFM8cZx7RHYz3!mPN3SV#_ZGeG zqRU0Ed+2i2UiY!Bqi>4-50DRmYtT0h*N=Pz+`qnf6ThKPe+A!=@xKFejB$N(kAX83 zv;CyxjE(t{^X|My&tDn)dy4M<-qOPvdJg3LdlR!EXMW6v_o(eWT2C4EUZ8t7QST+X sT-4JiXMW7M^BDW7qr0E5U!i9p_BVqrXPoQHkaE_Gx262dU&C|Y3wFJpPXGV_ literal 2660 zcmZ9MX;V~J5QdM!pvJgwF>ZsXB+(F)pixnXqTqsxam%hFTgD7?$uL&wH~e6gpZqia z0V_Ys7^^INo;$a#TVCp=yWj59-RGP>)3vg1RZ1(;s*0R>GvTHudCkeB$QB zz+!uPVDQ*cBi5&`JkXd8X-(=ziuqc-spC`74-SKG!A9csQwXh#>?!@r;tFheT?OA7 zeC_##+-IJ8b23{*R`}bBTxewvN3*Ooopar3A95;dWcFU6-#+AGZGNFK(;Ah&TI=Mp zpL+B59Yh{yZ`q^vSgSUd#|3Y{bB%jrt*qG|t4-CLbDi49;9E1ZjhU%-J!6;ldJ66_ zP(P1+lIuNb0$J_>GmW!T_p=vxZrb*`ANYmci|+Yo+q3b0+V)(w?R72KRQRo1&ZliY z>un*cd3)*A+f(0;)`P5q9pv|Zw7rum|5qdB#9?fGpMaE>M)X_T-1>(K+dax{!(NB1 z0zcPluLst5{RX75<~>3d^Lz%ZQAX6>1>Nv?E4UM1&}vhyT9P{e}(QI<6N}8JGt1)*XSuN4R0muH)yW& zahX@!yxQKeT&z2e?iXk91G-!pp8W~9DsZj2Pa^F{-dxHd@NRi|IqY-T_84d2{P^kj z?ylulC*O5+^LZ}O+pUg&DB|y8mwUgT`_G??db1z-|IYodMvn8MJZtCB&z|1ERFL-O zT>3i^=d0~+L)rFsp=|qp!}ctEyJg$=t9_O#&gDknEIY4fsOdg^XY$X9(cTQ4Q~60& zyM7ChFJqV;*snfw8Mh6XKkV)3#ylgp{vE&=dDpu?xrpD1F88#E{~TS;_Y?7Q5x)oB z_{i_?h@5XI;^mC*MIHcsh3%Yw0s6t+qTZM2#>l(g^OlQxN6_V76!8P-a?ZW+z6Uwu zo%ip6v;H5xL8RYXeDdD|IcGrK_1>qmukKws%m3p)jWkaAn)SoT5#Xo)N2GqGwS5O? zfjM5%tG$dCobSONw9f!@xwfNse)FU5g~F$_?l|%y@U!kEq-&K?_cFS37j>_o%SB!7 zF<>s&s=LKcTzNtnlANmvbhJzYXMW0q08Y4ls|t zsP!|twS3=E>lbwSsP!wldy87Xq02?B-_hmDwf?|1kG@IjJ9mEqd(aoNcMskD>x*|+ zL%;tKe5byp2f#JP*q_`KaE9XjOc$K7F<)}to%iVZD`S5%= #include "vulkanexamplebase.h" -#include "VulkanTexture.hpp" #include "VulkanModel.hpp" #include "VulkanBuffer.hpp" @@ -34,10 +33,6 @@ class VulkanExample : public VulkanExampleBase public: bool debugDisplay = false; - struct { - vks::Texture2D colorMap; - } textures; - // Vertex layout for the models vks::VertexLayout vertexLayout = vks::VertexLayout({ vks::VERTEX_COMPONENT_POSITION, @@ -124,9 +119,6 @@ public: // Clean up used Vulkan resources // Note : Inherited destructor cleans up resources stored in base class - // Textures - textures.colorMap.destroy(); - // Frame buffer // Color attachment @@ -453,20 +445,6 @@ public: { models.plane.loadFromFile(getAssetPath() + "models/plane.obj", vertexLayout, 0.5f, vulkanDevice, queue); models.example.loadFromFile(getAssetPath() + "models/chinesedragon.dae", vertexLayout, 0.3f, vulkanDevice, queue); - - // Textures - if (vulkanDevice->features.textureCompressionBC) { - textures.colorMap.loadFromFile(getAssetPath() + "textures/darkmetal_bc3_unorm.ktx", VK_FORMAT_BC3_UNORM_BLOCK, vulkanDevice, queue); - } - else if (vulkanDevice->features.textureCompressionASTC_LDR) { - textures.colorMap.loadFromFile(getAssetPath() + "textures/darkmetal_astc_8x8_unorm.ktx", VK_FORMAT_ASTC_8x8_UNORM_BLOCK, vulkanDevice, queue); - } - else if (vulkanDevice->features.textureCompressionETC2) { - textures.colorMap.loadFromFile(getAssetPath() + "textures/darkmetal_etc2_unorm.ktx", VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, vulkanDevice, queue); - } - else { - vks::tools::exitFatal("Device does not support any compressed texture format!", VK_ERROR_FEATURE_NOT_PRESENT); - } } void generateQuad() @@ -591,12 +569,6 @@ public: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &offscreenPass.descriptor), - // Binding 2 : Fragment shader texture sampler - vks::initializers::writeDescriptorSet( - descriptorSets.mirror, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 2, - &textures.colorMap.descriptor) }; vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL); @@ -625,7 +597,6 @@ public: allocInfo.pSetLayouts = &descriptorSetLayouts.shaded; // Model - // No texture VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.model)); std::vector modelWriteDescriptorSets = From 40c5e64fafc5965057c0d73a9029df03b7fe1085 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 9 Nov 2019 10:35:49 +0100 Subject: [PATCH 2/9] Updated comments Refs #622 --- examples/nv_ray_tracing_basic/nv_ray_tracing_basic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/nv_ray_tracing_basic/nv_ray_tracing_basic.cpp b/examples/nv_ray_tracing_basic/nv_ray_tracing_basic.cpp index ab8b07b6..38d0bd4b 100644 --- a/examples/nv_ray_tracing_basic/nv_ray_tracing_basic.cpp +++ b/examples/nv_ray_tracing_basic/nv_ray_tracing_basic.cpp @@ -244,7 +244,7 @@ public: */ void createScene() { - // Setup vertices for a single uv-mapped quad made from two triangles + // Setup vertices for a single triangle struct Vertex { float pos[3]; }; From f544895708bf688071c25d91cf0c1e2c2f021468 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 9 Nov 2019 10:47:31 +0100 Subject: [PATCH 3/9] Use proper type for scratch buffer memory requirements Explicitly set type for top and botom level AS memory requirements Fixes #622 --- examples/nv_ray_tracing_basic/nv_ray_tracing_basic.cpp | 4 +++- .../nv_ray_tracing_reflections/nv_ray_tracing_reflections.cpp | 4 +++- examples/nv_ray_tracing_shadows/nv_ray_tracing_shadows.cpp | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/nv_ray_tracing_basic/nv_ray_tracing_basic.cpp b/examples/nv_ray_tracing_basic/nv_ray_tracing_basic.cpp index 38d0bd4b..40fd8e60 100644 --- a/examples/nv_ray_tracing_basic/nv_ray_tracing_basic.cpp +++ b/examples/nv_ray_tracing_basic/nv_ray_tracing_basic.cpp @@ -183,6 +183,7 @@ public: VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{}; memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV; memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure; VkMemoryRequirements2 memoryRequirements2{}; @@ -220,6 +221,7 @@ public: VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{}; memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV; memoryRequirementsInfo.accelerationStructure = topLevelAS.accelerationStructure; VkMemoryRequirements2 memoryRequirements2{}; @@ -336,7 +338,7 @@ public: // Acceleration structure build requires some scratch space to store temporary information VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{}; memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; - memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV; + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV; VkMemoryRequirements2 memReqBottomLevelAS; memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure; diff --git a/examples/nv_ray_tracing_reflections/nv_ray_tracing_reflections.cpp b/examples/nv_ray_tracing_reflections/nv_ray_tracing_reflections.cpp index 020477eb..a5f56cad 100644 --- a/examples/nv_ray_tracing_reflections/nv_ray_tracing_reflections.cpp +++ b/examples/nv_ray_tracing_reflections/nv_ray_tracing_reflections.cpp @@ -196,6 +196,7 @@ public: VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{}; memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV; memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure; VkMemoryRequirements2 memoryRequirements2{}; @@ -233,6 +234,7 @@ public: VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{}; memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV; memoryRequirementsInfo.accelerationStructure = topLevelAS.accelerationStructure; VkMemoryRequirements2 memoryRequirements2{}; @@ -325,7 +327,7 @@ public: // Acceleration structure build requires some scratch space to store temporary information VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{}; memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; - memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV; + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV; VkMemoryRequirements2 memReqBottomLevelAS; memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure; diff --git a/examples/nv_ray_tracing_shadows/nv_ray_tracing_shadows.cpp b/examples/nv_ray_tracing_shadows/nv_ray_tracing_shadows.cpp index 676284e8..dcb5c379 100644 --- a/examples/nv_ray_tracing_shadows/nv_ray_tracing_shadows.cpp +++ b/examples/nv_ray_tracing_shadows/nv_ray_tracing_shadows.cpp @@ -197,6 +197,7 @@ public: VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{}; memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV; memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure; VkMemoryRequirements2 memoryRequirements2{}; @@ -234,6 +235,7 @@ public: VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{}; memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV; memoryRequirementsInfo.accelerationStructure = topLevelAS.accelerationStructure; VkMemoryRequirements2 memoryRequirements2{}; @@ -334,7 +336,7 @@ public: // Acceleration structure build requires some scratch space to store temporary information VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{}; memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; - memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV; + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV; VkMemoryRequirements2 memReqBottomLevelAS; memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure; From 39852c4a27e36acbe5f5992b5335908ba66dea49 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 19 Nov 2019 18:02:49 +0100 Subject: [PATCH 4/9] Use proper buffer sizes --- base/VulkanModel.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/VulkanModel.hpp b/base/VulkanModel.hpp index 681e3504..8b7a15db 100644 --- a/base/VulkanModel.hpp +++ b/base/VulkanModel.hpp @@ -351,10 +351,10 @@ namespace vks VkBufferCopy copyRegion{}; - copyRegion.size = vertices.size; + copyRegion.size = vBufferSize; vkCmdCopyBuffer(copyCmd, vertexStaging.buffer, vertices.buffer, 1, ©Region); - copyRegion.size = indices.size; + copyRegion.size = iBufferSize; vkCmdCopyBuffer(copyCmd, indexStaging.buffer, indices.buffer, 1, ©Region); device->flushCommandBuffer(copyCmd, copyQueue); From 70866849794c9b350cfb94b93e782b4d97b023d9 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 19 Nov 2019 19:07:03 +0100 Subject: [PATCH 5/9] Fix image memory barriers Use proper stages and access masks This fixes image memory barrier validation Refs #631 --- examples/texturemipmapgen/README.md | 45 +++++---- .../texturemipmapgen/texturemipmapgen.cpp | 91 ++++++++++--------- 2 files changed, 72 insertions(+), 64 deletions(-) diff --git a/examples/texturemipmapgen/README.md b/examples/texturemipmapgen/README.md index ba67ca92..c0247538 100644 --- a/examples/texturemipmapgen/README.md +++ b/examples/texturemipmapgen/README.md @@ -68,15 +68,16 @@ subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; subresourceRange.levelCount = 1; subresourceRange.layerCount = 1; -vkTools::setImageLayout( +vks::tools::insertImageMemoryBarrier( copyCmd, texture.image, - VK_IMAGE_ASPECT_COLOR_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - subresourceRange, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_HOST_BIT); + VK_PIPELINE_STAGE_TRANSFER_BIT, + subresourceRange); ``` ### Generating the mip-chain @@ -119,16 +120,17 @@ Before we can blit to this mip level, we need to transition it's image layout to mipSubRange.levelCount = 1; mipSubRange.layerCount = 1; - // Transiton current mip level to transfer dest - vkTools::setImageLayout( + // Prepare current mip level as image blit destination + vks::tools::insertImageMemoryBarrier( blitCmd, texture.image, - VK_IMAGE_ASPECT_COLOR_BIT, + 0, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - mipSubRange, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_HOST_BIT); + VK_PIPELINE_STAGE_TRANSFER_BIT, + mipSubRange); ``` Note that we set the ```baseMipLevel``` member of the subresource range so the image memory barrier will only affect the one mip level we want to copy to. @@ -150,15 +152,17 @@ Now that the mip level we want to copy from and the one we'll copy to have are i After the blit is done we can use this mip level as a base for the next level, so we transition the layout from ```TRANSFER_DST_OPTIMAL``` to ```TRANSFER_SRC_OPTIMAL``` so we can use this level as transfer source for the next level: ```cpp - vkTools::setImageLayout( - blitCmd, + // Prepare current mip level as image blit source for next level + vks::tools::insertImageMemoryBarrier( + copyCmd, texture.image, - VK_IMAGE_ASPECT_COLOR_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - mipSubRange, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_HOST_BIT); + VK_PIPELINE_STAGE_TRANSFER_BIT, + mipSubRange); } ``` @@ -167,15 +171,16 @@ Once the loop is done we need to transition all mip levels of the image to their ```cpp subresourceRange.levelCount = texture.mipLevels; - vkTools::setImageLayout( - blitCmd, + vks::tools::insertImageMemoryBarrier( + copyCmd, texture.image, - VK_IMAGE_ASPECT_COLOR_BIT, + VK_ACCESS_TRANSFER_READ_BIT, + VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;, - subresourceRange, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_HOST_BIT); + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + subresourceRange); ``` Submitting that command buffer will result in an image with a complete mip-chain and all mip levels being transitioned to the proper image layout for shader reads. diff --git a/examples/texturemipmapgen/texturemipmapgen.cpp b/examples/texturemipmapgen/texturemipmapgen.cpp index 471b1914..fb4cf6ea 100644 --- a/examples/texturemipmapgen/texturemipmapgen.cpp +++ b/examples/texturemipmapgen/texturemipmapgen.cpp @@ -1,7 +1,7 @@ /* * Vulkan Example - Runtime mip map generation * -* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de +* Copyright (C) by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ @@ -35,7 +35,6 @@ class VulkanExample : public VulkanExampleBase public: struct Texture { VkImage image; - VkImageLayout imageLayout; VkDeviceMemory deviceMemory; VkImageView view; uint32_t width, height; @@ -110,6 +109,13 @@ public: models.tunnel.destroy(); } + virtual void getEnabledFeatures() + { + if (deviceFeatures.samplerAnisotropy) { + enabledFeatures.samplerAnisotropy = VK_TRUE; + } + } + void loadTexture(std::string fileName, VkFormat format, bool forceLinearTiling) { #if defined(__ANDROID__) @@ -200,11 +206,15 @@ public: subresourceRange.layerCount = 1; // Optimal image will be used as destination for the copy, so we must transfer from our initial undefined image layout to the transfer destination layout - vks::tools::setImageLayout( + vks::tools::insertImageMemoryBarrier( copyCmd, texture.image, + 0, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, subresourceRange); // Copy the first mip of the chain, remaining mips will be generated @@ -220,12 +230,15 @@ public: vkCmdCopyBufferToImage(copyCmd, stagingBuffer, texture.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion); // Transition first mip level to transfer source for read during blit - texture.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - vks::tools::setImageLayout( + vks::tools::insertImageMemoryBarrier( copyCmd, texture.image, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, subresourceRange); VulkanExampleBase::flushCommandBuffer(copyCmd, queue, true); @@ -267,15 +280,17 @@ public: mipSubRange.levelCount = 1; mipSubRange.layerCount = 1; - // Transiton current mip level to transfer dest - vks::tools::setImageLayout( + // Prepare current mip level as image blit destination + vks::tools::insertImageMemoryBarrier( blitCmd, texture.image, + 0, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - mipSubRange, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_HOST_BIT); + VK_PIPELINE_STAGE_TRANSFER_BIT, + mipSubRange); // Blit from previous level vkCmdBlitImage( @@ -288,24 +303,30 @@ public: &imageBlit, VK_FILTER_LINEAR); - // Transiton current mip level to transfer source for read in next iteration - vks::tools::setImageLayout( - blitCmd, + // Prepare current mip level as image blit source for next level + vks::tools::insertImageMemoryBarrier( + copyCmd, texture.image, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - mipSubRange, - VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT); + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + mipSubRange); } // After the loop, all mip layers are in TRANSFER_SRC layout, so transition all to SHADER_READ subresourceRange.levelCount = texture.mipLevels; - vks::tools::setImageLayout( - blitCmd, + vks::tools::insertImageMemoryBarrier( + copyCmd, texture.image, + VK_ACCESS_TRANSFER_READ_BIT, + VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - texture.imageLayout, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, subresourceRange); VulkanExampleBase::flushCommandBuffer(blitCmd, queue, true); @@ -534,34 +555,17 @@ public: void setupDescriptorSet() { - VkDescriptorSetAllocateInfo allocInfo = - vks::initializers::descriptorSetAllocateInfo( - descriptorPool, - &descriptorSetLayout, - 1); - + VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout,1); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); - std::vector writeDescriptorSets; + VkDescriptorImageInfo textureDescriptor = vks::initializers::descriptorImageInfo(VK_NULL_HANDLE, texture.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + std::vector writeDescriptorSets = { - // Binding 0: Vertex shader uniform buffer - writeDescriptorSets.push_back(vks::initializers::writeDescriptorSet( - descriptorSet, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - &uniformBufferVS.descriptor)); - - // Binding 1: Sampled image - VkDescriptorImageInfo textureDescriptor = - vks::initializers::descriptorImageInfo( - VK_NULL_HANDLE, - texture.view, - texture.imageLayout); - writeDescriptorSets.push_back(vks::initializers::writeDescriptorSet( - descriptorSet, - VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - 1, - &textureDescriptor)); + // Binding 0: Vertex shader uniform buffer + vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBufferVS.descriptor), + // Binding 1: Sampled image + vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, &textureDescriptor) + }; // Binding 2: Sampler array std::vector samplerDescriptors; @@ -578,7 +582,6 @@ public: samplerDescriptorWrite.dstBinding = 2; samplerDescriptorWrite.dstArrayElement = 0; writeDescriptorSets.push_back(samplerDescriptorWrite); - vkUpdateDescriptorSets(device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL); } From 9a727ccc43034286496515013ac69150ef1c4861 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 23 Nov 2019 13:59:11 +0100 Subject: [PATCH 6/9] Put image memory barrier in proper command buffer --- examples/texturemipmapgen/texturemipmapgen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/texturemipmapgen/texturemipmapgen.cpp b/examples/texturemipmapgen/texturemipmapgen.cpp index fb4cf6ea..db0f7926 100644 --- a/examples/texturemipmapgen/texturemipmapgen.cpp +++ b/examples/texturemipmapgen/texturemipmapgen.cpp @@ -305,7 +305,7 @@ public: // Prepare current mip level as image blit source for next level vks::tools::insertImageMemoryBarrier( - copyCmd, + blitCmd, texture.image, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, From 144b58a253bdf0cfae424f6f7538f57f49945c97 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 23 Nov 2019 14:00:24 +0100 Subject: [PATCH 7/9] Put image memory barrier in proper command buffer --- examples/texturemipmapgen/texturemipmapgen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/texturemipmapgen/texturemipmapgen.cpp b/examples/texturemipmapgen/texturemipmapgen.cpp index db0f7926..50fd04f6 100644 --- a/examples/texturemipmapgen/texturemipmapgen.cpp +++ b/examples/texturemipmapgen/texturemipmapgen.cpp @@ -319,7 +319,7 @@ public: // After the loop, all mip layers are in TRANSFER_SRC layout, so transition all to SHADER_READ subresourceRange.levelCount = texture.mipLevels; vks::tools::insertImageMemoryBarrier( - copyCmd, + blitCmd, texture.image, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, From 6eefd7a5b61e213731ade1bebb120bc437485c77 Mon Sep 17 00:00:00 2001 From: Robin Liu Date: Thu, 28 Nov 2019 16:44:13 -0500 Subject: [PATCH 8/9] Fix the validation error that there's not enough descriptors left in the pool. --- examples/inputattachments/inputattachments.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/inputattachments/inputattachments.cpp b/examples/inputattachments/inputattachments.cpp index c533fb9d..912841a6 100644 --- a/examples/inputattachments/inputattachments.cpp +++ b/examples/inputattachments/inputattachments.cpp @@ -412,9 +412,9 @@ public: Pool */ std::vector poolSizes = { - vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 4), - vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4), - vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 4), + vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, attachments.size() + 1), + vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, attachments.size() + 1), + vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, attachments.size() * 2 + 1), }; VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(static_cast(poolSizes.size()), poolSizes.data(), 4); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); From 99fa99ff3709467d51d95545d4e504f8f7795d13 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 1 Dec 2019 18:13:22 +0100 Subject: [PATCH 9/9] Added function for getting best-fit depth format to device Refs #607 --- base/VulkanDevice.hpp | 31 +++++++++++++++++++ .../shadowmappingcascade.cpp | 3 +- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/base/VulkanDevice.hpp b/base/VulkanDevice.hpp index 76c6655d..a6d8dbae 100644 --- a/base/VulkanDevice.hpp +++ b/base/VulkanDevice.hpp @@ -567,5 +567,36 @@ namespace vks return (std::find(supportedExtensions.begin(), supportedExtensions.end(), extension) != supportedExtensions.end()); } + /** + * Select the best-fit depth format for this device from a list of possible depth (and stencil) formats + * + * @param checkSamplingSupport Check if the format can be sampled from (e.g. for shader reads) + * + * @return The depth format that best fits for the current device + * + * @throw Throws an exception if no depth format fits the requirements + */ + VkFormat getSupportedDepthFormat(bool checkSamplingSupport) + { + // All depth formats may be optional, so we need to find a suitable depth format to use + std::vector depthFormats = { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM }; + for (auto& format : depthFormats) + { + VkFormatProperties formatProperties; + vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProperties); + // Format must support depth stencil attachment for optimal tiling + if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) + { + if (checkSamplingSupport) { + if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { + continue; + } + } + return format; + } + } + throw std::runtime_error("Could not find a matching depth format"); + } + }; } diff --git a/examples/shadowmappingcascade/shadowmappingcascade.cpp b/examples/shadowmappingcascade/shadowmappingcascade.cpp index 96e6ee55..d9b9d6d6 100644 --- a/examples/shadowmappingcascade/shadowmappingcascade.cpp +++ b/examples/shadowmappingcascade/shadowmappingcascade.cpp @@ -262,8 +262,7 @@ public: */ void prepareDepthPass() { - VkFormat depthFormat; - vks::tools::getSupportedDepthFormat(physicalDevice, &depthFormat); + VkFormat depthFormat = vulkanDevice->getSupportedDepthFormat(true); /* Depth map renderpass