770 lines
41 KiB
C
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, ¤tRenderPassBeginInfo, 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, ©_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, ©_region);
|
|
}
|
|
|
|
vkCmdBeginRenderPass(command_list->impl._buffer, ¤tRenderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
|
}
|
|
|
|
#endif
|