descriptor heap rewrite

This commit is contained in:
Jorijn van der Graaf 2026-04-05 22:53:59 +02:00
commit f8e142fb06
31 changed files with 429 additions and 1017 deletions

Binary file not shown.

Binary file not shown.

View file

@ -1,4 +1,5 @@
#include "vulkan/vulkan.h"
#include <cassert>
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<Raygenspv, Misspv, Closesthitspv> 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<VK_SHADER_UNUSED_KHR, 2, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>
> ShaderGroups;
typedef PipelineRTVulkanConst<AllShaders, ShaderGroups> 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<AllShaders>::Init();
VkSpecializationMapEntry entry = {
.constantID = 0,
.offset = 0,
.size = sizeof(uint16_t)
};
descriptorSetLayout::Init();
std::array<VkDescriptorSetLayout, 1> 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<descriptorSetLayout>(), layouts);
std::array<VulkanShader, 3> 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<VkRayTracingShaderGroupCreateInfoKHR, 1> 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<VkRayTracingShaderGroupCreateInfoKHR, 1> 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<VkRayTracingShaderGroupCreateInfoKHR, 1> 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<Vector<float, 3, 3>, 3> verts {{{-150, -150, 100}, {0, 150, 100}, {150, -150, 100}}};
@ -75,59 +90,111 @@ int main() {
MatrixRowMajor<float, 4, 3, 1> transform = MatrixRowMajor<float, 4, 3, 1>::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<std::uint32_t, true, false, false> 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<Pipeline>();
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();
}

View file

@ -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",

View file

@ -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));
}