diff --git a/impl/MainApp.cpp b/impl/MainApp.cpp index 4d18d43..172a11b 100644 --- a/impl/MainApp.cpp +++ b/impl/MainApp.cpp @@ -852,9 +852,10 @@ void vk_gltf_viewer::MainApp::loadGltf(const std::filesystem::path &path) { })); gpu.device.updateDescriptorSets({ sharedData.assetDescriptorSet.getWriteOne<0>({ gltf->assetGpuBuffers.getPrimitiveBuffer(), 0, vk::WholeSize }), - sharedData.assetDescriptorSet.getWrite<1>(gltf->nodeBuffer.descriptorInfo), - sharedData.assetDescriptorSet.getWriteOne<2>({ gltf->assetGpuBuffers.materialBuffer, 0, vk::WholeSize }), - sharedData.assetDescriptorSet.getWrite<3>(imageInfos), + sharedData.assetDescriptorSet.getWrite<1>(gltf->nodeBuffer.getDescriptorInfo()), + sharedData.assetDescriptorSet.getWrite<2>(gltf->instancedNodeWorldTransformBuffer.getDescriptorInfo()), + sharedData.assetDescriptorSet.getWriteOne<3>({ gltf->assetGpuBuffers.materialBuffer, 0, vk::WholeSize }), + sharedData.assetDescriptorSet.getWrite<4>(imageInfos), }, {}); // TODO: due to the ImGui's gamma correction issue, base color/emissive texture is rendered darker than it should be. diff --git a/interface/vulkan/buffer/InstancedNodeWorldTransforms.cppm b/interface/vulkan/buffer/InstancedNodeWorldTransforms.cppm index 1e42bea..cf1c920 100644 --- a/interface/vulkan/buffer/InstancedNodeWorldTransforms.cppm +++ b/interface/vulkan/buffer/InstancedNodeWorldTransforms.cppm @@ -41,10 +41,14 @@ namespace vk_gltf_viewer::vulkan::buffer { ) : asset { asset }, instanceOffsets { createInstanceOffsets() }, buffer { createBuffer(gpu.allocator, adapter) }, - bufferAddress { gpu.device.getBufferAddress({ buffer }) } { } + descriptorInfo { buffer, 0, vk::WholeSize } { } - [[nodiscard]] vk::DeviceAddress getTransformStartAddress(std::size_t nodeIndex) const noexcept { - return bufferAddress + sizeof(fastgltf::math::fmat4x4) * instanceOffsets[nodeIndex]; + [[nodiscard]] std::uint32_t getStartIndex(std::size_t nodeIndex) const noexcept { + return instanceOffsets[nodeIndex]; + } + + [[nodiscard]] const vk::DescriptorBufferInfo &getDescriptorInfo() const noexcept { + return descriptorInfo; } /** @@ -121,7 +125,7 @@ namespace vk_gltf_viewer::vulkan::buffer { * Be careful that there is no transform matrix related about node C, because it is meshless. */ vku::MappedBuffer buffer; - vk::DeviceAddress bufferAddress; + vk::DescriptorBufferInfo descriptorInfo; [[nodiscard]] std::vector createInstanceOffsets() const { std::vector result; @@ -154,7 +158,7 @@ namespace vk_gltf_viewer::vulkan::buffer { vku::MappedBuffer result { allocator, vk::BufferCreateInfo { {}, sizeof(fastgltf::math::fmat4x4) * instanceOffsets.back(), - vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eShaderDeviceAddress, + vk::BufferUsageFlagBits::eStorageBuffer, } }; const std::span data = result.asRange(); diff --git a/interface/vulkan/buffer/Nodes.cppm b/interface/vulkan/buffer/Nodes.cppm index 9a96a79..fc6f9e4 100644 --- a/interface/vulkan/buffer/Nodes.cppm +++ b/interface/vulkan/buffer/Nodes.cppm @@ -7,14 +7,7 @@ export import :vulkan.buffer.InstancedNodeWorldTransforms; namespace vk_gltf_viewer::vulkan::buffer { export class Nodes { - /** - * @brief Buffer with the start address of the instanced node world transform buffer. - */ - vku::AllocatedBuffer buffer; - public: - vk::DescriptorBufferInfo descriptorInfo; - Nodes( const fastgltf::Asset &asset, const InstancedNodeWorldTransforms &instancedNodeWorldTransformBuffer, @@ -22,7 +15,17 @@ namespace vk_gltf_viewer::vulkan::buffer { ) : buffer { createBuffer(asset, instancedNodeWorldTransformBuffer, gpu) }, descriptorInfo { buffer, 0, vk::WholeSize } { } + [[nodiscard]] const vk::DescriptorBufferInfo &getDescriptorInfo() const noexcept { + return descriptorInfo; + } + private: + /** + * @brief Buffer with the start index of the instanced node world transform buffer. + */ + vku::AllocatedBuffer buffer; + vk::DescriptorBufferInfo descriptorInfo; + [[nodiscard]] vku::AllocatedBuffer createBuffer( const fastgltf::Asset &asset, const InstancedNodeWorldTransforms &instancedNodeWorldTransformBuffer, @@ -31,7 +34,7 @@ namespace vk_gltf_viewer::vulkan::buffer { vku::AllocatedBuffer buffer = vku::MappedBuffer { gpu.allocator, std::from_range, ranges::views::upto(asset.nodes.size()) | std::views::transform([&](std::size_t nodeIndex) { - return instancedNodeWorldTransformBuffer.getTransformStartAddress(nodeIndex); + return instancedNodeWorldTransformBuffer.getStartIndex(nodeIndex); }), gpu.isUmaDevice ? vk::BufferUsageFlagBits::eStorageBuffer : vk::BufferUsageFlagBits::eTransferSrc, }.unmap(); diff --git a/interface/vulkan/descriptor_set_layout/Asset.cppm b/interface/vulkan/descriptor_set_layout/Asset.cppm index 7b9a469..19677d9 100644 --- a/interface/vulkan/descriptor_set_layout/Asset.cppm +++ b/interface/vulkan/descriptor_set_layout/Asset.cppm @@ -4,12 +4,13 @@ import std; export import vku; namespace vk_gltf_viewer::vulkan::dsl { - export struct Asset : vku::DescriptorSetLayout { + export struct Asset : vku::DescriptorSetLayout { Asset(const vk::raii::Device &device [[clang::lifetimebound]], std::uint32_t textureCount) : DescriptorSetLayout { device, vk::StructureChain { vk::DescriptorSetLayoutCreateInfo { vk::DescriptorSetLayoutCreateFlagBits::eUpdateAfterBindPool, vku::unsafeProxy(getBindings( + { 1, vk::ShaderStageFlagBits::eVertex }, { 1, vk::ShaderStageFlagBits::eVertex }, { 1, vk::ShaderStageFlagBits::eVertex }, { 1, vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment }, @@ -20,6 +21,7 @@ namespace vk_gltf_viewer::vulkan::dsl { {}, {}, {}, + {}, vk::DescriptorBindingFlagBits::eUpdateAfterBind, }), }, diff --git a/shaders/depth.vert b/shaders/depth.vert index f4fb35e..3312418 100644 --- a/shaders/depth.vert +++ b/shaders/depth.vert @@ -12,15 +12,16 @@ #include "indexing.glsl" #include "types.glsl" -layout (std430, buffer_reference, buffer_reference_align = 64) readonly buffer Node { mat4 transforms[]; }; - layout (location = 0) flat out uint outNodeIndex; layout (set = 0, binding = 0) readonly buffer PrimitiveBuffer { Primitive primitives[]; }; layout (set = 0, binding = 1, std430) readonly buffer NodeBuffer { - Node nodes[]; + uint instancedTransformStartIndices[]; +}; +layout (set = 0, binding = 2) readonly buffer InstancedTransformBuffer { + mat4 instancedTransforms[]; }; layout (push_constant) uniform PushConstant { diff --git a/shaders/indexing.glsl b/shaders/indexing.glsl index 9e5d3d6..7bda420 100644 --- a/shaders/indexing.glsl +++ b/shaders/indexing.glsl @@ -7,7 +7,8 @@ #define PRIMITIVE_INDEX gl_BaseInstance & 0xFFFFU #define PRIMITIVE primitives[PRIMITIVE_INDEX] #define NODE_INDEX gl_BaseInstance >> 16U -#define TRANSFORM Node(nodes[NODE_INDEX]).transforms[gl_InstanceIndex - gl_BaseInstance] +#define INSTANCE_INDEX gl_InstanceIndex - gl_BaseInstance +#define TRANSFORM instancedTransforms[instancedTransformStartIndices[NODE_INDEX] + INSTANCE_INDEX] #define MATERIAL_INDEX PRIMITIVE.materialIndex #define MATERIAL materials[MATERIAL_INDEX] diff --git a/shaders/jump_flood_seed.vert b/shaders/jump_flood_seed.vert index 9a45ed8..34fe385 100644 --- a/shaders/jump_flood_seed.vert +++ b/shaders/jump_flood_seed.vert @@ -12,13 +12,14 @@ #include "indexing.glsl" #include "types.glsl" -layout (std430, buffer_reference, buffer_reference_align = 64) readonly buffer Node { mat4 transforms[]; }; - layout (set = 0, binding = 0) readonly buffer PrimitiveBuffer { Primitive primitives[]; }; layout (set = 0, binding = 1, std430) readonly buffer NodeBuffer { - Node nodes[]; + uint instancedTransformStartIndices[]; +}; +layout (set = 0, binding = 2) readonly buffer InstancedTransformBuffer { + mat4 instancedTransforms[]; }; layout (push_constant) uniform PushConstant { diff --git a/shaders/mask_depth.frag b/shaders/mask_depth.frag index 7b2d2dd..1ead04d 100644 --- a/shaders/mask_depth.frag +++ b/shaders/mask_depth.frag @@ -27,10 +27,10 @@ layout (location = 2) in FRAG_VARIADIC_IN { layout (location = 0) out uint outNodeIndex; -layout (set = 0, binding = 2, std430) readonly buffer MaterialBuffer { +layout (set = 0, binding = 3, std430) readonly buffer MaterialBuffer { Material materials[]; }; -layout (set = 0, binding = 3) uniform sampler2D textures[]; +layout (set = 0, binding = 4) uniform sampler2D textures[]; void main(){ float baseColorAlpha = MATERIAL.baseColorFactor.a; diff --git a/shaders/mask_depth.vert b/shaders/mask_depth.vert index aa204ae..415f03d 100644 --- a/shaders/mask_depth.vert +++ b/shaders/mask_depth.vert @@ -17,8 +17,6 @@ layout (constant_id = 0) const uint TEXCOORD_COMPONENT_TYPE = 5126; // FLOAT layout (constant_id = 1) const uint COLOR_COMPONENT_TYPE = 5126; // FLOAT -layout (std430, buffer_reference, buffer_reference_align = 64) readonly buffer Node { mat4 transforms[]; }; - layout (location = 0) flat out uint outNodeIndex; layout (location = 1) flat out uint outMaterialIndex; #if HAS_VARIADIC_OUT @@ -36,9 +34,12 @@ layout (set = 0, binding = 0) readonly buffer PrimitiveBuffer { Primitive primitives[]; }; layout (set = 0, binding = 1, std430) readonly buffer NodeBuffer { - Node nodes[]; + uint instancedTransformStartIndices[]; +}; +layout (set = 0, binding = 2) readonly buffer InstancedTransformBuffer { + mat4 instancedTransforms[]; }; -layout (set = 0, binding = 2, std430) readonly buffer MaterialBuffer { +layout (set = 0, binding = 3, std430) readonly buffer MaterialBuffer { Material materials[]; }; diff --git a/shaders/mask_jump_flood_seed.frag b/shaders/mask_jump_flood_seed.frag index 0a1c179..dbef5b0 100644 --- a/shaders/mask_jump_flood_seed.frag +++ b/shaders/mask_jump_flood_seed.frag @@ -26,10 +26,10 @@ layout (location = 1) in FRAG_VARIDIC_IN { layout (location = 0) out uvec2 outCoordinate; -layout (set = 0, binding = 2, std430) readonly buffer MaterialBuffer { +layout (set = 0, binding = 3, std430) readonly buffer MaterialBuffer { Material materials[]; }; -layout (set = 0, binding = 3) uniform sampler2D textures[]; +layout (set = 0, binding = 4) uniform sampler2D textures[]; void main(){ float baseColorAlpha = MATERIAL.baseColorFactor.a; diff --git a/shaders/mask_jump_flood_seed.vert b/shaders/mask_jump_flood_seed.vert index 5e771aa..58e062a 100644 --- a/shaders/mask_jump_flood_seed.vert +++ b/shaders/mask_jump_flood_seed.vert @@ -17,8 +17,6 @@ layout (constant_id = 0) const uint TEXCOORD_COMPONENT_TYPE = 5126; // FLOAT layout (constant_id = 1) const uint COLOR_COMPONENT_TYPE = 5126; // FLOAT -layout (std430, buffer_reference, buffer_reference_align = 64) readonly buffer Node { mat4 transforms[]; }; - layout (location = 0) flat out uint outMaterialIndex; #if HAS_VARIADIC_OUT layout (location = 1) out VS_VARIADIC_OUT { @@ -35,9 +33,12 @@ layout (set = 0, binding = 0) readonly buffer PrimitiveBuffer { Primitive primitives[]; }; layout (set = 0, binding = 1, std430) readonly buffer NodeBuffer { - Node nodes[]; + uint instancedTransformStartIndices[]; +}; +layout (set = 0, binding = 2) readonly buffer InstancedTransformBuffer { + mat4 instancedTransforms[]; }; -layout (set = 0, binding = 2, std430) readonly buffer MaterialBuffer { +layout (set = 0, binding = 3, std430) readonly buffer MaterialBuffer { Material materials[]; }; diff --git a/shaders/primitive.frag b/shaders/primitive.frag index 5cd30f9..aad5a5c 100644 --- a/shaders/primitive.frag +++ b/shaders/primitive.frag @@ -54,10 +54,10 @@ layout (set = 0, binding = 0, scalar) uniform SphericalHarmonicsBuffer { layout (set = 0, binding = 1) uniform samplerCube prefilteredmap; layout (set = 0, binding = 2) uniform sampler2D brdfmap; -layout (set = 1, binding = 2, std430) readonly buffer MaterialBuffer { +layout (set = 1, binding = 3, std430) readonly buffer MaterialBuffer { Material materials[]; }; -layout (set = 1, binding = 3) uniform sampler2D textures[]; +layout (set = 1, binding = 4) uniform sampler2D textures[]; layout (push_constant, std430) uniform PushConstant { mat4 projectionView; diff --git a/shaders/primitive.vert b/shaders/primitive.vert index 728e1c4..37aa381 100644 --- a/shaders/primitive.vert +++ b/shaders/primitive.vert @@ -18,8 +18,6 @@ layout (constant_id = 0) const uint PACKED_TEXCOORD_COMPONENT_TYPES = 0x06060606 layout (constant_id = 1) const uint COLOR_COMPONENT_COUNT = 0; layout (constant_id = 2) const uint COLOR_COMPONENT_TYPE = 5126; // FLOAT -layout (std430, buffer_reference, buffer_reference_align = 64) readonly buffer Node { mat4 transforms[]; }; - layout (location = 0) out vec3 outPosition; layout (location = 1) flat out uint outMaterialIndex; #if HAS_VARIADIC_OUT @@ -50,9 +48,12 @@ layout (set = 1, binding = 0) readonly buffer PrimitiveBuffer { Primitive primitives[]; }; layout (set = 1, binding = 1, std430) readonly buffer NodeBuffer { - Node nodes[]; + uint instancedTransformStartIndices[]; +}; +layout (set = 1, binding = 2) readonly buffer InstancedTransformBuffer { + mat4 instancedTransforms[]; }; -layout (set = 1, binding = 2, std430) readonly buffer MaterialBuffer { +layout (set = 1, binding = 3, std430) readonly buffer MaterialBuffer { Material materials[]; }; diff --git a/shaders/unlit_primitive.frag b/shaders/unlit_primitive.frag index cfa455c..047a430 100644 --- a/shaders/unlit_primitive.frag +++ b/shaders/unlit_primitive.frag @@ -30,10 +30,10 @@ layout (location = 0) out vec4 outColor; layout (location = 1) out float outRevealage; #endif -layout (set = 1, binding = 2, std430) readonly buffer MaterialBuffer { +layout (set = 1, binding = 3, std430) readonly buffer MaterialBuffer { Material materials[]; }; -layout (set = 1, binding = 3) uniform sampler2D textures[]; +layout (set = 1, binding = 4) uniform sampler2D textures[]; #if ALPHA_MODE == 0 || ALPHA_MODE == 2 layout (early_fragment_tests) in; diff --git a/shaders/unlit_primitive.vert b/shaders/unlit_primitive.vert index dbdab24..33f13d6 100644 --- a/shaders/unlit_primitive.vert +++ b/shaders/unlit_primitive.vert @@ -18,8 +18,6 @@ layout (constant_id = 0) const uint TEXCOORD_COMPONENT_TYPE = 5126; // FLOAT layout (constant_id = 1) const uint COLOR_COMPONENT_COUNT = 0; layout (constant_id = 2) const uint COLOR_COMPONENT_TYPE = 5126; // FLOAT -layout (std430, buffer_reference, buffer_reference_align = 64) readonly buffer Node { mat4 transforms[]; }; - layout (location = 0) flat out uint outMaterialIndex; #if HAS_VARIADIC_OUT layout (location = 1) out VS_VARIADIC_OUT { @@ -37,9 +35,12 @@ layout (set = 1, binding = 0) readonly buffer PrimitiveBuffer { Primitive primitives[]; }; layout (set = 1, binding = 1, std430) readonly buffer NodeBuffer { - Node nodes[]; + uint instancedTransformStartIndices[]; +}; +layout (set = 1, binding = 2) readonly buffer InstancedTransformBuffer { + mat4 instancedTransforms[]; }; -layout (set = 1, binding = 2, std430) readonly buffer MaterialBuffer { +layout (set = 1, binding = 3, std430) readonly buffer MaterialBuffer { Material materials[]; };