diff --git a/examples/VulkanAnimation/main.cpp b/examples/VulkanAnimation/main.cpp index f9d67ed..d77262c 100644 --- a/examples/VulkanAnimation/main.cpp +++ b/examples/VulkanAnimation/main.cpp @@ -9,31 +9,32 @@ import Crafter.Math; typedef VulkanShader<"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR, 2, {{{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1}}}> Raygenspv; typedef VulkanShader<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, 0, {{}}> Closesthitspv; typedef VulkanShader<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR, 0, {{}}> Misspv; +typedef std::tuple AllShaders; +typedef std::tuple< + ShaderGroup<0, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>, + ShaderGroup<1, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>, + ShaderGroup +> ShaderGroups; +typedef PipelineRTVulkan Pipeline; int main() { - /* - This sets up all necessary things and creates the vulkan device. - This must be called before any vulkan related things. - Things like VkDevice are static members of the VulkanDevice class. - */ - VulkanDevice::CreateDevice(); + VulkanDevice::CreateDevice(); + WindowVulkan window(1280, 720, "HelloVulkan"); + VkCommandBuffer cmd = window.StartInit(); + Raygenspv::CreateShader(); Closesthitspv::CreateShader(); Misspv::CreateShader(); + + ShaderBindingTableVulkan::Init(); std::array layouts {{Raygenspv::layout, Raygenspv::layout, Raygenspv::layout}}; - PipelineRTVulkan::Init(layouts); + Pipeline::Init(cmd, layouts); + window.SetPipelineRT(); + DescriptorPool pool; pool.sets.resize(3); pool.BuildPool(DescriptorPool::GetPoolSizes(), layouts); - WindowVulkan window(1280, 720, "HelloVulkan"); - - /* - StartInit gives you a VkCommandBuffer to use before the event loop starts - Use this for inititializing things like textures. - */ - VkCommandBuffer cmd = window.StartInit(); - Mesh triangleMesh; std::array verts {{{-150, -150, 100}, {0, 150, 100}, {150, -150, 100}}}; std::array index {{2,1,0}}; @@ -41,13 +42,12 @@ int main() { RenderingElement3DVulkan& el = RenderingElement3DVulkan::elements.emplace_back(triangleMesh); MatrixRowMajor transform = MatrixRowMajor::Identity(); std::memcpy(el.instance.transform.matrix, transform.m, sizeof(transform.m)); + RenderingElement3DVulkan::tlases.resize(3); - - window.SetPipelineRT(); - RenderingElement3DVulkan::BuildTLAS(cmd, 0); RenderingElement3DVulkan::BuildTLAS(cmd, 1); RenderingElement3DVulkan::BuildTLAS(cmd, 2); + VkDescriptorImageInfo imageInfo = { .imageView = window.imageViews[0], .imageLayout = VK_IMAGE_LAYOUT_GENERAL diff --git a/examples/VulkanTriangle/main.cpp b/examples/VulkanTriangle/main.cpp index b5451ba..bec4d46 100644 --- a/examples/VulkanTriangle/main.cpp +++ b/examples/VulkanTriangle/main.cpp @@ -9,30 +9,28 @@ import Crafter.Math; typedef VulkanShader<"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR, 2, {{{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1}}}> Raygenspv; typedef VulkanShader<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, 0, {{}}> Closesthitspv; typedef VulkanShader<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR, 0, {{}}> Misspv; +typedef std::tuple AllShaders; +typedef std::tuple< + ShaderGroup<0, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>, + ShaderGroup<1, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>, + ShaderGroup +> ShaderGroups; +typedef PipelineRTVulkan Pipeline; int main() { - /* - This sets up all necessary things and creates the vulkan device. - This must be called before any vulkan related things. - Things like VkDevice are static members of the VulkanDevice class. - */ VulkanDevice::CreateDevice(); + WindowVulkan window(1280, 720, "HelloVulkan"); + VkCommandBuffer cmd = window.StartInit(); + Raygenspv::CreateShader(); Closesthitspv::CreateShader(); Misspv::CreateShader(); + ShaderBindingTableVulkan::Init(); std::array layouts {{Raygenspv::layout}}; - PipelineRTVulkan::Init(layouts); + Pipeline::Init(cmd, layouts); DescriptorPool pool; pool.sets.resize(1); - pool.BuildPool(DescriptorPool::GetPoolSizes(), layouts); - - WindowVulkan window(1280, 720, "HelloVulkan"); - - /* - StartInit gives you a VkCommandBuffer to use before the event loop starts - Use this for inititializing things like textures. - */ - VkCommandBuffer cmd = window.StartInit(); + pool.BuildPool(DescriptorPool::GetPoolSizes(), layouts); Mesh triangleMesh; std::array verts {{{-150, -150, 100}, {0, 150, 100}, {150, -150, 100}}}; @@ -77,17 +75,10 @@ int main() { }; vkUpdateDescriptorSets(VulkanDevice::device, 2, write, 0, nullptr); - - /* - FinishInit executes all commands recorded to StartInit. - This must be called before the the event loops starts if you called StartInit before. - */ - window.FinishInit(); - - window.SetPipelineRT(); + window.SetPipelineRT(); window.descriptorsRt = pool.sets; - + window.FinishInit(); window.Render(); window.StartSync(); } diff --git a/examples/VulkanTriangle/project.json b/examples/VulkanTriangle/project.json index 61eba87..b30faa8 100644 --- a/examples/VulkanTriangle/project.json +++ b/examples/VulkanTriangle/project.json @@ -7,7 +7,7 @@ "dependencies": [ { "path":"../../project.json", - "configuration":"lib-vulkan" + "configuration":"lib-vulkan-debug" } ], "shaders": [ diff --git a/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm b/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm index 4901901..bbc2f54 100644 --- a/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm +++ b/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm @@ -26,10 +26,19 @@ export module Crafter.Graphics:PipelineRTVulkan; import std; import :VulkanDevice; import :VulkanBuffer; +import :ShaderBindingTableVulkan; import :Types; export namespace Crafter { - template + template + struct ShaderGroup { + static constexpr std::uint32_t generalShader = GeneralShader; + static constexpr std::uint32_t closestHitShader = ClosestHitShader; + static constexpr std::uint32_t anyHitShader = AnyHitShader; + static constexpr std::uint32_t intersectionShader = IntersectionShader; + }; + + template class PipelineRTVulkan { public: inline static VkPipeline pipeline; @@ -41,7 +50,7 @@ export namespace Crafter { inline static VkStridedDeviceAddressRegionKHR hitRegion; inline static VkStridedDeviceAddressRegionKHR callableRegion; - static void Init(std::span setLayouts) { + static void Init(VkCommandBuffer cmd, std::span setLayouts) { VkPipelineLayoutCreateInfo pipelineLayoutInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .setLayoutCount = static_cast(setLayouts.size()), @@ -50,144 +59,146 @@ export namespace Crafter { VulkanDevice::CheckVkResult(vkCreatePipelineLayout(VulkanDevice::device, &pipelineLayoutInfo, nullptr, &pipelineLayout)); - std::array shaderStages; + constexpr auto groupIndexSeq = std::make_index_sequence>{}; - shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStages[0].stage = Raygen::_stage; - shaderStages[0].module = Raygen::shader; - shaderStages[0].pName = Raygen::_entrypoint.value; - shaderStages[0].flags = 0; - shaderStages[0].pSpecializationInfo = nullptr; - shaderStages[0].pNext = nullptr; - - shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStages[1].stage = Miss::_stage; - shaderStages[1].module = Miss::shader; - shaderStages[1].pName = Miss::_entrypoint.value; - shaderStages[1].flags = 0; - shaderStages[1].pSpecializationInfo = nullptr; - shaderStages[1].pNext = nullptr; - - shaderStages[2].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStages[2].stage = ClosestHit::_stage; - shaderStages[2].module = ClosestHit::shader; - shaderStages[2].pName = ClosestHit::_entrypoint.value; - shaderStages[2].flags = 0; - shaderStages[2].pSpecializationInfo = nullptr; - shaderStages[2].pNext = nullptr; - - shaderStages[3].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStages[3].stage = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; - shaderStages[3].module = ShadowClosestHit::shader; - shaderStages[3].pName = ShadowClosestHit::_entrypoint.value; - shaderStages[3].flags = 0; - shaderStages[3].pSpecializationInfo = nullptr; - shaderStages[3].pNext = nullptr; - - shaderStages[4].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStages[4].stage = ShadowMiss::_stage; - shaderStages[4].module = ShadowMiss::shader; - shaderStages[4].pName = ShadowMiss::_entrypoint.value; - shaderStages[4].flags = 0; - shaderStages[4].pSpecializationInfo = nullptr; - shaderStages[4].pNext = nullptr; - - std::array groups {{ - { - .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, - .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, - .generalShader = 0, - .closestHitShader = VK_SHADER_UNUSED_KHR, - .anyHitShader = VK_SHADER_UNUSED_KHR, - .intersectionShader = VK_SHADER_UNUSED_KHR - }, - { - .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, - .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, - .generalShader = 1, - .closestHitShader = VK_SHADER_UNUSED_KHR, - .anyHitShader = VK_SHADER_UNUSED_KHR, - .intersectionShader = VK_SHADER_UNUSED_KHR - }, - { - .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, - .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR, - .generalShader = VK_SHADER_UNUSED_KHR, - .closestHitShader = 2, - .anyHitShader = VK_SHADER_UNUSED_KHR, - .intersectionShader = VK_SHADER_UNUSED_KHR - }, - { - .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, - .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR, - .generalShader = VK_SHADER_UNUSED_KHR, - .closestHitShader = 3, - .anyHitShader = VK_SHADER_UNUSED_KHR, - .intersectionShader = VK_SHADER_UNUSED_KHR - }, - { - .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, - .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, - .generalShader = 4, - .closestHitShader = VK_SHADER_UNUSED_KHR, - .anyHitShader = VK_SHADER_UNUSED_KHR, - .intersectionShader = VK_SHADER_UNUSED_KHR - } - }}; + constexpr std::array> groups = GetShaderGroups(groupIndexSeq); VkRayTracingPipelineCreateInfoKHR rtPipelineInfo{ .sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR, - .stageCount = static_cast(shaderStages.size()), - .pStages = shaderStages.data(), + .stageCount = static_cast(ShaderBindingTableVulkan::shaderStages.size()), + .pStages = ShaderBindingTableVulkan::shaderStages.data(), .groupCount = static_cast(groups.size()), .pGroups = groups.data(), - .maxPipelineRayRecursionDepth = 2, + .maxPipelineRayRecursionDepth = 1, .layout = pipelineLayout }; VulkanDevice::CheckVkResult(VulkanDevice::vkCreateRayTracingPipelinesKHR(VulkanDevice::device, {}, {}, 1, &rtPipelineInfo, nullptr, &pipeline)); - std::uint32_t handleSize = VulkanDevice::rayTracingProperties.shaderGroupHandleSize; - std::uint32_t handleAlignment = VulkanDevice::rayTracingProperties.shaderGroupHandleAlignment; - std::uint32_t baseAlignment = VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment; - std::uint32_t groupCount = rtPipelineInfo.groupCount; - - std::size_t dataSize = handleSize * groupCount; + std::size_t dataSize = VulkanDevice::rayTracingProperties.shaderGroupHandleSize * rtPipelineInfo.groupCount; shaderHandles.resize(dataSize); - VulkanDevice::CheckVkResult(VulkanDevice::vkGetRayTracingShaderGroupHandlesKHR(VulkanDevice::device, pipeline, 0, groupCount, dataSize, shaderHandles.data())); + VulkanDevice::CheckVkResult(VulkanDevice::vkGetRayTracingShaderGroupHandlesKHR(VulkanDevice::device, pipeline, 0, rtPipelineInfo.groupCount, dataSize, shaderHandles.data())); - std::uint32_t sbtStride = AlignUp(handleSize, handleAlignment); - std::uint32_t raygenOffset = 0; - std::uint32_t missOffset = AlignUp(raygenOffset + sbtStride, baseAlignment); - std::uint32_t hitOffset = AlignUp(missOffset + sbtStride * 2, baseAlignment); + std::uint32_t sbtStride = AlignUp(VulkanDevice::rayTracingProperties.shaderGroupHandleSize, VulkanDevice::rayTracingProperties.shaderGroupHandleAlignment); - std::uint32_t hitGroupCount = 2; - std::size_t bufferSize = hitOffset + sbtStride * hitGroupCount; + raygenRegion.stride = sbtStride; + raygenRegion.deviceAddress = 0; + raygenRegion.size = GetGroupCount(groupIndexSeq) * sbtStride; + missRegion.stride = sbtStride; + missRegion.deviceAddress = AlignUp(raygenRegion.size, VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment); + missRegion.size = GetGroupCount(groupIndexSeq) * sbtStride; + + hitRegion.stride = sbtStride; + hitRegion.deviceAddress = AlignUp(missRegion.deviceAddress + missRegion.size, VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment); + hitRegion.size = GetGroupCount(groupIndexSeq) * sbtStride; + + std::size_t bufferSize = hitRegion.deviceAddress + hitRegion.size; sbtBuffer.Create(VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferSize); - // Ray generation shader (group 0) - std::memcpy(sbtBuffer.value + raygenOffset, shaderHandles.data() + 0 * handleSize, handleSize); - raygenRegion.deviceAddress = sbtBuffer.address + raygenOffset; - raygenRegion.stride = sbtStride; - raygenRegion.size = sbtStride; + AddShaderGroupsToBuffer(sbtStride, groupIndexSeq); + sbtBuffer.FlushDevice(cmd, VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); - std::memcpy(sbtBuffer.value + missOffset, shaderHandles.data() + 1 * handleSize, handleSize); - std::memcpy(sbtBuffer.value + missOffset + 1 * sbtStride, shaderHandles.data() + 4 * handleSize, handleSize); - missRegion.deviceAddress = sbtBuffer.address + missOffset; - missRegion.stride = sbtStride; - missRegion.size = sbtStride * 2; - - std::memcpy(sbtBuffer.value + hitOffset + 0 * sbtStride, shaderHandles.data() + 2 * handleSize, handleSize); - std::memcpy(sbtBuffer.value + hitOffset + 1 * sbtStride, shaderHandles.data() + 3 * handleSize, handleSize); - hitRegion.deviceAddress = sbtBuffer.address + hitOffset; - hitRegion.stride = sbtStride; - hitRegion.size = sbtStride * hitGroupCount; + raygenRegion.deviceAddress += sbtBuffer.address; + missRegion.deviceAddress += sbtBuffer.address; + hitRegion.deviceAddress += sbtBuffer.address; callableRegion.deviceAddress = 0; callableRegion.stride = 0; callableRegion.size = 0; } + private: + template + consteval static void AddShaderGroup(std::array>& groups) { + using groupTemplate = std::tuple_element_t; + VkRayTracingShaderGroupTypeKHR groupType; + if constexpr(groupTemplate::generalShader != VK_SHADER_UNUSED_KHR) { + groupType = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR; + } else if constexpr(groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR) { + groupType = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR; + } else { + static_assert( + groupTemplate::generalShader != VK_SHADER_UNUSED_KHR || + groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR, + "Shader group must define either a general or closest-hit shader" + ); + } + groups[index] = { + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, + .type = groupType, + .generalShader = groupTemplate::generalShader, + .closestHitShader = groupTemplate::closestHitShader, + .anyHitShader = groupTemplate::anyHitShader, + .intersectionShader = groupTemplate::intersectionShader + }; + } + template + consteval static std::array> GetShaderGroups(std::index_sequence) { + std::array> groups{}; + (AddShaderGroup(groups), ...); + return groups; + } + + template + consteval static void GetGroupCountImpl(std::uint32_t& count) { + using groupTemplate = std::tuple_element_t; + if constexpr(groupTemplate::generalShader != VK_SHADER_UNUSED_KHR) { + using shaderTemplate = std::tuple_element_t; + if constexpr(shaderTemplate::_stage == stage) { + count++; + } + } else if constexpr(groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR) { + using shaderTemplate = std::tuple_element_t; + if constexpr(shaderTemplate::_stage == stage) { + count++; + } + } else { + static_assert( + groupTemplate::generalShader != VK_SHADER_UNUSED_KHR || + groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR, + "Shader group must define either a general or closest-hit shader" + ); + } + } + template + consteval static std::uint32_t GetGroupCount(std::index_sequence) { + std::uint32_t count = 0; + (GetGroupCountImpl(count), ...); + return count; + } + + template + static void AddShaderGroupToBuffer(std::uint32_t sbtStride, std::uint32_t& offset) { + using groupTemplate = std::tuple_element_t; + if constexpr(groupTemplate::generalShader != VK_SHADER_UNUSED_KHR) { + using shaderTemplate = std::tuple_element_t; + if constexpr(shaderTemplate::_stage == stage) { + std::memcpy(sbtBuffer.value + offset, shaderHandles.data() + index * VulkanDevice::rayTracingProperties.shaderGroupHandleSize, VulkanDevice::rayTracingProperties.shaderGroupHandleSize); + offset += sbtStride; + } + } else if constexpr(groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR) { + using shaderTemplate = std::tuple_element_t; + if constexpr(shaderTemplate::_stage == stage) { + std::memcpy(sbtBuffer.value + offset, shaderHandles.data() + index * VulkanDevice::rayTracingProperties.shaderGroupHandleSize, VulkanDevice::rayTracingProperties.shaderGroupHandleSize); + offset += sbtStride; + } + } else { + static_assert( + groupTemplate::generalShader != VK_SHADER_UNUSED_KHR || + groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR, + "Shader group must define either a general or closest-hit shader" + ); + } + } + template + static void AddShaderGroupsToBuffer(std::uint32_t sbtStride, std::index_sequence) { + std::uint32_t offset = 0; + (AddShaderGroupToBuffer(sbtStride, offset), ...); + offset = AlignUp(offset, VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment); + (AddShaderGroupToBuffer(sbtStride, offset), ...); + offset = AlignUp(offset, VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment); + (AddShaderGroupToBuffer(sbtStride, offset), ...); + } }; } diff --git a/interfaces/Crafter.Graphics-ShaderBindingTableVulkan.cppm b/interfaces/Crafter.Graphics-ShaderBindingTableVulkan.cppm new file mode 100644 index 0000000..6e1101f --- /dev/null +++ b/interfaces/Crafter.Graphics-ShaderBindingTableVulkan.cppm @@ -0,0 +1,56 @@ +/* +Crafter®.Graphics +Copyright (C) 2026 Catcrafts® +catcrafts.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License version 3.0 as published by the Free Software Foundation; + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +module; +#ifdef CRAFTER_GRAPHICS_VULKAN +#include +#endif +export module Crafter.Graphics:ShaderBindingTableVulkan; +#ifdef CRAFTER_GRAPHICS_VULKAN +import std; +import :VulkanDevice; +import :VulkanBuffer; +import :Types; + +export namespace Crafter { + template + class ShaderBindingTableVulkan { + public: + inline static std::array> shaderStages; + static void Init() { + AddAllToSBT(std::make_index_sequence>{}); + } + private: + template + static void AddToSBT() { + shaderStages[index] = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = std::tuple_element_t::_stage, + .module = std::tuple_element_t::shader, + .pName = std::tuple_element_t::_entrypoint.value + }; + } + template + static void AddAllToSBT(std::index_sequence) { + (AddToSBT(), ...); + } + }; +} + +#endif \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-Window.cppm b/interfaces/Crafter.Graphics-Window.cppm index 5ae72dd..465904c 100644 --- a/interfaces/Crafter.Graphics-Window.cppm +++ b/interfaces/Crafter.Graphics-Window.cppm @@ -313,14 +313,14 @@ export namespace Crafter { VkCommandBuffer StartInit(); void FinishInit(); - template + template void SetPipelineRT() { - rtPipeline = PipelineRTVulkan::pipeline; - rtPipelineLayout = PipelineRTVulkan::pipelineLayout; - raygenRegion = PipelineRTVulkan::raygenRegion; - missRegion = PipelineRTVulkan::missRegion; - hitRegion = PipelineRTVulkan::hitRegion; - callableRegion = PipelineRTVulkan::callableRegion; + rtPipeline = Pipeline::pipeline; + rtPipelineLayout = Pipeline::pipelineLayout; + raygenRegion = Pipeline::raygenRegion; + missRegion = Pipeline::missRegion; + hitRegion = Pipeline::hitRegion; + callableRegion = Pipeline::callableRegion; } inline static wl_compositor* compositor = nullptr; static void wl_surface_frame_done(void *data, wl_callback *cb, uint32_t time); diff --git a/interfaces/Crafter.Graphics.cppm b/interfaces/Crafter.Graphics.cppm index 9d01123..e51d857 100644 --- a/interfaces/Crafter.Graphics.cppm +++ b/interfaces/Crafter.Graphics.cppm @@ -38,6 +38,7 @@ export import :VulkanTransition; export import :VulkanBuffer; export import :DescriptorPoolVulkan; export import :ShaderVulkan; +export import :ShaderBindingTableVulkan; export import :PipelineRTVulkan; export import :RenderingElement3DVulkan; #endif diff --git a/project.json b/project.json index a0caa3c..8f925d5 100644 --- a/project.json +++ b/project.json @@ -4,7 +4,7 @@ { "name": "base", "implementations": ["implementations/Crafter.Graphics-Font", "implementations/Crafter.Graphics-Shm", "implementations/Crafter.Graphics-Window", "implementations/Crafter.Graphics-MouseElement", "implementations/Crafter.Graphics-Transform", "implementations/Crafter.Graphics-GridElement", "implementations/Crafter.Graphics-Image"], - "interfaces": ["interfaces/Crafter.Graphics-Window", "interfaces/Crafter.Graphics", "interfaces/Crafter.Graphics-Types", "interfaces/Crafter.Graphics-Font", "interfaces/Crafter.Graphics-Image", "interfaces/Crafter.Graphics-Shm", "interfaces/Crafter.Graphics-Animation", "interfaces/Crafter.Graphics-RenderingElement", "interfaces/Crafter.Graphics-MouseElement", "interfaces/Crafter.Graphics-Transform", "interfaces/Crafter.Graphics-GridElement", "interfaces/Crafter.Graphics-VulkanDevice", "interfaces/Crafter.Graphics-VulkanTransition", "interfaces/Crafter.Graphics-Mesh", "interfaces/Crafter.Graphics-VulkanBuffer", "interfaces/Crafter.Graphics-RenderingElement3DVulkan", "interfaces/Crafter.Graphics-DescriptorPoolVulkan", "interfaces/Crafter.Graphics-ShaderVulkan", "interfaces/Crafter.Graphics-PipelineRTVulkan"], + "interfaces": ["interfaces/Crafter.Graphics-Window", "interfaces/Crafter.Graphics", "interfaces/Crafter.Graphics-Types", "interfaces/Crafter.Graphics-Font", "interfaces/Crafter.Graphics-Image", "interfaces/Crafter.Graphics-Shm", "interfaces/Crafter.Graphics-Animation", "interfaces/Crafter.Graphics-RenderingElement", "interfaces/Crafter.Graphics-MouseElement", "interfaces/Crafter.Graphics-Transform", "interfaces/Crafter.Graphics-GridElement", "interfaces/Crafter.Graphics-VulkanDevice", "interfaces/Crafter.Graphics-VulkanTransition", "interfaces/Crafter.Graphics-Mesh", "interfaces/Crafter.Graphics-VulkanBuffer", "interfaces/Crafter.Graphics-RenderingElement3DVulkan", "interfaces/Crafter.Graphics-DescriptorPoolVulkan", "interfaces/Crafter.Graphics-ShaderVulkan", "interfaces/Crafter.Graphics-PipelineRTVulkan", "interfaces/Crafter.Graphics-ShaderBindingTableVulkan"], "type": "library" }, {