From 5e3a7738ede0f333cf259d4249a3f0800caeeac2 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Thu, 29 Jan 2026 23:31:56 +0100 Subject: [PATCH] fixed descriptors --- examples/VulkanAnimation/closesthit.glsl | 12 ++ examples/VulkanAnimation/main.cpp | 128 ++++++++++++++++++ examples/VulkanAnimation/miss.glsl | 9 ++ examples/VulkanAnimation/project.json | 32 +++++ examples/VulkanAnimation/raygen.glsl | 47 +++++++ examples/VulkanTriangle/main.cpp | 12 +- .../Crafter.Graphics-Window_vulkan.cpp | 1 + ...after.Graphics-DescriptorLayoutVulkan.cppm | 128 ------------------ ...Crafter.Graphics-DescriptorPoolVulkan.cppm | 97 ++++++++++--- .../Crafter.Graphics-PipelineRTVulkan.cppm | 7 +- interfaces/Crafter.Graphics-ShaderVulkan.cppm | 22 ++- interfaces/Crafter.Graphics-Window.cppm | 3 +- interfaces/Crafter.Graphics.cppm | 1 - project.json | 2 +- 14 files changed, 334 insertions(+), 167 deletions(-) create mode 100644 examples/VulkanAnimation/closesthit.glsl create mode 100644 examples/VulkanAnimation/main.cpp create mode 100644 examples/VulkanAnimation/miss.glsl create mode 100644 examples/VulkanAnimation/project.json create mode 100644 examples/VulkanAnimation/raygen.glsl delete mode 100644 interfaces/Crafter.Graphics-DescriptorLayoutVulkan.cppm diff --git a/examples/VulkanAnimation/closesthit.glsl b/examples/VulkanAnimation/closesthit.glsl new file mode 100644 index 0000000..9a511b6 --- /dev/null +++ b/examples/VulkanAnimation/closesthit.glsl @@ -0,0 +1,12 @@ +#version 460 +#extension GL_EXT_ray_tracing : enable +#extension GL_EXT_nonuniform_qualifier : enable + +layout(location = 0) rayPayloadInEXT vec3 hitValue; +hitAttributeEXT vec2 attribs; + +void main() +{ + const vec3 barycentricCoords = vec3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y); + hitValue = barycentricCoords; +} \ No newline at end of file diff --git a/examples/VulkanAnimation/main.cpp b/examples/VulkanAnimation/main.cpp new file mode 100644 index 0000000..9238e88 --- /dev/null +++ b/examples/VulkanAnimation/main.cpp @@ -0,0 +1,128 @@ +#include + +import Crafter.Graphics; +using namespace Crafter; +import std; +import Crafter.Event; +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; + +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(); + Raygenspv::CreateShader(); + Closesthitspv::CreateShader(); + Misspv::CreateShader(); + DescriptorLayoutVulkan::Init(); + PipelineRTVulkan::Init(); + DescriptorPool<1, Raygenspv, Closesthitspv, Misspv> pool; + pool.setsCount = 2; + pool.BuildPool(0); + + 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}}; + triangleMesh.Build(verts, index, cmd); + 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(2); + + window.SetPipelineRT(); + window.descriptorsRt = pool.sets; + + RenderingElement3DVulkan::BuildTLAS(cmd, 0); + VkDescriptorImageInfo imageInfo = { + .imageView = window.imageViews[0], + .imageLayout = VK_IMAGE_LAYOUT_GENERAL + }; + + VkWriteDescriptorSetAccelerationStructureKHR writeDescriptorSetAccelerationStructure { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, + .accelerationStructureCount = 1, + .pAccelerationStructures = &RenderingElement3DVulkan::tlases[0].accelerationStructure + }; + + VkWriteDescriptorSet write[2] = { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = &writeDescriptorSetAccelerationStructure, + .dstSet = pool.sets[0], + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, + }, + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = pool.sets[0], + .dstBinding = 1, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .pImageInfo = &imageInfo + } + }; + 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(); + + EventListener updateListener(&window.onRender, [&](VkCommandBuffer cmd){ + RenderingElement3DVulkan::BuildTLAS(cmd, window.currentBuffer); + VkDescriptorImageInfo imageInfo = { + .imageView = window.imageViews[window.currentBuffer], + .imageLayout = VK_IMAGE_LAYOUT_GENERAL + }; + + VkWriteDescriptorSetAccelerationStructureKHR writeDescriptorSetAccelerationStructure { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, + .accelerationStructureCount = 1, + .pAccelerationStructures = &RenderingElement3DVulkan::tlases[window.currentBuffer].accelerationStructure + }; + + VkWriteDescriptorSet write[2] = { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = &writeDescriptorSetAccelerationStructure, + .dstSet = pool.sets[window.currentBuffer], + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, + }, + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = pool.sets[window.currentBuffer], + .dstBinding = 1, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .pImageInfo = &imageInfo + } + }; + vkUpdateDescriptorSets(VulkanDevice::device, 2, write, 0, nullptr); + }); + + window.Render(); + window.StartUpdate(); + window.StartSync(); +} diff --git a/examples/VulkanAnimation/miss.glsl b/examples/VulkanAnimation/miss.glsl new file mode 100644 index 0000000..1478ecf --- /dev/null +++ b/examples/VulkanAnimation/miss.glsl @@ -0,0 +1,9 @@ +#version 460 +#extension GL_EXT_ray_tracing : enable + +layout(location = 0) rayPayloadInEXT vec3 hitValue; + +void main() +{ + hitValue = vec3(1, 1, 1); +} \ No newline at end of file diff --git a/examples/VulkanAnimation/project.json b/examples/VulkanAnimation/project.json new file mode 100644 index 0000000..b30faa8 --- /dev/null +++ b/examples/VulkanAnimation/project.json @@ -0,0 +1,32 @@ +{ + "name": "crafter-graphics", + "configurations": [ + { + "name": "executable", + "implementations": ["main"], + "dependencies": [ + { + "path":"../../project.json", + "configuration":"lib-vulkan-debug" + } + ], + "shaders": [ + { + "path":"raygen.glsl", + "type": 6, + "entrypoint":"main" + }, + { + "path":"closesthit.glsl", + "type": 9, + "entrypoint":"main" + }, + { + "path":"miss.glsl", + "type": 10, + "entrypoint":"main" + } + ] + } + ] +} diff --git a/examples/VulkanAnimation/raygen.glsl b/examples/VulkanAnimation/raygen.glsl new file mode 100644 index 0000000..ad7b74c --- /dev/null +++ b/examples/VulkanAnimation/raygen.glsl @@ -0,0 +1,47 @@ +#version 460 +#extension GL_EXT_ray_tracing : enable +#extension GL_EXT_shader_image_load_formatted : enable + +layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; +layout(binding = 1, set = 0, rgba8) uniform writeonly image2D image; + +layout(location = 0) rayPayloadEXT vec3 hitValue; + +void main() +{ + // Pixel coordinates + uvec2 pixel = gl_LaunchIDEXT.xy; + uvec2 resolution = gl_LaunchSizeEXT.xy; + + // Normalized coordinates in range [-1, 1] + vec2 uv = (vec2(pixel) + 0.5) / vec2(resolution); + vec2 ndc = uv * 2.0 - 1.0; + + // Camera parameters + vec3 origin = vec3(0.0, 0.0, -300.0); + + float aspect = float(resolution.x) / float(resolution.y); + float fov = radians(60.0); + float tanHalfFov = tan(fov * 0.5); + + // Simple pinhole camera facing +Z + vec3 direction = normalize(vec3( + ndc.x * aspect * tanHalfFov, + -ndc.y * tanHalfFov, + 1.0 + )); + + traceRayEXT( + topLevelAS, + gl_RayFlagsNoneEXT, + 0xff, + 0, 0, 0, + origin, + 0.001, + direction, + 10000.0, + 0 + ); + + imageStore(image, ivec2(pixel), vec4(hitValue, 1.0)); +} diff --git a/examples/VulkanTriangle/main.cpp b/examples/VulkanTriangle/main.cpp index 3dd49e9..5013de4 100644 --- a/examples/VulkanTriangle/main.cpp +++ b/examples/VulkanTriangle/main.cpp @@ -11,8 +11,6 @@ typedef VulkanShader<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_K typedef VulkanShader<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR, 0, {{}}> Misspv; int main() { - - std::this_thread::sleep_for(std::chrono::milliseconds(500)); /* This sets up all necessary things and creates the vulkan device. This must be called before any vulkan related things. @@ -22,11 +20,11 @@ int main() { Raygenspv::CreateShader(); Closesthitspv::CreateShader(); Misspv::CreateShader(); - DescriptorLayoutVulkan::Init(); - PipelineRTVulkan::Init(); - DescriptorPool<1, Raygenspv, Closesthitspv, Misspv> pool; - pool.setsCount = 1; - pool.BuildPool(0); + std::array layouts {{Raygenspv::layout, Closesthitspv::layout, Misspv::layout}}; + PipelineRTVulkan::Init(layouts); + DescriptorPool pool; + pool.sets.resize(1); + pool.BuildPool(DescriptorPool::GetPoolSizes(), layouts); WindowVulkan window(1280, 720, "HelloVulkan"); diff --git a/implementations/Crafter.Graphics-Window_vulkan.cpp b/implementations/Crafter.Graphics-Window_vulkan.cpp index 5dea6f7..a2a0ace 100644 --- a/implementations/Crafter.Graphics-Window_vulkan.cpp +++ b/implementations/Crafter.Graphics-Window_vulkan.cpp @@ -368,6 +368,7 @@ void WindowVulkan::Render() { range ); + onRender.Invoke(drawCmdBuffers[currentBuffer]); vkCmdBindPipeline(drawCmdBuffers[currentBuffer], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rtPipeline); VkBindDescriptorSetsInfo bindDescriptorSetsInfo{ diff --git a/interfaces/Crafter.Graphics-DescriptorLayoutVulkan.cppm b/interfaces/Crafter.Graphics-DescriptorLayoutVulkan.cppm deleted file mode 100644 index 396a7fe..0000000 --- a/interfaces/Crafter.Graphics-DescriptorLayoutVulkan.cppm +++ /dev/null @@ -1,128 +0,0 @@ -/* -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:DescriptorLayoutVulkan; -#ifdef CRAFTER_GRAPHICS_VULKAN -import std; -import :VulkanDevice; -import :Types; - -export namespace Crafter { - struct DescriptorEntry { - VkDescriptorType type; - bool occured = true; - }; - - template - class DescriptorLayoutVulkan { - public: - inline static VkDescriptorSetLayout descriptorSetLayout[sizeof...(Shaders)]; - - template - consteval static void GetOccuringDescriptors(std::array& types) { - for (const DescriptorBinding& binding : Shader::descriptors) { - for (DescriptorEntry& type : types) { - if (type.type == binding.type) { - type.occured = true; - } - } - } - } - - consteval static std::uint32_t GetUniqueDiscriptorCount() { - std::array types = {{{VK_DESCRIPTOR_TYPE_SAMPLER, 0},{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0},{VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0},{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 0},{VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0},{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 0},{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 0},{VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 0},{VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, 0},{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 0},{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV, 0},{VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM, 0},{VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, 0},{VK_DESCRIPTOR_TYPE_MUTABLE_EXT, 0},{VK_DESCRIPTOR_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_NV, 0},{VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, 0},{VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, 0}}}; - - (GetOccuringDescriptors(types), ... ); - - std::uint32_t size = 0; - for(DescriptorEntry& type : types) { - if(type.occured) { - size++; - } - } - - return size; - } - constexpr static std::uint32_t uniqueDescriptorCount = GetUniqueDiscriptorCount(); - - consteval static std::array GetPoolSizes() { - std::array types = {}; - for(std::uint32_t i = 0; i < uniqueDescriptorCount; i++){ - types[i].descriptorCount = 12345; - } - - ([&] { - for (const DescriptorBinding& binding : Shaders::descriptors) { - bool found = false; - for(VkDescriptorPoolSize& type : types) { - if(type.type == binding.type && type.descriptorCount != 12345) { - type.descriptorCount += 1; - found = true; - } - } - if(!found) { - for(std::uint32_t i = 0; i < uniqueDescriptorCount; i++){ - if(types[i].descriptorCount == 12345) { - types[i].type = binding.type; - types[i].descriptorCount = 1; - break; - } - } - } - } - }(), - ...); - - return types; - } - - template - consteval static std::array GetDescriptorSet() { - std::array set; - - for(std::uint32_t i = 0; i < Shader::descriptors.size(); i++) { - set[i] = {Shader::descriptors[i].slot, Shader::descriptors[i].type, 1, Shader::_stage, nullptr}; - } - - return set; - } - - public: - static void Init() { - std::uint32_t shaderIndex = 0; - - ([&] { - constexpr std::array setLayoutBindingsMesh = GetDescriptorSet(); - VkDescriptorSetLayoutCreateInfo descriptorLayoutInfoMesh = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = Shaders::descriptorCount, - .pBindings = setLayoutBindingsMesh.data() - }; - VulkanDevice::CheckVkResult(vkCreateDescriptorSetLayout(VulkanDevice::device, &descriptorLayoutInfoMesh, nullptr, &descriptorSetLayout[shaderIndex++])); - }(), - ...); - } - }; -} - -#endif \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-DescriptorPoolVulkan.cppm b/interfaces/Crafter.Graphics-DescriptorPoolVulkan.cppm index 9b0f885..24d6e90 100644 --- a/interfaces/Crafter.Graphics-DescriptorPoolVulkan.cppm +++ b/interfaces/Crafter.Graphics-DescriptorPoolVulkan.cppm @@ -26,51 +26,104 @@ export module Crafter.Graphics:DescriptorPoolVulkan; import std; import :VulkanDevice; import :Types; -import :DescriptorLayoutVulkan; import Crafter.Event; export namespace Crafter { - class DescriptorPoolBase { - public: - std::vector sets; + struct DescriptorEntry { + VkDescriptorType type; + bool occured = true; }; - template - class DescriptorPool : public DescriptorPoolBase { + + class DescriptorPool { public: Event onDescriptorRefresh; std::uint32_t setIndex = 0; - std::uint32_t setsCount = 0; - VkDescriptorPool descriptorPool[PoolCount] = { VK_NULL_HANDLE }; + std::vector sets; + VkDescriptorPool descriptorPool = VK_NULL_HANDLE; + template + consteval static void GetOccuringDescriptors(std::array& types) { + for (const DescriptorBinding& binding : Shader::descriptors) { + for (DescriptorEntry& type : types) { + if (type.type == binding.type) { + type.occured = true; + } + } + } + } + + template + consteval static std::uint32_t GetUniqueDiscriptorCount() { + std::array types = {{{VK_DESCRIPTOR_TYPE_SAMPLER, 0},{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0},{VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0},{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 0},{VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0},{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 0},{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 0},{VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 0},{VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, 0},{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 0},{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV, 0},{VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM, 0},{VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, 0},{VK_DESCRIPTOR_TYPE_MUTABLE_EXT, 0},{VK_DESCRIPTOR_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_NV, 0},{VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, 0},{VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, 0}}}; + + (GetOccuringDescriptors(types), ... ); + + std::uint32_t size = 0; + for(DescriptorEntry& type : types) { + if(type.occured) { + size++; + } + } + + return size; + } + + template + consteval static std::array()> GetPoolSizes() { + std::array()> types = {}; + for(std::uint32_t i = 0; i < GetUniqueDiscriptorCount(); i++){ + types[i].descriptorCount = 12345; + } + + ([&] { + for (const DescriptorBinding& binding : Shaders::descriptors) { + bool found = false; + for(VkDescriptorPoolSize& type : types) { + if(type.type == binding.type && type.descriptorCount != 12345) { + type.descriptorCount += 1; + found = true; + } + } + if(!found) { + for(std::uint32_t i = 0; i < GetUniqueDiscriptorCount(); i++){ + if(types[i].descriptorCount == 12345) { + types[i].type = binding.type; + types[i].descriptorCount = 1; + break; + } + } + } + } + }(), + ...); + + return types; + } + public: - void BuildPool(std::uint32_t poolIndex) { - if(descriptorPool[poolIndex] != VK_NULL_HANDLE) { - vkDestroyDescriptorPool(VulkanDevice::device, descriptorPool[poolIndex], nullptr); + void BuildPool(std::span poolSizes, std::span setLayouts) { + if(descriptorPool != VK_NULL_HANDLE) { + vkDestroyDescriptorPool(VulkanDevice::device, descriptorPool, nullptr); } - std::array::uniqueDescriptorCount> poolSizes = DescriptorLayoutVulkan::GetPoolSizes(); - for(VkDescriptorPoolSize& size : poolSizes) { - size.descriptorCount *= setsCount; - } VkDescriptorPoolCreateInfo descriptorPoolInfo { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .maxSets = static_cast(setsCount), - .poolSizeCount = DescriptorLayoutVulkan::uniqueDescriptorCount, + .maxSets = static_cast(sets.size()), + .poolSizeCount = static_cast(poolSizes.size()), .pPoolSizes = poolSizes.data() }; - VulkanDevice::CheckVkResult(vkCreateDescriptorPool(VulkanDevice::device, &descriptorPoolInfo, nullptr, &descriptorPool[poolIndex])); + VulkanDevice::CheckVkResult(vkCreateDescriptorPool(VulkanDevice::device, &descriptorPoolInfo, nullptr, &descriptorPool)); VkDescriptorSetAllocateInfo allocInfo { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = descriptorPool[poolIndex], - .descriptorSetCount = setsCount, - .pSetLayouts = DescriptorLayoutVulkan::descriptorSetLayout, + .descriptorPool = descriptorPool, + .descriptorSetCount = static_cast(sets.size()), + .pSetLayouts = setLayouts.data(), }; - sets.resize(setsCount); VulkanDevice::CheckVkResult(vkAllocateDescriptorSets(VulkanDevice::device, &allocInfo, sets.data())); setIndex = 0; diff --git a/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm b/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm index b433403..cdc8a70 100644 --- a/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm +++ b/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm @@ -25,7 +25,6 @@ export module Crafter.Graphics:PipelineRTVulkan; #ifdef CRAFTER_GRAPHICS_VULKAN import std; import :VulkanDevice; -import :DescriptorLayoutVulkan; import :VulkanBuffer; import :Types; @@ -42,11 +41,11 @@ export namespace Crafter { inline static VkStridedDeviceAddressRegionKHR hitRegion; inline static VkStridedDeviceAddressRegionKHR callableRegion; - static void Init() { + static void Init(std::span setLayouts) { VkPipelineLayoutCreateInfo pipelineLayoutInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = sizeof...(Shaders), - .pSetLayouts = DescriptorLayoutVulkan::descriptorSetLayout + .setLayoutCount = static_cast(setLayouts.size()), + .pSetLayouts = setLayouts.data() }; VulkanDevice::CheckVkResult(vkCreatePipelineLayout(VulkanDevice::device, &pipelineLayoutInfo, nullptr, &pipelineLayout)); diff --git a/interfaces/Crafter.Graphics-ShaderVulkan.cppm b/interfaces/Crafter.Graphics-ShaderVulkan.cppm index 6f9e767..16e6b08 100644 --- a/interfaces/Crafter.Graphics-ShaderVulkan.cppm +++ b/interfaces/Crafter.Graphics-ShaderVulkan.cppm @@ -47,10 +47,20 @@ export namespace Crafter { class VulkanShader { public: constexpr static VkShaderStageFlagBits _stage = stage; - constexpr static std::array descriptors = Descriptors; - constexpr static std::uint32_t descriptorCount = DescriptorCount; constexpr static StringLiteral _entrypoint = entrypoint; + constexpr static std::span descriptors = Descriptors; inline static VkShaderModule shader; + inline static VkDescriptorSetLayout layout; + + consteval static std::array GetDescriptorSet() { + std::array set; + + for(std::uint32_t i = 0; i < Descriptors.size(); i++) { + set[i] = {Descriptors[i].slot, Descriptors[i].type, 1, stage, nullptr}; + } + + return set; + } static void CreateShader() { std::ifstream file(path.value, std::ios::binary); @@ -78,6 +88,14 @@ export namespace Crafter { VkShaderModule shader_module; VulkanDevice::CheckVkResult(vkCreateShaderModule(VulkanDevice::device, &module_info, nullptr, &shader)); + + constexpr std::array setLayoutBindingsMesh = GetDescriptorSet(); + VkDescriptorSetLayoutCreateInfo descriptorLayoutInfoMesh = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = DescriptorCount, + .pBindings = setLayoutBindingsMesh.data() + }; + VulkanDevice::CheckVkResult(vkCreateDescriptorSetLayout(VulkanDevice::device, &descriptorLayoutInfoMesh, nullptr, &layout)); } }; } diff --git a/interfaces/Crafter.Graphics-Window.cppm b/interfaces/Crafter.Graphics-Window.cppm index e6b77f1..f580805 100644 --- a/interfaces/Crafter.Graphics-Window.cppm +++ b/interfaces/Crafter.Graphics-Window.cppm @@ -300,6 +300,7 @@ export namespace Crafter { xkb_keymap* xkb_keymap; xkb_context* xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); xkb_state* xkb_state; + Event onRender; std::vector descriptorsRt; void Render(); void QueueRender(); @@ -389,12 +390,10 @@ export namespace Crafter { std::vector imageViews; std::thread thread; std::vector drawCmdBuffers; - //std::vector frameBuffers; VkSubmitInfo submitInfo; Semaphores semaphores; uint32_t currentBuffer = 0; VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - //VkRenderPass renderPass = VK_NULL_HANDLE; VkPipeline rtPipeline; VkPipelineLayout rtPipelineLayout; VkStridedDeviceAddressRegionKHR raygenRegion; diff --git a/interfaces/Crafter.Graphics.cppm b/interfaces/Crafter.Graphics.cppm index 242002e..9d01123 100644 --- a/interfaces/Crafter.Graphics.cppm +++ b/interfaces/Crafter.Graphics.cppm @@ -37,7 +37,6 @@ export import :VulkanDevice; export import :VulkanTransition; export import :VulkanBuffer; export import :DescriptorPoolVulkan; -export import :DescriptorLayoutVulkan; export import :ShaderVulkan; export import :PipelineRTVulkan; export import :RenderingElement3DVulkan; diff --git a/project.json b/project.json index c7eab0b..a0caa3c 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/Crafter.Graphics-DescriptorLayoutVulkan"], + "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"], "type": "library" }, {