diff --git a/examples/VulkanTriangle/executable-linux.zip b/examples/VulkanTriangle/executable-linux.zip new file mode 100644 index 0000000..7e55202 Binary files /dev/null and b/examples/VulkanTriangle/executable-linux.zip differ diff --git a/examples/VulkanTriangle/executable-windows.zip b/examples/VulkanTriangle/executable-windows.zip new file mode 100644 index 0000000..d55aadf Binary files /dev/null and b/examples/VulkanTriangle/executable-windows.zip differ diff --git a/examples/VulkanTriangle/main.cpp b/examples/VulkanTriangle/main.cpp index 74406f8..7687e93 100644 --- a/examples/VulkanTriangle/main.cpp +++ b/examples/VulkanTriangle/main.cpp @@ -1,4 +1,5 @@ #include "vulkan/vulkan.h" +#include import Crafter.Graphics; using namespace Crafter; @@ -6,55 +7,69 @@ import std; import Crafter.Event; import Crafter.Math; -typedef VulkanShaderConst<"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR> Raygenspv; -typedef VulkanShaderConst<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR> Closesthitspv; -typedef VulkanShaderConst<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR> 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 PipelineRTVulkanConst Pipeline; -typedef DescriptorSetLayoutVulkanConst<3, {{ - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR, - }, - { - .binding = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR, - }, - { - .binding = 2, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR, - } -}}> descriptorSetLayout; int main() { Device::Initialize(); Window window(1280, 720, "HelloVulkan"); VkCommandBuffer cmd = window.StartInit(); + DescriptorHeapVulkan descriptorHeap; + descriptorHeap.Initialize(1,1,0); - Raygenspv::CreateShader(); - Closesthitspv::CreateShader(); - Misspv::CreateShader(); - ShaderBindingTableVulkanConst::Init(); + VkSpecializationMapEntry entry = { + .constantID = 0, + .offset = 0, + .size = sizeof(uint16_t) + }; - descriptorSetLayout::Init(); - std::array layouts {{descriptorSetLayout::layout}}; + VkSpecializationInfo specilizationInfo = { + .mapEntryCount = 1, + .pMapEntries = &entry, + .dataSize = sizeof(uint16_t), + .pData = &descriptorHeap.bufferStartElement + }; - DescriptorPool pool; - pool.sets.resize(1); - pool.BuildPool(DescriptorPool::GetPoolSizes(), layouts); + std::array shaders{{ + {"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR, &specilizationInfo}, + {"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR, nullptr}, + {"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, nullptr} + }}; - Pipeline::Init(cmd, layouts); + ShaderBindingTableVulkan shaderTable; + shaderTable.Init(shaders); + + std::array raygenGroups {{ + { + .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, + }, + }}; + std::array missGroups {{ + { + .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, + }, + }}; + std::array hitGroups {{ + { + .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, + }, + }}; + + PipelineRTVulkan pipeline; + pipeline.Init(cmd, raygenGroups, missGroups, hitGroups, shaderTable); Mesh triangleMesh; std::array, 3> verts {{{-150, -150, 100}, {0, 150, 100}, {150, -150, 100}}}; @@ -75,59 +90,111 @@ int main() { MatrixRowMajor transform = MatrixRowMajor::Identity(); std::memcpy(renderer.instance.transform.matrix, transform.m, sizeof(transform.m)); - RenderingElement3D::tlases.resize(1); RenderingElement3D::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 = &RenderingElement3D::tlases[0].accelerationStructure - }; - - VulkanBuffer lightBuffer; - lightBuffer.Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 1); - - VkWriteDescriptorSet write[3] = { - { - .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 - }, - { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = pool.sets[0], - .dstBinding = 2, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .pBufferInfo = &lightBuffer.descriptor - } - }; - vkUpdateDescriptorSets(Device::device, 3, write, 0, nullptr); - - - window.SetPipelineRT(); - window.descriptorsRt = pool.sets; + RenderingElement3D::BuildTLAS(cmd, 1); + RenderingElement3D::BuildTLAS(cmd, 2); window.FinishInit(); + + VkDeviceAddressRangeKHR tlasRange0 = { + .address = RenderingElement3D::tlases[0].address, + }; + + VkDeviceAddressRangeKHR tlasRange1 = { + .address = RenderingElement3D::tlases[1].address, + }; + + VkDeviceAddressRangeKHR tlasRange2 = { + .address = RenderingElement3D::tlases[2].address, + }; + + VkImageDescriptorInfoEXT imageInfo0 = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT, + .pView = &window.imageViews[0], + .layout = VK_IMAGE_LAYOUT_GENERAL + }; + + VkImageDescriptorInfoEXT imageInfo1 = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT, + .pView = &window.imageViews[1], + .layout = VK_IMAGE_LAYOUT_GENERAL + }; + + VkImageDescriptorInfoEXT imageInfo2 = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT, + .pView = &window.imageViews[2], + .layout = VK_IMAGE_LAYOUT_GENERAL + }; + + VkResourceDescriptorInfoEXT resources[6] = { + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, + .data = { .pAddressRange = &tlasRange0} + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .data = { .pImage = &imageInfo0 } + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, + .data = { .pAddressRange = &tlasRange1} + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .data = { .pImage = &imageInfo1 } + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, + .data = { .pAddressRange = &tlasRange2} + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .data = { .pImage = &imageInfo2 } + }, + }; + + VkHostAddressRangeEXT destinations[6] = { + { + .address = descriptorHeap.resourceHeap[0].value + descriptorHeap.bufferStartOffset, + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[0].value, + .size = Device::descriptorHeapProperties.imageDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[1].value + descriptorHeap.bufferStartOffset, + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[1].value, + .size = Device::descriptorHeapProperties.imageDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[2].value + descriptorHeap.bufferStartOffset, + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[2].value, + .size = Device::descriptorHeapProperties.imageDescriptorSize + }, + }; + + Device::vkWriteResourceDescriptorsEXT(Device::device, 6, resources, destinations); + + descriptorHeap.resourceHeap[0].FlushDevice(); + descriptorHeap.resourceHeap[1].FlushDevice(); + descriptorHeap.resourceHeap[2].FlushDevice(); + + window.pipeline = &pipeline; + window.descriptorHeap = &descriptorHeap; + window.Render(); window.StartSync(); } diff --git a/examples/VulkanTriangle/project.json b/examples/VulkanTriangle/project.json index df14df2..292a1cd 100644 --- a/examples/VulkanTriangle/project.json +++ b/examples/VulkanTriangle/project.json @@ -10,8 +10,10 @@ "configuration":"lib-win32-vulkan-debug" } ], + "march": "x86-64-v3", + "mtune": "generic", "target": "x86_64-w64-mingw32", - "debug": true, + "debug": false, "shaders": [ { "path":"raygen.glsl", diff --git a/examples/VulkanTriangle/raygen.glsl b/examples/VulkanTriangle/raygen.glsl index ad7b74c..eff2633 100644 --- a/examples/VulkanTriangle/raygen.glsl +++ b/examples/VulkanTriangle/raygen.glsl @@ -1,14 +1,17 @@ #version 460 #extension GL_EXT_ray_tracing : enable #extension GL_EXT_shader_image_load_formatted : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int16 : enable +#extension GL_EXT_descriptor_heap : enable +#extension GL_EXT_nonuniform_qualifier : enable -layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; -layout(binding = 1, set = 0, rgba8) uniform writeonly image2D image; +layout(constant_id = 0) const uint16_t bufferStart = 0us; +layout(descriptor_heap) uniform accelerationStructureEXT topLevelAS[]; +layout(descriptor_heap) uniform writeonly image2D image[]; layout(location = 0) rayPayloadEXT vec3 hitValue; -void main() -{ +void main() { // Pixel coordinates uvec2 pixel = gl_LaunchIDEXT.xy; uvec2 resolution = gl_LaunchSizeEXT.xy; @@ -32,7 +35,7 @@ void main() )); traceRayEXT( - topLevelAS, + topLevelAS[bufferStart], gl_RayFlagsNoneEXT, 0xff, 0, 0, 0, @@ -43,5 +46,5 @@ void main() 0 ); - imageStore(image, ivec2(pixel), vec4(hitValue, 1.0)); + imageStore(image[0], ivec2(pixel), vec4(hitValue, 1)); } diff --git a/examples/VulkanTriangleRuntime/README.md b/examples/VulkanTriangleRuntime/README.md deleted file mode 100644 index 6da7987..0000000 --- a/examples/VulkanTriangleRuntime/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# HelloWindow Example - -## Description - -This example demonstrates how to load shaders and render a triangle. - -## Expected Result - -A blue tinted vulkan window with a white triangle in the center. - -## Highlighted Code Snippet - -```cpp -EventListener listener(&window.onDraw, [&descriptors, &meshShader](VkCommandBuffer cmd){ - vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipelineLayout, 0, 2, &descriptors.set[0], 0, NULL); - vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipeline); - Device::vkCmdDrawMeshTasksEXTProc(cmd, meshShader.threadCount, 1, 1); -}); -``` - -## How to Run - -```bash -crafter-build build executable -r -``` \ No newline at end of file diff --git a/examples/VulkanTriangleRuntime/closesthit.glsl b/examples/VulkanTriangleRuntime/closesthit.glsl deleted file mode 100644 index 9a511b6..0000000 --- a/examples/VulkanTriangleRuntime/closesthit.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#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/VulkanTriangleRuntime/main.cpp b/examples/VulkanTriangleRuntime/main.cpp deleted file mode 100644 index 242971a..0000000 --- a/examples/VulkanTriangleRuntime/main.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include "vulkan/vulkan.h" - -import Crafter.Graphics; -using namespace Crafter; -import std; -import Crafter.Event; -import Crafter.Math; - - -int main() { - Device::CreateDevice(); - WindowVulkan window(1280, 720, "HelloVulkan"); - VkCommandBuffer cmd = window.StartInit(); - - std::vector bindings { - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR, - }, - { - .binding = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR, - } - }; - DescriptorSetLayoutVulkan layout(std::move(bindings)); - - std::array layouts {{layout.layout}}; - - DescriptorPool pool; - pool.sets.resize(1); - pool.BuildPool(DescriptorPool::GetPoolSizes({layout}), layouts); - - std::array shaders{{ - {"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR}, - {"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR}, - {"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR} - }}; - - ShaderBindingTableVulkan shaderTable; - shaderTable.Init(shaders); - - std::array raygenGroups {{ - { - .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, - }, - }}; - std::array missGroups {{ - { - .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, - }, - }}; - std::array hitGroups {{ - { - .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, - }, - }}; - - PipelineRTVulkan pipeline; - pipeline.Init(cmd, layouts, raygenGroups, missGroups, hitGroups, shaderTable); - - Mesh triangleMesh; - std::array, 3> verts {{{-150, -150, 100}, {0, 150, 100}, {150, -150, 100}}}; - std::array index {{2,1,0}}; - triangleMesh.Build(verts, index, cmd); - RenderingElement3D renderer = { - .instance = { - .instanceCustomIndex = 0, - .mask = 0xFF, - .instanceShaderBindingTableRecordOffset = 0, - .flags = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR, - .accelerationStructureReference = triangleMesh.blasAddr - } - }; - MatrixRowMajor transform = MatrixRowMajor::Identity(); - std::memcpy(renderer.instance.transform.matrix, transform.m, sizeof(transform.m)); - RenderingElement3D::tlases.resize(1); - RenderingElement3D::elements.push_back(&renderer); - RenderingElement3D::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 = &RenderingElement3D::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(Device::device, 2, write, 0, nullptr); - - window.SetPipelineRT(pipeline); - window.descriptorsRt = pool.sets; - - window.FinishInit(); - window.Render(); - window.StartSync(); -} diff --git a/examples/VulkanTriangleRuntime/miss.glsl b/examples/VulkanTriangleRuntime/miss.glsl deleted file mode 100644 index 1478ecf..0000000 --- a/examples/VulkanTriangleRuntime/miss.glsl +++ /dev/null @@ -1,9 +0,0 @@ -#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/VulkanTriangleRuntime/project.json b/examples/VulkanTriangleRuntime/project.json deleted file mode 100644 index b30faa8..0000000 --- a/examples/VulkanTriangleRuntime/project.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "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/VulkanTriangleRuntime/raygen.glsl b/examples/VulkanTriangleRuntime/raygen.glsl deleted file mode 100644 index ad7b74c..0000000 --- a/examples/VulkanTriangleRuntime/raygen.glsl +++ /dev/null @@ -1,47 +0,0 @@ -#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/implementations/Crafter.Graphics-Device.cpp b/implementations/Crafter.Graphics-Device.cpp index c56bef0..50a06a2 100644 --- a/implementations/Crafter.Graphics-Device.cpp +++ b/implementations/Crafter.Graphics-Device.cpp @@ -65,10 +65,12 @@ const char* const deviceExtensionNames[] = { "VK_KHR_swapchain", "VK_KHR_spirv_1_4", "VK_KHR_shader_float_controls", - "VK_KHR_dynamic_rendering", "VK_KHR_acceleration_structure", - "VK_KHR_deferred_host_operations", "VK_KHR_ray_tracing_pipeline", + "VK_EXT_descriptor_heap", + "VK_KHR_deferred_host_operations", + "VK_KHR_maintenance5", + "VK_KHR_shader_untyped_pointers" }; const char* const layerNames[] = { "VK_LAYER_KHRONOS_validation" @@ -474,10 +476,21 @@ void Device::Initialize() { VkApplicationInfo app{VK_STRUCTURE_TYPE_APPLICATION_INFO}; app.pApplicationName = ""; app.pEngineName = "Crafter.Graphics"; - app.apiVersion = VK_MAKE_VERSION(1, 3, 0); + app.apiVersion = VK_MAKE_VERSION(1, 4, 0); + + VkValidationFeatureEnableEXT enables[] = { + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT + }; + + VkValidationFeaturesEXT validationFeatures = { + .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT, + .enabledValidationFeatureCount = 1, + .pEnabledValidationFeatures = enables + }; VkInstanceCreateInfo instanceCreateInfo = {}; instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instanceCreateInfo.pNext = &validationFeatures; instanceCreateInfo.pApplicationInfo = &app; instanceCreateInfo.enabledExtensionCount = sizeof(instanceExtensionNames) / sizeof(const char*); instanceCreateInfo.ppEnabledExtensionNames = instanceExtensionNames; @@ -560,7 +573,7 @@ void Device::Initialize() { } } - VkPhysicalDeviceProperties2 properties2{ + VkPhysicalDeviceProperties2 properties2 { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &rayTracingProperties }; @@ -590,8 +603,20 @@ void Device::Initialize() { queueCreateInfo.queueCount = 1; queueCreateInfo.pQueuePriorities = &priority; + VkPhysicalDeviceShaderUntypedPointersFeaturesKHR untypedPointersFeatures { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNTYPED_POINTERS_FEATURES_KHR, + .shaderUntypedPointers = VK_TRUE, + }; + + VkPhysicalDeviceDescriptorHeapFeaturesEXT desciptorHeapFeatures { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_FEATURES_EXT, + .pNext = &untypedPointersFeatures, + .descriptorHeap = VK_TRUE, + }; + VkPhysicalDevice16BitStorageFeatures bit16 { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, + .pNext = &desciptorHeapFeatures, .storageBuffer16BitAccess = VK_TRUE, }; @@ -614,21 +639,14 @@ void Device::Initialize() { .accelerationStructure = VK_TRUE }; - VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeature = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR}; - dynamicRenderingFeature.dynamicRendering = VK_FALSE; - dynamicRenderingFeature.pNext = &deviceAccelerationStructureFeature; - - VkPhysicalDeviceMeshShaderFeaturesEXT ext_feature = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT}; - ext_feature.meshShader = VK_FALSE; - ext_feature.pNext = &dynamicRenderingFeature; - VkPhysicalDeviceFeatures2 physical_features2 = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + .pNext = &deviceAccelerationStructureFeature, .features = { - .samplerAnisotropy = VK_TRUE + .samplerAnisotropy = VK_TRUE, + .shaderInt16 = VK_TRUE } }; - physical_features2.pNext = &ext_feature; VkDeviceCreateInfo deviceCreateInfo = {}; deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; @@ -681,6 +699,10 @@ void Device::Initialize() { vkCreateRayTracingPipelinesKHR = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkCreateRayTracingPipelinesKHR")); vkGetRayTracingShaderGroupHandlesKHR = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkGetRayTracingShaderGroupHandlesKHR")); vkCmdTraceRaysKHR = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkCmdTraceRaysKHR")); + vkCmdBindResourceHeapEXT = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkCmdBindResourceHeapEXT")); + vkCmdBindSamplerHeapEXT = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkCmdBindSamplerHeapEXT")); + vkWriteResourceDescriptorsEXT = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkWriteResourceDescriptorsEXT")); + vkGetPhysicalDeviceDescriptorSizeEXT = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDescriptorSizeEXT")); #endif } diff --git a/implementations/Crafter.Graphics-RenderingElement3D.cpp b/implementations/Crafter.Graphics-RenderingElement3D.cpp index c1c3a0f..ca6902f 100644 --- a/implementations/Crafter.Graphics-RenderingElement3D.cpp +++ b/implementations/Crafter.Graphics-RenderingElement3D.cpp @@ -114,6 +114,12 @@ void RenderingElement3D::BuildTLAS(VkCommandBuffer cmd, std::uint32_t index) { 0, nullptr, 0, nullptr ); + + VkAccelerationStructureDeviceAddressInfoKHR addrInfo { + .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, + .accelerationStructure = tlases[index].accelerationStructure + }; + tlases[index].address = Device::vkGetAccelerationStructureDeviceAddressKHR(Device::device, &addrInfo); } #endif \ No newline at end of file diff --git a/implementations/Crafter.Graphics-Window.cpp b/implementations/Crafter.Graphics-Window.cpp index 2786b25..103d220 100644 --- a/implementations/Crafter.Graphics-Window.cpp +++ b/implementations/Crafter.Graphics-Window.cpp @@ -62,6 +62,8 @@ import :MouseElement; import :Device; #ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN import :VulkanTransition; +import :DescriptorHeapVulkan; +import :PipelineRTVulkan; #endif import std; @@ -813,10 +815,31 @@ void Window::Render() { } #endif - vkCmdBindPipeline(drawCmdBuffers[currentBuffer], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rtPipeline); - vkCmdBindDescriptorSets(drawCmdBuffers[currentBuffer], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rtPipelineLayout, 0, static_cast(descriptorsRt.size()), descriptorsRt.data(), 0, nullptr); - Device::vkCmdTraceRaysKHR(drawCmdBuffers[currentBuffer], &raygenRegion, &missRegion, &hitRegion, &callableRegion, width, height, 1); + vkCmdBindPipeline(drawCmdBuffers[currentBuffer], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline->pipeline); + + VkBindHeapInfoEXT resourceHeapInfo = { + .sType = VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT, + .heapRange = { + .address = descriptorHeap->resourceHeap[currentBuffer].address, + .size = static_cast(descriptorHeap->resourceHeap[currentBuffer].descriptor.range) + }, + .reservedRangeOffset = (descriptorHeap->resourceHeap[currentBuffer].descriptor.range - Device::descriptorHeapProperties.minResourceHeapReservedRange) & ~(Device::descriptorHeapProperties.imageDescriptorAlignment - 1), + .reservedRangeSize = Device::descriptorHeapProperties.minResourceHeapReservedRange + }; + Device::vkCmdBindResourceHeapEXT(drawCmdBuffers[currentBuffer], &resourceHeapInfo); + VkBindHeapInfoEXT samplerHeapInfo = { + .sType = VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT, + .heapRange = { + .address = descriptorHeap->samplerHeap[currentBuffer].address, + .size = static_cast(descriptorHeap->samplerHeap[currentBuffer].descriptor.range) + }, + .reservedRangeOffset = descriptorHeap->samplerHeap[currentBuffer].descriptor.range - Device::descriptorHeapProperties.minSamplerHeapReservedRange, + .reservedRangeSize = Device::descriptorHeapProperties.minSamplerHeapReservedRange + }; + Device::vkCmdBindSamplerHeapEXT(drawCmdBuffers[currentBuffer], &samplerHeapInfo); + + Device::vkCmdTraceRaysKHR(drawCmdBuffers[currentBuffer], &pipeline->raygenRegion, &pipeline->missRegion, &pipeline->hitRegion, &pipeline->callableRegion, width, height, 1); VkImageMemoryBarrier image_memory_barrier2 { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, @@ -986,9 +1009,6 @@ void Window::CreateSwapchain() // If an existing swap chain is re-created, destroy the old swap chain and the ressources owned by the application (image views, images are owned by the swap chain) if (oldSwapchain != VK_NULL_HANDLE) { - for (auto i = 0; i < numFrames; i++) { - vkDestroyImageView(Device::device, imageViews[i], nullptr); - } vkDestroySwapchainKHR(Device::device, oldSwapchain, nullptr); } uint32_t imageCount{ 0 }; @@ -997,34 +1017,27 @@ void Window::CreateSwapchain() // Get the swap chain images Device::CheckVkResult(vkGetSwapchainImagesKHR(Device::device, swapChain, &imageCount, images)); - for (auto i = 0; i < numFrames; i++) - { - VkImageViewCreateInfo colorAttachmentView = {}; - colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - colorAttachmentView.pNext = NULL; - colorAttachmentView.format = colorFormat; - colorAttachmentView.components = { - VK_COMPONENT_SWIZZLE_R, - VK_COMPONENT_SWIZZLE_G, - VK_COMPONENT_SWIZZLE_B, - VK_COMPONENT_SWIZZLE_A - }; - colorAttachmentView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - colorAttachmentView.subresourceRange.baseMipLevel = 0; - colorAttachmentView.subresourceRange.levelCount = 1; - colorAttachmentView.subresourceRange.baseArrayLayer = 0; - colorAttachmentView.subresourceRange.layerCount = 1; - colorAttachmentView.viewType = VK_IMAGE_VIEW_TYPE_2D; - colorAttachmentView.flags = 0; - colorAttachmentView.image = images[i]; - Device::CheckVkResult(vkCreateImageView(Device::device, &colorAttachmentView, nullptr, &imageViews[i])); - - VkImageSubresourceRange range{}; - range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - range.baseMipLevel = 0; - range.levelCount = VK_REMAINING_MIP_LEVELS; - range.baseArrayLayer = 0; - range.layerCount = VK_REMAINING_ARRAY_LAYERS; + for (std::uint8_t i = 0; i < numFrames; i++) { + imageViews[i] = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .flags = 0, + .image = images[i], + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = colorFormat, + .components = { + VK_COMPONENT_SWIZZLE_R, + VK_COMPONENT_SWIZZLE_G, + VK_COMPONENT_SWIZZLE_B, + VK_COMPONENT_SWIZZLE_A + }, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + }; } } diff --git a/interfaces/Crafter.Graphics-DescriptorHeapVulkan.cppm b/interfaces/Crafter.Graphics-DescriptorHeapVulkan.cppm new file mode 100644 index 0000000..659f18c --- /dev/null +++ b/interfaces/Crafter.Graphics-DescriptorHeapVulkan.cppm @@ -0,0 +1,57 @@ +/* +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_RENDERER_VULKAN +#include "vulkan/vulkan.h" +#endif +export module Crafter.Graphics:DescriptorHeapVulkan; +#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN +import std; +import :Device; +import :Window; +import :Types; +import :VulkanBuffer; + +export namespace Crafter { + struct DescriptorHeapVulkan { + inline static VulkanBuffer resourceHeap[Window::numFrames]; + inline static VulkanBuffer samplerHeap[Window::numFrames]; + inline static std::uint32_t bufferStartOffset; + inline static std::uint16_t bufferStartElement; + void Initialize(std::uint16_t images, std::uint16_t buffers, std::uint16_t samplers) { + std::uint32_t descriptorRegion = images * Device::descriptorHeapProperties.imageDescriptorSize + buffers * Device::descriptorHeapProperties.bufferDescriptorSize; + std::uint32_t alignedDescriptorRegion = (descriptorRegion + Device::descriptorHeapProperties.imageDescriptorAlignment - 1) & ~(Device::descriptorHeapProperties.imageDescriptorAlignment - 1); + std::uint32_t resourceSize = alignedDescriptorRegion + Device::descriptorHeapProperties.minResourceHeapReservedRange; + std::uint32_t samplerSize = samplers * Device::descriptorHeapProperties.samplerDescriptorSize + Device::descriptorHeapProperties.minSamplerHeapReservedRange; + bufferStartElement = images * Device::descriptorHeapProperties.imageDescriptorSize / Device::descriptorHeapProperties.bufferDescriptorSize; + + if(images > 0 && bufferStartElement == 0) { + bufferStartElement = 1; + } + bufferStartOffset = bufferStartElement * Device::descriptorHeapProperties.bufferDescriptorSize; + for(std::uint8_t i = 0; i < Window::numFrames; i++) { + resourceHeap[i].Create(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_DESCRIPTOR_HEAP_BIT_EXT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, resourceSize); + samplerHeap[i].Create(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_DESCRIPTOR_HEAP_BIT_EXT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, samplerSize); + } + } + }; +} + +#endif \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-DescriptorPoolVulkan.cppm b/interfaces/Crafter.Graphics-DescriptorPoolVulkan.cppm deleted file mode 100644 index 4ed941d..0000000 --- a/interfaces/Crafter.Graphics-DescriptorPoolVulkan.cppm +++ /dev/null @@ -1,187 +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_RENDERER_VULKAN -#include "vulkan/vulkan.h" -#endif -export module Crafter.Graphics:DescriptorPoolVulkan; -#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN -import std; -import :Device; -import :Types; -import :DescriptorSetLayoutVulkan; -import Crafter.Event; - -export namespace Crafter { - struct DescriptorEntry { - VkDescriptorType type; - bool occured = true; - }; - - class DescriptorPool { - public: - std::vector sets; - VkDescriptorPool descriptorPool = VK_NULL_HANDLE; - - template - consteval static void GetOccuringDescriptors(std::array& types) { - for (const VkDescriptorSetLayoutBinding& binding : Shader::descriptors) { - for (DescriptorEntry& type : types) { - if (type.type == binding.descriptorType) { - 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 VkDescriptorSetLayoutBinding& binding : Shaders::descriptors) { - bool found = false; - for(VkDescriptorPoolSize& type : types) { - if(type.type == binding.descriptorType && type.descriptorCount != 12345) { - type.descriptorCount += binding.descriptorCount; - found = true; - } - } - if(!found) { - for(std::uint32_t i = 0; i < GetUniqueDiscriptorCount(); i++){ - if(types[i].descriptorCount == 12345) { - types[i].type = binding.descriptorType; - types[i].descriptorCount = binding.descriptorCount; - break; - } - } - } - } - }(), - ...); - - return types; - } - - constexpr static std::vector GetPoolSizes(const std::span shaders) { - std::vector types; - - for(const DescriptorSetLayoutVulkan& shader : shaders) { - for (const VkDescriptorSetLayoutBinding& binding : shader.descriptors) { - for(VkDescriptorPoolSize& type : types) { - if(type.type == binding.descriptorType) { - type.descriptorCount += binding.descriptorCount; - goto inner; - } - } - types.emplace_back(binding.descriptorType, binding.descriptorCount); - inner:; - } - } - - return types; - } - - template - constexpr static std::vector GetPoolSizesCombined(const std::span shaders) { - std::vector types; - - for(const DescriptorSetLayoutVulkan& shader : shaders) { - for (const VkDescriptorSetLayoutBinding& binding : shader.descriptors) { - for(VkDescriptorPoolSize& type : types) { - if(type.type == binding.descriptorType) { - type.descriptorCount += binding.descriptorCount; - goto inner; - } - } - types.emplace_back(binding.descriptorType, binding.descriptorCount); - inner:; - } - } - - ([&] { - for (const VkDescriptorSetLayoutBinding& binding : Shaders::descriptors) { - for(VkDescriptorPoolSize& type : types) { - if(type.type == binding.descriptorType) { - type.descriptorCount += binding.descriptorCount; - goto inner2; - } - } - types.emplace_back(binding.descriptorType, binding.descriptorCount); - inner2:; - } - }(), - ...); - - return types; - } - - public: - ~DescriptorPool() { - vkDestroyDescriptorPool(Device::device, descriptorPool, nullptr); - } - void BuildPool(std::span poolSizes, std::span setLayouts) { - if(descriptorPool != VK_NULL_HANDLE) { - vkDestroyDescriptorPool(Device::device, descriptorPool, nullptr); - } - - sets.resize(setLayouts.size()); - - VkDescriptorPoolCreateInfo descriptorPoolInfo { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .maxSets = static_cast(sets.size()), - .poolSizeCount = static_cast(poolSizes.size()), - .pPoolSizes = poolSizes.data() - }; - - Device::CheckVkResult(vkCreateDescriptorPool(Device::device, &descriptorPoolInfo, nullptr, &descriptorPool)); - - VkDescriptorSetAllocateInfo allocInfo { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = descriptorPool, - .descriptorSetCount = static_cast(sets.size()), - .pSetLayouts = setLayouts.data(), - }; - - Device::CheckVkResult(vkAllocateDescriptorSets(Device::device, &allocInfo, sets.data())); - } - }; -} - -#endif \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-DescriptorSetLayoutVulkan.cppm b/interfaces/Crafter.Graphics-DescriptorSetLayoutVulkan.cppm deleted file mode 100644 index c499eff..0000000 --- a/interfaces/Crafter.Graphics-DescriptorSetLayoutVulkan.cppm +++ /dev/null @@ -1,62 +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_RENDERER_VULKAN -#include "vulkan/vulkan.h" -#endif -export module Crafter.Graphics:DescriptorSetLayoutVulkan; -#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN -import std; -import :Device; -import :Types; -import Crafter.Event; - -export namespace Crafter { - class DescriptorSetLayoutVulkan { - public: - VkDescriptorSetLayout layout; - std::vector descriptors; - DescriptorSetLayoutVulkan(std::vector&& layouts) : descriptors(std::move(layouts)) { - VkDescriptorSetLayoutCreateInfo descriptorLayoutInfoMesh = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = static_cast(descriptors.size()), - .pBindings = descriptors.data() - }; - Device::CheckVkResult(vkCreateDescriptorSetLayout(Device::device, &descriptorLayoutInfoMesh, nullptr, &layout)); - } - }; - - template Descriptors> - class DescriptorSetLayoutVulkanConst { - public: - inline static VkDescriptorSetLayout layout; - constexpr static std::span descriptors = Descriptors; - static void Init() { - VkDescriptorSetLayoutCreateInfo descriptorLayoutInfoMesh = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = DescriptorCount, - .pBindings = Descriptors.data() - }; - Device::CheckVkResult(vkCreateDescriptorSetLayout(Device::device, &descriptorLayoutInfoMesh, nullptr, &layout)); - } - }; -} - -#endif \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-Device.cppm b/interfaces/Crafter.Graphics-Device.cppm index 0c5dd50..819a43e 100644 --- a/interfaces/Crafter.Graphics-Device.cppm +++ b/interfaces/Crafter.Graphics-Device.cppm @@ -114,9 +114,19 @@ export namespace Crafter { inline static PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR; inline static PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR; inline static PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR; + inline static PFN_vkCmdBindResourceHeapEXT vkCmdBindResourceHeapEXT; + inline static PFN_vkCmdBindSamplerHeapEXT vkCmdBindSamplerHeapEXT; + inline static PFN_vkWriteResourceDescriptorsEXT vkWriteResourceDescriptorsEXT; + inline static PFN_vkGetPhysicalDeviceDescriptorSizeEXT vkGetPhysicalDeviceDescriptorSizeEXT; + inline static VkPhysicalDeviceMemoryProperties memoryProperties; + + inline static VkPhysicalDeviceDescriptorHeapPropertiesEXT descriptorHeapProperties = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_PROPERTIES_EXT + }; inline static VkPhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingProperties = { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR, + .pNext = &descriptorHeapProperties }; static void CheckVkResult(VkResult result); diff --git a/interfaces/Crafter.Graphics-ImageVulkan.cppm b/interfaces/Crafter.Graphics-ImageVulkan.cppm index 2b95d24..a8f2672 100644 --- a/interfaces/Crafter.Graphics-ImageVulkan.cppm +++ b/interfaces/Crafter.Graphics-ImageVulkan.cppm @@ -37,7 +37,7 @@ export namespace Crafter { std::uint8_t mipLevels; VkImage image; VkDeviceMemory imageMemory; - VulkanBuffer buffer; + VulkanBuffer buffer; VkImageView imageView; VkDescriptorImageInfo descriptor; diff --git a/interfaces/Crafter.Graphics-Mesh.cppm b/interfaces/Crafter.Graphics-Mesh.cppm index 76720b2..54ab6be 100644 --- a/interfaces/Crafter.Graphics-Mesh.cppm +++ b/interfaces/Crafter.Graphics-Mesh.cppm @@ -32,10 +32,10 @@ export namespace Crafter { #ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN class Mesh { public: - VulkanBuffer scratchBuffer; - VulkanBuffer blasBuffer; - VulkanBuffer, true, true, false> vertexBuffer; - VulkanBuffer indexBuffer; + VulkanBuffer scratchBuffer; + VulkanBuffer blasBuffer; + VulkanBuffer, true, true> vertexBuffer; + VulkanBuffer indexBuffer; VkAccelerationStructureGeometryTrianglesDataKHR blasData; VkAccelerationStructureGeometryKHR blas; VkAccelerationStructureKHR accelerationStructure; diff --git a/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm b/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm index 2b312a8..755768c 100644 --- a/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm +++ b/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm @@ -30,26 +30,16 @@ import :ShaderBindingTableVulkan; import :Types; export namespace Crafter { - class PipelineRTVulkan { - public: + struct PipelineRTVulkan { VkPipeline pipeline; - VkPipelineLayout pipelineLayout; std::vector shaderHandles; - VulkanBuffer sbtBuffer; + VulkanBuffer sbtBuffer; VkStridedDeviceAddressRegionKHR raygenRegion; VkStridedDeviceAddressRegionKHR missRegion; VkStridedDeviceAddressRegionKHR hitRegion; VkStridedDeviceAddressRegionKHR callableRegion; - void Init(VkCommandBuffer cmd, std::span setLayouts, std::span raygenGroups, std::span missGroups, std::span hitGroups, ShaderBindingTableVulkan& shaderTable) { - VkPipelineLayoutCreateInfo pipelineLayoutInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = static_cast(setLayouts.size()), - .pSetLayouts = setLayouts.data() - }; - - Device::CheckVkResult(vkCreatePipelineLayout(Device::device, &pipelineLayoutInfo, nullptr, &pipelineLayout)); - + void Init(VkCommandBuffer cmd, std::span raygenGroups, std::span missGroups, std::span hitGroups, ShaderBindingTableVulkan& shaderTable) { std::vector groups; groups.reserve(raygenGroups.size() + missGroups.size() + hitGroups.size()); @@ -57,14 +47,21 @@ export namespace Crafter { groups.insert(groups.end(), missGroups.begin(), missGroups.end()); groups.insert(groups.end(), hitGroups.begin(), hitGroups.end()); - VkRayTracingPipelineCreateInfoKHR rtPipelineInfo{ + VkPipelineCreateFlags2CreateInfo flags2 = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO, + .flags = VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT + }; + + VkRayTracingPipelineCreateInfoKHR rtPipelineInfo { .sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR, + .pNext = &flags2, + .flags = 0, .stageCount = static_cast(shaderTable.shaderStages.size()), .pStages = shaderTable.shaderStages.data(), .groupCount = static_cast(groups.size()), .pGroups = groups.data(), .maxPipelineRayRecursionDepth = 1, - .layout = pipelineLayout + .layout = VK_NULL_HANDLE }; Device::CheckVkResult(Device::vkCreateRayTracingPipelinesKHR(Device::device, {}, {}, 1, &rtPipelineInfo, nullptr, &pipeline)); @@ -114,189 +111,6 @@ export namespace Crafter { callableRegion.size = 0; } }; - - 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 PipelineRTVulkanConst { - public: - inline static VkPipeline pipeline; - inline static VkPipelineLayout pipelineLayout; - inline static std::vector shaderHandles; - inline static VulkanBuffer sbtBuffer; - inline static VkStridedDeviceAddressRegionKHR raygenRegion; - inline static VkStridedDeviceAddressRegionKHR missRegion; - inline static VkStridedDeviceAddressRegionKHR hitRegion; - inline static VkStridedDeviceAddressRegionKHR callableRegion; - - static void Init(VkCommandBuffer cmd, const std::span setLayouts) { - VkPipelineLayoutCreateInfo pipelineLayoutInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = static_cast(setLayouts.size()), - .pSetLayouts = setLayouts.data() - }; - - Device::CheckVkResult(vkCreatePipelineLayout(Device::device, &pipelineLayoutInfo, nullptr, &pipelineLayout)); - - constexpr auto groupIndexSeq = std::make_index_sequence>{}; - - constexpr std::array> groups = GetShaderGroups(groupIndexSeq); - - VkRayTracingPipelineCreateInfoKHR rtPipelineInfo{ - .sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR, - .stageCount = static_cast(ShaderBindingTableVulkanConst::shaderStages.size()), - .pStages = ShaderBindingTableVulkanConst::shaderStages.data(), - .groupCount = static_cast(groups.size()), - .pGroups = groups.data(), - .maxPipelineRayRecursionDepth = 1, - .layout = pipelineLayout - }; - - Device::CheckVkResult(Device::vkCreateRayTracingPipelinesKHR(Device::device, {}, {}, 1, &rtPipelineInfo, nullptr, &pipeline)); - - std::size_t dataSize = Device::rayTracingProperties.shaderGroupHandleSize * rtPipelineInfo.groupCount; - shaderHandles.resize(dataSize); - Device::CheckVkResult(Device::vkGetRayTracingShaderGroupHandlesKHR(Device::device, pipeline, 0, rtPipelineInfo.groupCount, dataSize, shaderHandles.data())); - - std::uint32_t sbtStride = AlignUp(Device::rayTracingProperties.shaderGroupHandleSize, Device::rayTracingProperties.shaderGroupHandleAlignment); - - raygenRegion.stride = sbtStride; - raygenRegion.deviceAddress = 0; - raygenRegion.size = GetGroupCount(groupIndexSeq) * sbtStride; - - missRegion.stride = sbtStride; - missRegion.deviceAddress = AlignUp(raygenRegion.size, Device::rayTracingProperties.shaderGroupBaseAlignment); - missRegion.size = GetGroupCount(groupIndexSeq) * sbtStride; - - hitRegion.stride = sbtStride; - hitRegion.deviceAddress = AlignUp(missRegion.deviceAddress + missRegion.size, Device::rayTracingProperties.shaderGroupBaseAlignment); - hitRegion.size = (GetGroupCount(groupIndexSeq) * sbtStride) + (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); - - AddShaderGroupsToBuffer(sbtStride, groupIndexSeq); - sbtBuffer.FlushDevice(cmd, VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); - - 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 || groupTemplate::anyHitShader != 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 if constexpr(groupTemplate::anyHitShader != 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 * Device::rayTracingProperties.shaderGroupHandleSize, Device::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 * Device::rayTracingProperties.shaderGroupHandleSize, Device::rayTracingProperties.shaderGroupHandleSize); - offset += sbtStride; - } - } else if constexpr(groupTemplate::anyHitShader != VK_SHADER_UNUSED_KHR) { - using shaderTemplate = std::tuple_element_t; - if constexpr(shaderTemplate::_stage == stage) { - std::memcpy(sbtBuffer.value + offset, shaderHandles.data() + index * Device::rayTracingProperties.shaderGroupHandleSize, Device::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, Device::rayTracingProperties.shaderGroupBaseAlignment); - (AddShaderGroupToBuffer(sbtStride, offset), ...); - offset = AlignUp(offset, Device::rayTracingProperties.shaderGroupBaseAlignment); - (AddShaderGroupToBuffer(sbtStride, offset), ...); - (AddShaderGroupToBuffer(sbtStride, offset), ...); - } - }; } #endif \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-RenderingElement2D.cppm b/interfaces/Crafter.Graphics-RenderingElement2D.cppm index c54d906..22c04f0 100644 --- a/interfaces/Crafter.Graphics-RenderingElement2D.cppm +++ b/interfaces/Crafter.Graphics-RenderingElement2D.cppm @@ -383,29 +383,7 @@ export namespace Crafter { } break; } - case OpaqueType::SemiOpaque: { - for (int j = 0; j < h; j++) { - for (int i = 0; i < w; i++) { - int bufferX = x + i + c_x1 + offsetX; - int bufferY = currentY + j + c_y1 + offsetY; - - // Only draw pixels that are within our scaled buffer bounds - if constexpr(Scaling) { - if (bufferX >= 0 && bufferX < ScalingBase::bufferWidth && bufferY >= 0 && bufferY < ScalingBase::bufferHeight) { - ScalingBase::scalingBuffer[bufferY * ScalingBase::bufferWidth + bufferX] = {color.r, color.g, color.b, static_cast(bitmap[j * w + i])}; - } - } else { - if (bufferX >= 0 && bufferX < (int)this->scaled.size.x && bufferY >= 0 && bufferY < (int)this->scaled.size.y) { - std::uint8_t alpha = bitmap[j * w + i]; - if(alpha != 0) { - this->buffer[bufferY * this->scaled.size.x + bufferX] = {color.r, color.g, color.b, static_cast(bitmap[j * w + i])}; - } - } - } - } - } - break; - } + case OpaqueType::SemiOpaque: case OpaqueType::Transparent: { for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { diff --git a/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm b/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm new file mode 100644 index 0000000..c88c982 --- /dev/null +++ b/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm @@ -0,0 +1,75 @@ +/* +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; +#include "../lib/stb_truetype.h" +export module Crafter.Graphics:RenderingElement2DVulkan; +import Crafter.Asset; +import std; +import :Transform2D; +import :Types; +import :Window; + +export namespace Crafter { + struct __attribute__((packed)) RenderingElement2DVulkanTransformInfo { + ScaleData2D scaled; // 0 - 8 bytes + std::uint16_t bufferX; // 8 - 2 bytes + std::uint16_t bufferY; // 10 - 2 bytes + //12 bytes total; + } + + + template + struct RenderingElement2DVulkan { + std::uint16_t index; + std:array*, Window::NumFrames> buffers; + RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferWidth, std::uint16_t bufferHeight) requires(Owning) : index(renderingElement2DVulkans.size()-1) { + renderingElement2DVulkans.push_back(this); + } + RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferWidth, std::uint16_t bufferHeight, std:array*, Window::NumFrames> buffers) requires(!Owning) : buffers(buffers) { + renderingElement2DVulkans.push_back(this); + } + + ~RenderingElement2DVulkan() { + if constexpr(Owning) { + for(VulkanBuffer<_Float16, Mapped, false>* buffer : buffers) { + delete buffer; + } + } + } + + RenderingElement2DVulkan(RenderingElement2DVulkan&) = delete; + RenderingElement2DVulkan& operator=(RenderingElement2DVulkan&) = delete; + + void UpdatePosition(RendertargetBase& window, Transform2D& parent) override { + ScaleData2D oldScale = this->scaled; + this->ScaleElement(parent); + if(oldScale.size.x != this->scaled.size.x || oldScale.size.y != this->scaled.size.y) { + this->buffer.resize(this->scaled.size.x * this->scaled.size.y); + } + for(Transform2D* child : this->children) { + child->UpdatePosition(window, *this); + } + } + }; + + inline static std::vector renderingElement2DVulkans; + inline static std::vector renderingElement2DVulkanDescriptors[Window::NumFrames]; + inline static VulkanBuffer* renderingElement2DVulkanTransformBuffer[Window::NumFrames]; +} \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-RenderingElement3D.cppm b/interfaces/Crafter.Graphics-RenderingElement3D.cppm index 2931cc4..d753c7a 100644 --- a/interfaces/Crafter.Graphics-RenderingElement3D.cppm +++ b/interfaces/Crafter.Graphics-RenderingElement3D.cppm @@ -27,20 +27,22 @@ import std; import :Mesh; import :VulkanBuffer; import Crafter.Math; +import :Window; export namespace Crafter { struct TlasWithBuffer { - VulkanBuffer buffer; + VkDeviceAddress address; + VulkanBuffer buffer; VkAccelerationStructureKHR accelerationStructure; - VulkanBuffer instanceBuffer; + VulkanBuffer instanceBuffer; }; class RenderingElement3D { public: VkAccelerationStructureInstanceKHR instance; static std::vector elements; - inline static VulkanBuffer scratchBuffer; - inline static std::vector tlases; + inline static VulkanBuffer scratchBuffer; + inline static TlasWithBuffer tlases[Window::numFrames]; static void BuildTLAS(VkCommandBuffer cmd, std::uint32_t index); }; } diff --git a/interfaces/Crafter.Graphics-ShaderBindingTableVulkan.cppm b/interfaces/Crafter.Graphics-ShaderBindingTableVulkan.cppm index 54b9720..4979411 100644 --- a/interfaces/Crafter.Graphics-ShaderBindingTableVulkan.cppm +++ b/interfaces/Crafter.Graphics-ShaderBindingTableVulkan.cppm @@ -36,33 +36,10 @@ export namespace Crafter { void Init(std::span shaders) { shaderStages.reserve(shaders.size()); for(const VulkanShader& shader: shaders) { - shaderStages.emplace_back(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, shader.stage, shader.shader, shader.entrypoint.c_str(), nullptr); + shaderStages.emplace_back(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, shader.stage, shader.shader, shader.entrypoint.c_str(), shader.specilizationInfo); } } }; - - template - class ShaderBindingTableVulkanConst { - 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-ShaderVulkan.cppm b/interfaces/Crafter.Graphics-ShaderVulkan.cppm index a571ded..8f71926 100644 --- a/interfaces/Crafter.Graphics-ShaderVulkan.cppm +++ b/interfaces/Crafter.Graphics-ShaderVulkan.cppm @@ -28,21 +28,14 @@ import :Device; import :Types; export namespace Crafter { - template - struct StringLiteral { - constexpr StringLiteral(const char (&str)[N]) { - std::copy_n(str, N, value); - } - - char value[N]; - }; - class VulkanShader { public: + std::vector specilizations; + VkSpecializationInfo* specilizationInfo; VkShaderStageFlagBits stage; std::string entrypoint; VkShaderModule shader; - VulkanShader(const std::filesystem::path& path, std::string entrypoint, VkShaderStageFlagBits stage) : stage(stage), entrypoint(entrypoint) { + VulkanShader(const std::filesystem::path& path, std::string entrypoint, VkShaderStageFlagBits stage, VkSpecializationInfo* specilizationInfo) : stage(stage), entrypoint(entrypoint), specilizationInfo(specilizationInfo) { std::ifstream file(path, std::ios::binary); if (!file) { std::cerr << "Error: Could not open file " << path << std::endl; @@ -69,44 +62,6 @@ export namespace Crafter { Device::CheckVkResult(vkCreateShaderModule(Device::device, &module_info, nullptr, &shader)); } }; - - template < - StringLiteral path, - StringLiteral entrypoint, - VkShaderStageFlagBits stage - > - class VulkanShaderConst { - public: - constexpr static VkShaderStageFlagBits _stage = stage; - constexpr static StringLiteral _entrypoint = entrypoint; - inline static VkShaderModule shader; - static void CreateShader() { - std::ifstream file(path.value, std::ios::binary); - if (!file) { - std::cerr << "Error: Could not open file " << path.value << std::endl; - } - - // Move to the end of the file to determine its size - file.seekg(0, std::ios::end); - std::streamsize size = file.tellg(); - file.seekg(0, std::ios::beg); - - std::vector spirv(size / sizeof(std::uint32_t)); - - // Read the data into the vector - if (!file.read(reinterpret_cast(spirv.data()), size)) { - std::cerr << "Error: Could not read data from file" << std::endl; - } - - file.close(); - - VkShaderModuleCreateInfo module_info{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO}; - module_info.codeSize = spirv.size() * sizeof(uint32_t); - module_info.pCode = spirv.data(); - - Device::CheckVkResult(vkCreateShaderModule(Device::device, &module_info, nullptr, &shader)); - } - }; } #endif \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-Types.cppm b/interfaces/Crafter.Graphics-Types.cppm index a8d3cf7..4f8afe3 100644 --- a/interfaces/Crafter.Graphics-Types.cppm +++ b/interfaces/Crafter.Graphics-Types.cppm @@ -33,8 +33,8 @@ export namespace Crafter { }; struct ScaleData2D { - Vector position; - Vector size; + Vector position; + Vector size; }; struct ClipRect { diff --git a/interfaces/Crafter.Graphics-VulkanBuffer.cppm b/interfaces/Crafter.Graphics-VulkanBuffer.cppm index fdaef60..002902f 100644 --- a/interfaces/Crafter.Graphics-VulkanBuffer.cppm +++ b/interfaces/Crafter.Graphics-VulkanBuffer.cppm @@ -64,32 +64,15 @@ namespace Crafter { >; - export template requires ((Mapped && !Staged) || (!Mapped && Staged) || (!Mapped && !Staged)) + export template class VulkanBuffer; - export template - class VulkanBufferStaged { - VulkanBuffer* stagingBuffer; - }; - export class VulkanBufferStagedEmpty {}; - template - using VulkanBufferStagedConditional = - std::conditional_t< - Staged, - VulkanBufferStaged, - VulkanBufferStagedEmpty - >; - - export template requires ((Mapped && !Staged) || (!Mapped && Staged) || (!Mapped && !Staged)) - class VulkanBuffer : public VulkanBufferBase, public VulkanBufferMappedConditional, public VulkanBufferAdressableConditional, public VulkanBufferStagedConditional { + export template + class VulkanBuffer : public VulkanBufferBase, public VulkanBufferMappedConditional, public VulkanBufferAdressableConditional { public: VulkanBuffer() = default; void Create(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, std::uint32_t count) { - if constexpr(Staged) { - new (&VulkanBufferMappedConditional::stagingBuffer) VulkanBuffer(); - VulkanBufferMappedConditional::stagingBuffer->Create(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, count); - } VkBufferCreateInfo bufferCreateInfo {}; bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; @@ -117,7 +100,7 @@ namespace Crafter { descriptor.offset = 0; descriptor.buffer = buffer; - descriptor.range = VK_WHOLE_SIZE; + descriptor.range = sizeof(T)*count; Device::CheckVkResult(vkBindBufferMemory(Device::device, buffer, memory, 0)); @@ -141,9 +124,6 @@ namespace Crafter { vkDestroyBuffer(Device::device, buffer, nullptr); vkFreeMemory(Device::device, memory, nullptr); buffer = VK_NULL_HANDLE; - if constexpr(Staged) { - delete VulkanBufferMappedConditional::stagingBuffer; - } } void Resize(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, std::uint32_t count) { @@ -237,22 +217,6 @@ namespace Crafter { }; vkInvalidateMappedMemoryRanges(Device::device, 1, &range); } - - void FlushDevice(VkCommandBuffer cmd) requires(Staged) { - VulkanBufferStagedConditional::stagingBuffer.FlushDevice(VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - VulkanBufferStagedConditional::stagingBuffer.Copy(cmd, this); - } - - void FlushDevice(VkCommandBuffer cmd, VkAccessFlags dstAccessMask, VkPipelineStageFlags dstStageMask) requires(Staged) { - VulkanBufferStagedConditional::stagingBuffer.FlushDevice(VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - VulkanBufferStagedConditional::stagingBuffer.Copy(cmd, this, VK_ACCESS_TRANSFER_WRITE_BIT, dstAccessMask, VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageMask); - } - - void FlushHost(VkCommandBuffer cmd) requires(Staged) { - Copy(cmd, VulkanBufferStagedConditional::stagingBuffer); - VulkanBufferStagedConditional::stagingBuffer.FlushHost(); - } - VulkanBuffer(VulkanBuffer&& other) { descriptor = other.descriptor; @@ -265,9 +229,6 @@ namespace Crafter { if constexpr(Mapped) { VulkanBufferMappedConditional::value = other.VulkanBufferMappedConditional::value; } - if constexpr(Staged) { - VulkanBufferStagedConditional::stagingBuffer = other.VulkanBufferStagedConditional::stagingBuffer; - } }; ~VulkanBuffer() { diff --git a/interfaces/Crafter.Graphics-Window.cppm b/interfaces/Crafter.Graphics-Window.cppm index e1ba38e..0bcb47a 100644 --- a/interfaces/Crafter.Graphics-Window.cppm +++ b/interfaces/Crafter.Graphics-Window.cppm @@ -51,9 +51,6 @@ import :Types; import :Rendertarget; import :Transform2D; import Crafter.Event; -#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN -import :PipelineRTVulkan; -#endif export namespace Crafter { #ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN @@ -63,6 +60,8 @@ export namespace Crafter { // Command buffer submission and execution VkSemaphore renderComplete; }; + struct PipelineRTVulkan; + struct DescriptorHeapVulkan; #endif struct MouseElement; @@ -178,17 +177,6 @@ export namespace Crafter { #endif #ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN - std::vector descriptorsRt; - template - void SetPipelineRT() { - rtPipeline = Pipeline::pipeline; - rtPipelineLayout = Pipeline::pipelineLayout; - raygenRegion = Pipeline::raygenRegion; - missRegion = Pipeline::missRegion; - hitRegion = Pipeline::hitRegion; - callableRegion = Pipeline::callableRegion; - } - void SetPipelineRT(PipelineRTVulkan& pipeline); VkCommandBuffer StartInit(); void FinishInit(); VkCommandBuffer GetCmd(); @@ -200,19 +188,15 @@ export namespace Crafter { VkFormat colorFormat; VkColorSpaceKHR colorSpace; VkImage images[numFrames]; - VkImageView imageViews[numFrames]; + VkImageViewCreateInfo imageViews[numFrames]; std::thread thread; VkCommandBuffer drawCmdBuffers[numFrames]; VkSubmitInfo submitInfo; Semaphores semaphores; std::uint32_t currentBuffer = 0; VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - VkPipeline rtPipeline; - VkPipelineLayout rtPipelineLayout; - VkStridedDeviceAddressRegionKHR raygenRegion; - VkStridedDeviceAddressRegionKHR missRegion; - VkStridedDeviceAddressRegionKHR hitRegion; - VkStridedDeviceAddressRegionKHR callableRegion; + PipelineRTVulkan* pipeline; + DescriptorHeapVulkan* descriptorHeap; #endif }; } \ No newline at end of file diff --git a/interfaces/Crafter.Graphics.cppm b/interfaces/Crafter.Graphics.cppm index 6e1d964..d06c440 100644 --- a/interfaces/Crafter.Graphics.cppm +++ b/interfaces/Crafter.Graphics.cppm @@ -38,14 +38,13 @@ export import :ForwardDeclarations; export import :Device; export import :VulkanTransition; export import :VulkanBuffer; -export import :DescriptorPoolVulkan; export import :ShaderVulkan; export import :ShaderBindingTableVulkan; export import :PipelineRTVulkan; export import :RenderingElement3D; export import :ImageVulkan; export import :SamplerVulkan; -export import :DescriptorSetLayoutVulkan; +export import :DescriptorHeapVulkan; #endif // export import :WindowWaylandVulkan; diff --git a/project.json b/project.json index 19f463b..89385d7 100644 --- a/project.json +++ b/project.json @@ -28,13 +28,12 @@ "interfaces/Crafter.Graphics-Mesh", "interfaces/Crafter.Graphics-VulkanBuffer", "interfaces/Crafter.Graphics-RenderingElement3D", - "interfaces/Crafter.Graphics-DescriptorPoolVulkan", "interfaces/Crafter.Graphics-ShaderVulkan", "interfaces/Crafter.Graphics-PipelineRTVulkan", "interfaces/Crafter.Graphics-ShaderBindingTableVulkan", "interfaces/Crafter.Graphics-ImageVulkan", "interfaces/Crafter.Graphics-SamplerVulkan", - "interfaces/Crafter.Graphics-DescriptorSetLayoutVulkan", + "interfaces/Crafter.Graphics-DescriptorHeapVulkan", "interfaces/Crafter.Graphics-Rendertarget", "interfaces/Crafter.Graphics-ForwardDeclarations" ],