Files
2025-01-29 10:55:49 +01:00

770 lines
41 KiB
C

#include "vulkan.h"
#include "raytrace.h"
#ifndef KORE_ANDROID
#include <kinc/graphics5/commandlist.h>
#include <kinc/graphics5/constantbuffer.h>
#include <kinc/graphics5/graphics.h>
#include <kinc/graphics5/indexbuffer.h>
#include <kinc/graphics5/pipeline.h>
#include <kinc/graphics5/raytrace.h>
#include <kinc/graphics5/vertexbuffer.h>
extern VkRenderPassBeginInfo currentRenderPassBeginInfo;
extern VkFramebuffer *framebuffers;
extern uint32_t current_buffer;
bool memory_type_from_properties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex);
static const int INDEX_RAYGEN = 0;
static const int INDEX_MISS = 1;
static const int INDEX_CLOSEST_HIT = 2;
static const char *raygen_shader_name = "raygeneration";
static const char *closesthit_shader_name = "closesthit";
static const char *miss_shader_name = "miss";
static VkDescriptorPool raytrace_descriptor_pool;
static kinc_raytrace_acceleration_structure_t *accel;
static kinc_raytrace_pipeline_t *pipeline;
static kinc_g5_texture_t *output = NULL;
static PFN_vkCreateRayTracingPipelinesKHR _vkCreateRayTracingPipelinesKHR = NULL;
static PFN_vkGetRayTracingShaderGroupHandlesKHR _vkGetRayTracingShaderGroupHandlesKHR = NULL;
static PFN_vkGetBufferDeviceAddressKHR _vkGetBufferDeviceAddressKHR = NULL;
static PFN_vkCreateAccelerationStructureKHR _vkCreateAccelerationStructureKHR = NULL;
static PFN_vkGetAccelerationStructureDeviceAddressKHR _vkGetAccelerationStructureDeviceAddressKHR = NULL;
static PFN_vkGetAccelerationStructureBuildSizesKHR _vkGetAccelerationStructureBuildSizesKHR = NULL;
static PFN_vkCmdBuildAccelerationStructuresKHR _vkCmdBuildAccelerationStructuresKHR = NULL;
static PFN_vkDestroyAccelerationStructureKHR _vkDestroyAccelerationStructureKHR = NULL;
static PFN_vkCmdTraceRaysKHR _vkCmdTraceRaysKHR = NULL;
void kinc_raytrace_pipeline_init(kinc_raytrace_pipeline_t *pipeline, kinc_g5_command_list_t *command_list, void *ray_shader, int ray_shader_size,
kinc_g5_constant_buffer_t *constant_buffer) {
pipeline->_constant_buffer = constant_buffer;
{
VkDescriptorSetLayoutBinding acceleration_structure_layout_binding = {0};
acceleration_structure_layout_binding.binding = 0;
acceleration_structure_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
acceleration_structure_layout_binding.descriptorCount = 1;
acceleration_structure_layout_binding.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
VkDescriptorSetLayoutBinding result_image_layout_binding = {0};
result_image_layout_binding.binding = 1;
result_image_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
result_image_layout_binding.descriptorCount = 1;
result_image_layout_binding.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
VkDescriptorSetLayoutBinding uniform_buffer_binding = {0};
uniform_buffer_binding.binding = 2;
uniform_buffer_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uniform_buffer_binding.descriptorCount = 1;
uniform_buffer_binding.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
VkDescriptorSetLayoutBinding bindings[3] = {acceleration_structure_layout_binding, result_image_layout_binding, uniform_buffer_binding};
VkDescriptorSetLayoutCreateInfo layout_info = {0};
layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layout_info.pNext = NULL;
layout_info.bindingCount = 3;
layout_info.pBindings = &bindings[0];
vkCreateDescriptorSetLayout(vk_ctx.device, &layout_info, NULL, &pipeline->impl.descriptor_set_layout);
VkPipelineLayoutCreateInfo pipeline_layout_create_info = {0};
pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipeline_layout_create_info.pNext = NULL;
pipeline_layout_create_info.setLayoutCount = 1;
pipeline_layout_create_info.pSetLayouts = &pipeline->impl.descriptor_set_layout;
vkCreatePipelineLayout(vk_ctx.device, &pipeline_layout_create_info, NULL, &pipeline->impl.pipeline_layout);
VkShaderModuleCreateInfo module_create_info = {0};
memset(&module_create_info, 0, sizeof(VkShaderModuleCreateInfo));
module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
module_create_info.codeSize = ray_shader_size;
module_create_info.pCode = (const uint32_t *)ray_shader;
module_create_info.pNext = NULL;
module_create_info.flags = 0;
VkShaderModule shader_module;
vkCreateShaderModule(vk_ctx.device, &module_create_info, NULL, &shader_module);
VkPipelineShaderStageCreateInfo shader_stages[3];
shader_stages[INDEX_RAYGEN].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shader_stages[INDEX_RAYGEN].pNext = NULL;
shader_stages[INDEX_RAYGEN].stage = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
shader_stages[INDEX_RAYGEN].module = shader_module;
shader_stages[INDEX_RAYGEN].pName = raygen_shader_name;
shader_stages[INDEX_RAYGEN].flags = 0;
shader_stages[INDEX_RAYGEN].pSpecializationInfo = NULL;
shader_stages[INDEX_MISS].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shader_stages[INDEX_MISS].pNext = NULL;
shader_stages[INDEX_MISS].stage = VK_SHADER_STAGE_MISS_BIT_KHR;
shader_stages[INDEX_MISS].module = shader_module;
shader_stages[INDEX_MISS].pName = miss_shader_name;
shader_stages[INDEX_MISS].flags = 0;
shader_stages[INDEX_MISS].pSpecializationInfo = NULL;
shader_stages[INDEX_CLOSEST_HIT].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shader_stages[INDEX_CLOSEST_HIT].pNext = NULL;
shader_stages[INDEX_CLOSEST_HIT].stage = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
shader_stages[INDEX_CLOSEST_HIT].module = shader_module;
shader_stages[INDEX_CLOSEST_HIT].pName = closesthit_shader_name;
shader_stages[INDEX_CLOSEST_HIT].flags = 0;
shader_stages[INDEX_CLOSEST_HIT].pSpecializationInfo = NULL;
VkRayTracingShaderGroupCreateInfoKHR groups[3];
groups[INDEX_RAYGEN].sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR;
groups[INDEX_RAYGEN].pNext = NULL;
groups[INDEX_RAYGEN].generalShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_RAYGEN].closestHitShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_RAYGEN].anyHitShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_RAYGEN].intersectionShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_RAYGEN].type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
groups[INDEX_RAYGEN].generalShader = INDEX_RAYGEN;
groups[INDEX_MISS].sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR;
groups[INDEX_MISS].pNext = NULL;
groups[INDEX_MISS].generalShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_MISS].closestHitShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_MISS].anyHitShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_MISS].intersectionShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_MISS].type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
groups[INDEX_MISS].generalShader = INDEX_MISS;
groups[INDEX_CLOSEST_HIT].sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR;
groups[INDEX_CLOSEST_HIT].pNext = NULL;
groups[INDEX_CLOSEST_HIT].generalShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_CLOSEST_HIT].closestHitShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_CLOSEST_HIT].anyHitShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_CLOSEST_HIT].intersectionShader = VK_SHADER_UNUSED_KHR;
groups[INDEX_CLOSEST_HIT].type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR;
groups[INDEX_CLOSEST_HIT].closestHitShader = INDEX_CLOSEST_HIT;
VkRayTracingPipelineCreateInfoKHR raytracing_pipeline_create_info = {0};
raytracing_pipeline_create_info.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR;
raytracing_pipeline_create_info.pNext = NULL;
raytracing_pipeline_create_info.flags = 0;
raytracing_pipeline_create_info.stageCount = 3;
raytracing_pipeline_create_info.pStages = &shader_stages[0];
raytracing_pipeline_create_info.groupCount = 3;
raytracing_pipeline_create_info.pGroups = &groups[0];
raytracing_pipeline_create_info.maxPipelineRayRecursionDepth = 1;
raytracing_pipeline_create_info.layout = pipeline->impl.pipeline_layout;
_vkCreateRayTracingPipelinesKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkCreateRayTracingPipelinesKHR");
_vkCreateRayTracingPipelinesKHR(vk_ctx.device, VK_NULL_HANDLE, VK_NULL_HANDLE, 1, &raytracing_pipeline_create_info, NULL, &pipeline->impl.pipeline);
}
{
VkPhysicalDeviceRayTracingPipelinePropertiesKHR ray_tracing_pipeline_properties;
ray_tracing_pipeline_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR;
ray_tracing_pipeline_properties.pNext = NULL;
VkPhysicalDeviceProperties2 device_properties = {0};
device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
device_properties.pNext = &ray_tracing_pipeline_properties;
vkGetPhysicalDeviceProperties2(vk_ctx.gpu, &device_properties);
_vkGetRayTracingShaderGroupHandlesKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkGetRayTracingShaderGroupHandlesKHR");
uint32_t handle_size = ray_tracing_pipeline_properties.shaderGroupHandleSize;
uint32_t handle_size_aligned =
(ray_tracing_pipeline_properties.shaderGroupHandleSize + ray_tracing_pipeline_properties.shaderGroupHandleAlignment - 1) &
~(ray_tracing_pipeline_properties.shaderGroupHandleAlignment - 1);
VkBufferCreateInfo buf_info = {0};
buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buf_info.pNext = NULL;
buf_info.size = handle_size;
buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
buf_info.flags = 0;
vkCreateBuffer(vk_ctx.device, &buf_info, NULL, &pipeline->impl.raygen_shader_binding_table);
vkCreateBuffer(vk_ctx.device, &buf_info, NULL, &pipeline->impl.hit_shader_binding_table);
vkCreateBuffer(vk_ctx.device, &buf_info, NULL, &pipeline->impl.miss_shader_binding_table);
uint8_t shader_handle_storage[1024];
_vkGetRayTracingShaderGroupHandlesKHR(vk_ctx.device, pipeline->impl.pipeline, 0, 3, handle_size_aligned * 3, shader_handle_storage);
VkMemoryAllocateFlagsInfo memory_allocate_flags_info = {0};
memory_allocate_flags_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO;
memory_allocate_flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
VkMemoryAllocateInfo memory_allocate_info = {0};
memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memory_allocate_info.pNext = &memory_allocate_flags_info;
VkMemoryRequirements mem_reqs = {0};
vkGetBufferMemoryRequirements(vk_ctx.device, pipeline->impl.raygen_shader_binding_table, &mem_reqs);
memory_allocate_info.allocationSize = mem_reqs.size;
memory_type_from_properties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
&memory_allocate_info.memoryTypeIndex);
VkDeviceMemory mem;
void *data;
vkAllocateMemory(vk_ctx.device, &memory_allocate_info, NULL, &mem);
vkBindBufferMemory(vk_ctx.device, pipeline->impl.raygen_shader_binding_table, mem, 0);
vkMapMemory(vk_ctx.device, mem, 0, handle_size, 0, (void **)&data);
memcpy(data, shader_handle_storage, handle_size);
vkUnmapMemory(vk_ctx.device, mem);
vkGetBufferMemoryRequirements(vk_ctx.device, pipeline->impl.miss_shader_binding_table, &mem_reqs);
memory_allocate_info.allocationSize = mem_reqs.size;
memory_type_from_properties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memory_allocate_info.memoryTypeIndex);
vkAllocateMemory(vk_ctx.device, &memory_allocate_info, NULL, &mem);
vkBindBufferMemory(vk_ctx.device, pipeline->impl.miss_shader_binding_table, mem, 0);
vkMapMemory(vk_ctx.device, mem, 0, handle_size, 0, (void **)&data);
memcpy(data, shader_handle_storage + handle_size_aligned, handle_size);
vkUnmapMemory(vk_ctx.device, mem);
vkGetBufferMemoryRequirements(vk_ctx.device, pipeline->impl.hit_shader_binding_table, &mem_reqs);
memory_allocate_info.allocationSize = mem_reqs.size;
memory_type_from_properties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memory_allocate_info.memoryTypeIndex);
vkAllocateMemory(vk_ctx.device, &memory_allocate_info, NULL, &mem);
vkBindBufferMemory(vk_ctx.device, pipeline->impl.hit_shader_binding_table, mem, 0);
vkMapMemory(vk_ctx.device, mem, 0, handle_size, 0, (void **)&data);
memcpy(data, shader_handle_storage + handle_size_aligned * 2, handle_size);
vkUnmapMemory(vk_ctx.device, mem);
}
{
VkDescriptorPoolSize type_counts[3];
memset(type_counts, 0, sizeof(type_counts));
type_counts[0].type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
type_counts[0].descriptorCount = 1;
type_counts[1].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
type_counts[1].descriptorCount = 1;
type_counts[2].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
type_counts[2].descriptorCount = 1;
VkDescriptorPoolCreateInfo descriptor_pool_create_info = {0};
descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptor_pool_create_info.pNext = NULL;
descriptor_pool_create_info.maxSets = 1024;
descriptor_pool_create_info.poolSizeCount = 3;
descriptor_pool_create_info.pPoolSizes = type_counts;
vkCreateDescriptorPool(vk_ctx.device, &descriptor_pool_create_info, NULL, &raytrace_descriptor_pool);
VkDescriptorSetAllocateInfo alloc_info = {0};
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info.pNext = NULL;
alloc_info.descriptorPool = raytrace_descriptor_pool;
alloc_info.descriptorSetCount = 1;
alloc_info.pSetLayouts = &pipeline->impl.descriptor_set_layout;
vkAllocateDescriptorSets(vk_ctx.device, &alloc_info, &pipeline->impl.descriptor_set);
}
}
void kinc_raytrace_pipeline_destroy(kinc_raytrace_pipeline_t *pipeline) {
vkDestroyPipeline(vk_ctx.device, pipeline->impl.pipeline, NULL);
vkDestroyPipelineLayout(vk_ctx.device, pipeline->impl.pipeline_layout, NULL);
vkDestroyDescriptorSetLayout(vk_ctx.device, pipeline->impl.descriptor_set_layout, NULL);
}
uint64_t get_buffer_device_address(VkBuffer buffer) {
VkBufferDeviceAddressInfoKHR buffer_device_address_info = {0};
buffer_device_address_info.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
buffer_device_address_info.buffer = buffer;
_vkGetBufferDeviceAddressKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkGetBufferDeviceAddressKHR");
return _vkGetBufferDeviceAddressKHR(vk_ctx.device, &buffer_device_address_info);
}
void kinc_raytrace_acceleration_structure_init(kinc_raytrace_acceleration_structure_t *accel, kinc_g5_command_list_t *command_list, kinc_g5_vertex_buffer_t *vb,
kinc_g5_index_buffer_t *ib) {
_vkGetBufferDeviceAddressKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkGetBufferDeviceAddressKHR");
_vkCreateAccelerationStructureKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkCreateAccelerationStructureKHR");
_vkGetAccelerationStructureDeviceAddressKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkGetAccelerationStructureDeviceAddressKHR");
_vkGetAccelerationStructureBuildSizesKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkGetAccelerationStructureBuildSizesKHR");
{
VkDeviceOrHostAddressConstKHR vertex_data_device_address = {0};
VkDeviceOrHostAddressConstKHR index_data_device_address = {0};
vertex_data_device_address.deviceAddress = get_buffer_device_address(vb->impl.vertices.buf);
index_data_device_address.deviceAddress = get_buffer_device_address(ib->impl.buf);
VkAccelerationStructureGeometryKHR acceleration_geometry = {0};
acceleration_geometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
acceleration_geometry.flags = VK_GEOMETRY_OPAQUE_BIT_KHR;
acceleration_geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
acceleration_geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
acceleration_geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
acceleration_geometry.geometry.triangles.vertexData.deviceAddress = vertex_data_device_address.deviceAddress;
acceleration_geometry.geometry.triangles.vertexStride = vb->impl.myStride;
acceleration_geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
acceleration_geometry.geometry.triangles.indexData.deviceAddress = index_data_device_address.deviceAddress;
VkAccelerationStructureBuildGeometryInfoKHR acceleration_structure_build_geometry_info = {0};
acceleration_structure_build_geometry_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
acceleration_structure_build_geometry_info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
acceleration_structure_build_geometry_info.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
acceleration_structure_build_geometry_info.geometryCount = 1;
acceleration_structure_build_geometry_info.pGeometries = &acceleration_geometry;
VkAccelerationStructureBuildSizesInfoKHR acceleration_build_sizes_info = {0};
acceleration_build_sizes_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
const uint32_t primitive_count = 1;
_vkGetAccelerationStructureBuildSizesKHR(vk_ctx.device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &acceleration_structure_build_geometry_info,
&primitive_count, &acceleration_build_sizes_info);
VkBufferCreateInfo buffer_create_info = {0};
buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_create_info.size = acceleration_build_sizes_info.accelerationStructureSize;
buffer_create_info.usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR;
buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VkBuffer bottom_level_buffer = VK_NULL_HANDLE;
vkCreateBuffer(vk_ctx.device, &buffer_create_info, NULL, &bottom_level_buffer);
VkMemoryRequirements memory_requirements2;
vkGetBufferMemoryRequirements(vk_ctx.device, bottom_level_buffer, &memory_requirements2);
VkMemoryAllocateFlagsInfo memory_allocate_flags_info2 = {0};
memory_allocate_flags_info2.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO;
memory_allocate_flags_info2.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
VkMemoryAllocateInfo memory_allocate_info = {0};
memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memory_allocate_info.pNext = &memory_allocate_flags_info2;
memory_allocate_info.allocationSize = memory_requirements2.size;
memory_type_from_properties(memory_requirements2.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memory_allocate_info.memoryTypeIndex);
VkDeviceMemory mem;
vkAllocateMemory(vk_ctx.device, &memory_allocate_info, NULL, &mem);
vkBindBufferMemory(vk_ctx.device, bottom_level_buffer, mem, 0);
VkAccelerationStructureCreateInfoKHR acceleration_create_info = {0};
acceleration_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
acceleration_create_info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
acceleration_create_info.buffer = bottom_level_buffer;
acceleration_create_info.size = acceleration_build_sizes_info.accelerationStructureSize;
_vkCreateAccelerationStructureKHR(vk_ctx.device, &acceleration_create_info, NULL, &accel->impl.bottom_level_acceleration_structure);
VkBuffer scratch_buffer = VK_NULL_HANDLE;
VkDeviceMemory scratch_memory = VK_NULL_HANDLE;
buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_create_info.size = acceleration_build_sizes_info.buildScratchSize;
buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
vkCreateBuffer(vk_ctx.device, &buffer_create_info, NULL, &scratch_buffer);
VkMemoryRequirements memory_requirements;
vkGetBufferMemoryRequirements(vk_ctx.device, scratch_buffer, &memory_requirements);
VkMemoryAllocateFlagsInfo memory_allocate_flags_info = {0};
memory_allocate_flags_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO;
memory_allocate_flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memory_allocate_info.pNext = &memory_allocate_flags_info;
memory_allocate_info.allocationSize = memory_requirements.size;
memory_type_from_properties(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memory_allocate_info.memoryTypeIndex);
vkAllocateMemory(vk_ctx.device, &memory_allocate_info, NULL, &scratch_memory);
vkBindBufferMemory(vk_ctx.device, scratch_buffer, scratch_memory, 0);
VkBufferDeviceAddressInfoKHR buffer_device_address_info = {0};
buffer_device_address_info.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
buffer_device_address_info.buffer = scratch_buffer;
uint64_t scratch_buffer_device_address = _vkGetBufferDeviceAddressKHR(vk_ctx.device, &buffer_device_address_info);
VkAccelerationStructureBuildGeometryInfoKHR acceleration_build_geometry_info = {0};
acceleration_build_geometry_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
acceleration_build_geometry_info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
acceleration_build_geometry_info.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
acceleration_build_geometry_info.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
acceleration_build_geometry_info.dstAccelerationStructure = accel->impl.bottom_level_acceleration_structure;
acceleration_build_geometry_info.geometryCount = 1;
acceleration_build_geometry_info.pGeometries = &acceleration_geometry;
acceleration_build_geometry_info.scratchData.deviceAddress = scratch_buffer_device_address;
VkAccelerationStructureBuildRangeInfoKHR acceleration_build_range_info = {0};
acceleration_build_range_info.primitiveCount = 1;
acceleration_build_range_info.primitiveOffset = 0x0;
acceleration_build_range_info.firstVertex = 0;
acceleration_build_range_info.transformOffset = 0x0;
const VkAccelerationStructureBuildRangeInfoKHR *acceleration_build_infos[1] = {&acceleration_build_range_info};
{
VkCommandBufferAllocateInfo cmd_buf_allocate_info = {0};
cmd_buf_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmd_buf_allocate_info.commandPool = vk_ctx.cmd_pool;
cmd_buf_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmd_buf_allocate_info.commandBufferCount = 1;
VkCommandBuffer command_buffer;
vkAllocateCommandBuffers(vk_ctx.device, &cmd_buf_allocate_info, &command_buffer);
VkCommandBufferBeginInfo command_buffer_info = {0};
command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(command_buffer, &command_buffer_info);
_vkCmdBuildAccelerationStructuresKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkCmdBuildAccelerationStructuresKHR");
_vkCmdBuildAccelerationStructuresKHR(command_buffer, 1, &acceleration_build_geometry_info, &acceleration_build_infos[0]);
vkEndCommandBuffer(command_buffer);
VkSubmitInfo submit_info = {0};
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &command_buffer;
VkFenceCreateInfo fence_info = {0};
fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fence_info.flags = 0;
VkFence fence;
vkCreateFence(vk_ctx.device, &fence_info, NULL, &fence);
VkResult result = vkQueueSubmit(vk_ctx.queue, 1, &submit_info, fence);
assert(!result);
vkWaitForFences(vk_ctx.device, 1, &fence, VK_TRUE, 100000000000);
vkDestroyFence(vk_ctx.device, fence, NULL);
vkFreeCommandBuffers(vk_ctx.device, vk_ctx.cmd_pool, 1, &command_buffer);
}
VkAccelerationStructureDeviceAddressInfoKHR acceleration_device_address_info = {0};
acceleration_device_address_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
acceleration_device_address_info.accelerationStructure = accel->impl.bottom_level_acceleration_structure;
accel->impl.bottom_level_acceleration_structure_handle = _vkGetAccelerationStructureDeviceAddressKHR(vk_ctx.device, &acceleration_device_address_info);
vkFreeMemory(vk_ctx.device, scratch_memory, NULL);
vkDestroyBuffer(vk_ctx.device, scratch_buffer, NULL);
}
{
VkTransformMatrixKHR transform_matrix = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
VkAccelerationStructureInstanceKHR instance = {0};
instance.transform = transform_matrix;
instance.instanceCustomIndex = 0;
instance.mask = 0xFF;
instance.instanceShaderBindingTableRecordOffset = 0;
instance.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
instance.accelerationStructureReference = accel->impl.bottom_level_acceleration_structure_handle;
VkBufferCreateInfo buf_info = {0};
buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buf_info.pNext = NULL;
buf_info.size = sizeof(instance);
buf_info.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
buf_info.flags = 0;
VkMemoryAllocateInfo mem_alloc;
memset(&mem_alloc, 0, sizeof(VkMemoryAllocateInfo));
mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
mem_alloc.pNext = NULL;
mem_alloc.allocationSize = 0;
mem_alloc.memoryTypeIndex = 0;
VkBuffer instances_buffer;
vkCreateBuffer(vk_ctx.device, &buf_info, NULL, &instances_buffer);
VkMemoryRequirements mem_reqs = {0};
vkGetBufferMemoryRequirements(vk_ctx.device, instances_buffer, &mem_reqs);
mem_alloc.allocationSize = mem_reqs.size;
memory_type_from_properties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &mem_alloc.memoryTypeIndex);
VkMemoryAllocateFlagsInfo memory_allocate_flags_info = {0};
memory_allocate_flags_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO;
memory_allocate_flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
mem_alloc.pNext = &memory_allocate_flags_info;
VkDeviceMemory mem;
vkAllocateMemory(vk_ctx.device, &mem_alloc, NULL, &mem);
vkBindBufferMemory(vk_ctx.device, instances_buffer, mem, 0);
void *data;
vkMapMemory(vk_ctx.device, mem, 0, sizeof(VkAccelerationStructureInstanceKHR), 0, (void **)&data);
memcpy(data, &instance, sizeof(VkAccelerationStructureInstanceKHR));
vkUnmapMemory(vk_ctx.device, mem);
VkDeviceOrHostAddressConstKHR instance_data_device_address = {0};
instance_data_device_address.deviceAddress = get_buffer_device_address(instances_buffer);
VkAccelerationStructureGeometryKHR acceleration_geometry = {0};
acceleration_geometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
acceleration_geometry.flags = VK_GEOMETRY_OPAQUE_BIT_KHR;
acceleration_geometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
acceleration_geometry.geometry.instances.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
acceleration_geometry.geometry.instances.arrayOfPointers = VK_FALSE;
acceleration_geometry.geometry.instances.data.deviceAddress = instance_data_device_address.deviceAddress;
VkAccelerationStructureBuildGeometryInfoKHR acceleration_structure_build_geometry_info = {0};
acceleration_structure_build_geometry_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
acceleration_structure_build_geometry_info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
acceleration_structure_build_geometry_info.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
acceleration_structure_build_geometry_info.geometryCount = 1;
acceleration_structure_build_geometry_info.pGeometries = &acceleration_geometry;
VkAccelerationStructureBuildSizesInfoKHR acceleration_build_sizes_info = {0};
acceleration_build_sizes_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
const uint32_t primitive_count = 1;
_vkGetAccelerationStructureBuildSizesKHR(vk_ctx.device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &acceleration_structure_build_geometry_info,
&primitive_count, &acceleration_build_sizes_info);
VkBufferCreateInfo buffer_create_info = {0};
buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_create_info.size = acceleration_build_sizes_info.accelerationStructureSize;
buffer_create_info.usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR;
buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VkBuffer top_level_buffer = VK_NULL_HANDLE;
vkCreateBuffer(vk_ctx.device, &buffer_create_info, NULL, &top_level_buffer);
VkMemoryRequirements memory_requirements2;
vkGetBufferMemoryRequirements(vk_ctx.device, top_level_buffer, &memory_requirements2);
memory_allocate_flags_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO;
memory_allocate_flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
VkMemoryAllocateInfo memory_allocate_info = {0};
memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memory_allocate_info.pNext = &memory_allocate_flags_info;
memory_allocate_info.allocationSize = memory_requirements2.size;
memory_type_from_properties(memory_requirements2.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memory_allocate_info.memoryTypeIndex);
vkAllocateMemory(vk_ctx.device, &memory_allocate_info, NULL, &mem);
vkBindBufferMemory(vk_ctx.device, top_level_buffer, mem, 0);
VkAccelerationStructureCreateInfoKHR acceleration_create_info = {0};
acceleration_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
acceleration_create_info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
acceleration_create_info.buffer = top_level_buffer;
acceleration_create_info.size = acceleration_build_sizes_info.accelerationStructureSize;
_vkCreateAccelerationStructureKHR(vk_ctx.device, &acceleration_create_info, NULL, &accel->impl.top_level_acceleration_structure);
VkBuffer scratch_buffer = VK_NULL_HANDLE;
VkDeviceMemory scratch_memory = VK_NULL_HANDLE;
buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_create_info.size = acceleration_build_sizes_info.buildScratchSize;
buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
vkCreateBuffer(vk_ctx.device, &buffer_create_info, NULL, &scratch_buffer);
VkMemoryRequirements memory_requirements;
vkGetBufferMemoryRequirements(vk_ctx.device, scratch_buffer, &memory_requirements);
memory_allocate_flags_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO;
memory_allocate_flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memory_allocate_info.pNext = &memory_allocate_flags_info;
memory_allocate_info.allocationSize = memory_requirements.size;
memory_type_from_properties(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memory_allocate_info.memoryTypeIndex);
vkAllocateMemory(vk_ctx.device, &memory_allocate_info, NULL, &scratch_memory);
vkBindBufferMemory(vk_ctx.device, scratch_buffer, scratch_memory, 0);
VkBufferDeviceAddressInfoKHR buffer_device_address_info = {0};
buffer_device_address_info.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
buffer_device_address_info.buffer = scratch_buffer;
uint64_t scratch_buffer_device_address = _vkGetBufferDeviceAddressKHR(vk_ctx.device, &buffer_device_address_info);
VkAccelerationStructureBuildGeometryInfoKHR acceleration_build_geometry_info = {0};
acceleration_build_geometry_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
acceleration_build_geometry_info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
acceleration_build_geometry_info.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
acceleration_build_geometry_info.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
acceleration_build_geometry_info.srcAccelerationStructure = VK_NULL_HANDLE;
acceleration_build_geometry_info.dstAccelerationStructure = accel->impl.top_level_acceleration_structure;
acceleration_build_geometry_info.geometryCount = 1;
acceleration_build_geometry_info.pGeometries = &acceleration_geometry;
acceleration_build_geometry_info.scratchData.deviceAddress = scratch_buffer_device_address;
VkAccelerationStructureBuildRangeInfoKHR acceleration_build_range_info = {0};
acceleration_build_range_info.primitiveCount = 1;
acceleration_build_range_info.primitiveOffset = 0x0;
acceleration_build_range_info.firstVertex = 0;
acceleration_build_range_info.transformOffset = 0x0;
const VkAccelerationStructureBuildRangeInfoKHR *acceleration_build_infos[1] = {&acceleration_build_range_info};
{
VkCommandBufferAllocateInfo cmd_buf_allocate_info = {0};
cmd_buf_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmd_buf_allocate_info.commandPool = vk_ctx.cmd_pool;
cmd_buf_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmd_buf_allocate_info.commandBufferCount = 1;
VkCommandBuffer command_buffer;
vkAllocateCommandBuffers(vk_ctx.device, &cmd_buf_allocate_info, &command_buffer);
VkCommandBufferBeginInfo command_buffer_info = {0};
command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(command_buffer, &command_buffer_info);
_vkCmdBuildAccelerationStructuresKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkCmdBuildAccelerationStructuresKHR");
_vkCmdBuildAccelerationStructuresKHR(command_buffer, 1, &acceleration_build_geometry_info, &acceleration_build_infos[0]);
vkEndCommandBuffer(command_buffer);
VkSubmitInfo submit_info = {0};
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &command_buffer;
VkFenceCreateInfo fence_info = {0};
fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fence_info.flags = 0;
VkFence fence;
vkCreateFence(vk_ctx.device, &fence_info, NULL, &fence);
VkResult result = vkQueueSubmit(vk_ctx.queue, 1, &submit_info, fence);
assert(!result);
vkWaitForFences(vk_ctx.device, 1, &fence, VK_TRUE, 100000000000);
vkDestroyFence(vk_ctx.device, fence, NULL);
vkFreeCommandBuffers(vk_ctx.device, vk_ctx.cmd_pool, 1, &command_buffer);
}
VkAccelerationStructureDeviceAddressInfoKHR acceleration_device_address_info = {0};
acceleration_device_address_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
acceleration_device_address_info.accelerationStructure = accel->impl.top_level_acceleration_structure;
accel->impl.top_level_acceleration_structure_handle = _vkGetAccelerationStructureDeviceAddressKHR(vk_ctx.device, &acceleration_device_address_info);
vkFreeMemory(vk_ctx.device, scratch_memory, NULL);
vkDestroyBuffer(vk_ctx.device, scratch_buffer, NULL);
}
}
void kinc_raytrace_acceleration_structure_destroy(kinc_raytrace_acceleration_structure_t *accel) {
_vkDestroyAccelerationStructureKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkDestroyAccelerationStructureKHR");
_vkDestroyAccelerationStructureKHR(vk_ctx.device, accel->impl.bottom_level_acceleration_structure, NULL);
_vkDestroyAccelerationStructureKHR(vk_ctx.device, accel->impl.top_level_acceleration_structure, NULL);
}
void kinc_raytrace_set_acceleration_structure(kinc_raytrace_acceleration_structure_t *_accel) {
accel = _accel;
}
void kinc_raytrace_set_pipeline(kinc_raytrace_pipeline_t *_pipeline) {
pipeline = _pipeline;
}
void kinc_raytrace_set_target(kinc_g5_texture_t *_output) {
output = _output;
}
void kinc_raytrace_dispatch_rays(kinc_g5_command_list_t *command_list) {
VkWriteDescriptorSetAccelerationStructureKHR descriptor_acceleration_structure_info = {0};
descriptor_acceleration_structure_info.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
descriptor_acceleration_structure_info.accelerationStructureCount = 1;
descriptor_acceleration_structure_info.pAccelerationStructures = &accel->impl.top_level_acceleration_structure;
VkWriteDescriptorSet acceleration_structure_write = {0};
acceleration_structure_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
acceleration_structure_write.pNext = &descriptor_acceleration_structure_info;
acceleration_structure_write.dstSet = pipeline->impl.descriptor_set;
acceleration_structure_write.dstBinding = 0;
acceleration_structure_write.descriptorCount = 1;
acceleration_structure_write.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
VkDescriptorImageInfo image_descriptor = {0};
image_descriptor.imageView = output->impl.texture.view;
image_descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
VkDescriptorBufferInfo buffer_descriptor = {0};
buffer_descriptor.buffer = pipeline->_constant_buffer->impl.buf;
buffer_descriptor.range = VK_WHOLE_SIZE;
buffer_descriptor.offset = 0;
VkWriteDescriptorSet result_image_write = {0};
result_image_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
result_image_write.pNext = NULL;
result_image_write.dstSet = pipeline->impl.descriptor_set;
result_image_write.dstBinding = 1;
result_image_write.descriptorCount = 1;
result_image_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
result_image_write.pImageInfo = &image_descriptor;
VkWriteDescriptorSet uniform_buffer_write = {0};
uniform_buffer_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
uniform_buffer_write.pNext = NULL;
uniform_buffer_write.dstSet = pipeline->impl.descriptor_set;
uniform_buffer_write.dstBinding = 2;
uniform_buffer_write.descriptorCount = 1;
uniform_buffer_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uniform_buffer_write.pBufferInfo = &buffer_descriptor;
VkWriteDescriptorSet write_descriptor_sets[3] = {acceleration_structure_write, result_image_write, uniform_buffer_write};
vkUpdateDescriptorSets(vk_ctx.device, 3, write_descriptor_sets, 0, VK_NULL_HANDLE);
VkPhysicalDeviceRayTracingPipelinePropertiesKHR ray_tracing_pipeline_properties;
ray_tracing_pipeline_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR;
ray_tracing_pipeline_properties.pNext = NULL;
VkPhysicalDeviceProperties2 device_properties = {0};
device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
device_properties.pNext = &ray_tracing_pipeline_properties;
vkGetPhysicalDeviceProperties2(vk_ctx.gpu, &device_properties);
// Setup the strided buffer regions pointing to the shaders in our shader binding table
const uint32_t handle_size_aligned =
(ray_tracing_pipeline_properties.shaderGroupHandleSize + ray_tracing_pipeline_properties.shaderGroupHandleAlignment - 1) &
~(ray_tracing_pipeline_properties.shaderGroupHandleAlignment - 1);
VkStridedDeviceAddressRegionKHR raygen_shader_sbt_entry = {0};
raygen_shader_sbt_entry.deviceAddress = get_buffer_device_address(pipeline->impl.raygen_shader_binding_table);
raygen_shader_sbt_entry.stride = handle_size_aligned;
raygen_shader_sbt_entry.size = handle_size_aligned;
VkStridedDeviceAddressRegionKHR miss_shader_sbt_entry = {0};
miss_shader_sbt_entry.deviceAddress = get_buffer_device_address(pipeline->impl.miss_shader_binding_table);
miss_shader_sbt_entry.stride = handle_size_aligned;
miss_shader_sbt_entry.size = handle_size_aligned;
VkStridedDeviceAddressRegionKHR hit_shader_sbt_entry = {0};
hit_shader_sbt_entry.deviceAddress = get_buffer_device_address(pipeline->impl.hit_shader_binding_table);
hit_shader_sbt_entry.stride = handle_size_aligned;
hit_shader_sbt_entry.size = handle_size_aligned;
VkStridedDeviceAddressRegionKHR callable_shader_sbt_entry = {0};
vkCmdEndRenderPass(command_list->impl._buffer);
// Dispatch the ray tracing commands
vkCmdBindPipeline(command_list->impl._buffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline->impl.pipeline);
vkCmdBindDescriptorSets(command_list->impl._buffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline->impl.pipeline_layout, 0, 1,
&pipeline->impl.descriptor_set, 0, 0);
_vkCmdTraceRaysKHR = (void *)vkGetDeviceProcAddr(vk_ctx.device, "vkCmdTraceRaysKHR");
_vkCmdTraceRaysKHR(command_list->impl._buffer, &raygen_shader_sbt_entry, &miss_shader_sbt_entry, &hit_shader_sbt_entry, &callable_shader_sbt_entry,
output->texWidth, output->texHeight, 1);
vkCmdBeginRenderPass(command_list->impl._buffer, &currentRenderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
}
void kinc_raytrace_copy(kinc_g5_command_list_t *command_list, kinc_g5_render_target_t *target, kinc_g5_texture_t *source) {
vkCmdEndRenderPass(command_list->impl._buffer);
VkImageCopy copy_region = {0};
copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_region.srcSubresource.layerCount = 1;
copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_region.dstSubresource.layerCount = 1;
copy_region.extent.width = (uint32_t)output->texWidth;
copy_region.extent.height = (uint32_t)output->texHeight;
copy_region.extent.depth = 1;
if (target->framebuffer_index >= 0) {
vkCmdCopyImage(command_list->impl._buffer, output->impl.texture.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
vk_ctx.windows[vk_ctx.current_window].images[vk_ctx.windows[vk_ctx.current_window].current_image], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copy_region);
}
else {
vkCmdCopyImage(command_list->impl._buffer, output->impl.texture.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, target->impl.sourceImage,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
}
vkCmdBeginRenderPass(command_list->impl._buffer, &currentRenderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
}
#endif