base: add gpu_raytrace_multi

This commit is contained in:
luboslenco
2026-08-13 12:51:49 +02:00
parent 95fb772b23
commit b61743e2f1
4 changed files with 58 additions and 151 deletions
+28 -15
View File
@@ -1254,9 +1254,9 @@ static D3D12_GPU_DESCRIPTOR_HANDLE dxr_texscramblegpu_descriptor_handle;
static D3D12_GPU_DESCRIPTOR_HANDLE dxr_texrankgpu_descriptor_handle;
static int dxr_descriptors_allocated = 0;
static UINT dxr_descriptor_size;
static gpu_buffer_t *dxr_vb[16];
static gpu_buffer_t *dxr_vb_last[16];
static gpu_buffer_t *dxr_ib[16];
static gpu_buffer_t *dxr_vb[GPU_RAYTRACE_MAX_OBJECTS];
static gpu_buffer_t *dxr_vb_last[GPU_RAYTRACE_MAX_OBJECTS];
static gpu_buffer_t *dxr_ib[GPU_RAYTRACE_MAX_OBJECTS];
static int dxr_vb_count = 0;
static int dxr_vb_count_last = 0;
static inst_t dxr_instances[1024];
@@ -1434,7 +1434,12 @@ UINT create_srv_ib(gpu_buffer_t *ib, UINT num_elements, UINT element_size) {
void gpu_raytrace_acceleration_structure_init(gpu_acceleration_structure_t *accel) {
dxr_vb_count = 0;
dxr_instances_count = 0;
memset(dxr_vb_last, 0, sizeof(dxr_vb_last));
if (gpu_raytrace_multi) {
memset(dxr_vb, 0, sizeof(dxr_vb));
}
else {
memset(dxr_vb_last, 0, sizeof(dxr_vb_last));
}
}
void gpu_raytrace_acceleration_structure_add(gpu_acceleration_structure_t *accel, gpu_buffer_t *vb, gpu_buffer_t *ib, mat4_t transform) {
@@ -1446,12 +1451,19 @@ void gpu_raytrace_acceleration_structure_add(gpu_acceleration_structure_t *accel
}
}
if (vb_i == -1) {
if (dxr_vb_count >= GPU_RAYTRACE_MAX_OBJECTS) {
return;
}
vb_i = dxr_vb_count;
dxr_vb[dxr_vb_count] = vb;
dxr_ib[dxr_vb_count] = ib;
dxr_vb_count++;
}
if (dxr_instances_count >= (int)(sizeof(dxr_instances) / sizeof(dxr_instances[0]))) {
return;
}
inst_t inst = {.i = vb_i, .m = transform};
dxr_instances[dxr_instances_count] = inst;
dxr_instances_count++;
@@ -1469,7 +1481,7 @@ void _gpu_raytrace_acceleration_structure_destroy_top(gpu_acceleration_structure
void gpu_raytrace_acceleration_structure_build(gpu_acceleration_structure_t *accel, gpu_buffer_t *vb_full, gpu_buffer_t *ib_full) {
bool build_bottom = false;
for (int i = 0; i < 16; ++i) {
for (int i = 0; i < GPU_RAYTRACE_MAX_OBJECTS; ++i) {
if (dxr_vb_last[i] != dxr_vb[i]) {
build_bottom = true;
}
@@ -1491,20 +1503,21 @@ void gpu_raytrace_acceleration_structure_build(gpu_acceleration_structure_t *acc
dxr_descriptors_allocated = 1; // 1 descriptor already allocated in gpu_raytrace_pipeline_init
#ifdef is_forge
create_srv_ib(ib_full, ib_full->count, 0);
create_srv_vb(vb_full, vb_full->count, dxr_vb[0]->stride);
#else
create_srv_ib(dxr_ib[0], dxr_ib[0]->count, 0);
create_srv_vb(dxr_vb[0], dxr_vb[0]->count, dxr_vb[0]->stride);
#endif
if (gpu_raytrace_multi) {
create_srv_ib(ib_full, ib_full->count, 0);
create_srv_vb(vb_full, vb_full->count, dxr_vb[0]->stride);
}
else {
create_srv_ib(dxr_ib[0], dxr_ib[0]->count, 0);
create_srv_vb(dxr_vb[0], dxr_vb[0]->count, dxr_vb[0]->stride);
}
command_list->lpVtbl->Reset(command_list, command_allocator, NULL);
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS top_level_inputs = {
.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY,
.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE,
.NumDescs = 1,
.NumDescs = gpu_raytrace_multi ? dxr_instances_count : 1,
.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL,
};
@@ -1514,8 +1527,8 @@ void gpu_raytrace_acceleration_structure_build(gpu_acceleration_structure_t *acc
UINT64 scratch_size = top_level_prebuild_info.ScratchDataSizeInBytes;
// Bottom AS
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS bottom_level_inputs[16];
D3D12_RAYTRACING_GEOMETRY_DESC geometry_descs[16];
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS bottom_level_inputs[GPU_RAYTRACE_MAX_OBJECTS];
D3D12_RAYTRACING_GEOMETRY_DESC geometry_descs[GPU_RAYTRACE_MAX_OBJECTS];
if (build_bottom) {
for (int i = 0; i < dxr_vb_count; ++i) {
D3D12_RAYTRACING_GEOMETRY_DESC geometry_desc = {
+3 -1
View File
@@ -3,6 +3,8 @@
#include <stdbool.h>
#include <stdint.h>
#define GPU_RAYTRACE_MAX_OBJECTS 64
struct ID3D12Resource;
struct ID3D12DescriptorHeap;
struct ID3D12PipelineState;
@@ -66,6 +68,6 @@ typedef struct {
} gpu_buffer_impl_t;
typedef struct {
struct ID3D12Resource *bottom_level_accel[16];
struct ID3D12Resource *bottom_level_accel[GPU_RAYTRACE_MAX_OBJECTS];
struct ID3D12Resource *top_level_accel;
} gpu_acceleration_structure_impl_t;
+21 -131
View File
@@ -1995,17 +1995,15 @@ static gpu_texture_t *texenv;
static gpu_texture_t *texsobol;
static gpu_texture_t *texscramble;
static gpu_texture_t *texrank;
static gpu_buffer_t *vb[16];
static gpu_buffer_t *vb_last[16];
static gpu_buffer_t *ib[16];
static gpu_buffer_t *vb[GPU_RAYTRACE_MAX_OBJECTS];
static gpu_buffer_t *vb_last[GPU_RAYTRACE_MAX_OBJECTS];
static gpu_buffer_t *ib[GPU_RAYTRACE_MAX_OBJECTS];
static int vb_count = 0;
static int vb_count_last = 0;
static inst_t instances[1024];
static int instances_count = 0;
static VkBuffer vb_full = VK_NULL_HANDLE;
static VkBuffer ib_full = VK_NULL_HANDLE;
static VkDeviceMemory vb_full_mem = VK_NULL_HANDLE;
static VkDeviceMemory ib_full_mem = VK_NULL_HANDLE;
static PFN_vkGetBufferDeviceAddressKHR _vkGetBufferDeviceAddressKHR = NULL;
static PFN_vkCreateAccelerationStructureKHR _vkCreateAccelerationStructureKHR = NULL;
@@ -2154,7 +2152,12 @@ void gpu_raytrace_acceleration_structure_init(gpu_acceleration_structure_t *acce
vb_count = 0;
instances_count = 0;
memset(vb_last, 0, sizeof(vb_last));
if (gpu_raytrace_multi) {
memset(vb, 0, sizeof(vb));
}
else {
memset(vb_last, 0, sizeof(vb_last));
}
}
void gpu_raytrace_acceleration_structure_add(gpu_acceleration_structure_t *accel, gpu_buffer_t *_vb, gpu_buffer_t *_ib, mat4_t _transform) {
@@ -2166,12 +2169,19 @@ void gpu_raytrace_acceleration_structure_add(gpu_acceleration_structure_t *accel
}
}
if (vb_i == -1) {
if (vb_count >= GPU_RAYTRACE_MAX_OBJECTS) {
return;
}
vb_i = vb_count;
vb[vb_count] = _vb;
ib[vb_count] = _ib;
vb_count++;
}
if (instances_count >= (int)(sizeof(instances) / sizeof(instances[0]))) {
return;
}
inst_t inst = {.i = vb_i, .m = _transform};
instances[instances_count] = inst;
instances_count++;
@@ -2199,7 +2209,7 @@ void gpu_raytrace_acceleration_structure_build(gpu_acceleration_structure_t *acc
gpu_execute_and_wait();
bool build_bottom = false;
for (int i = 0; i < 16; ++i) {
for (int i = 0; i < GPU_RAYTRACE_MAX_OBJECTS; ++i) {
if (vb_last[i] != vb[i]) {
build_bottom = true;
}
@@ -2430,7 +2440,7 @@ void gpu_raytrace_acceleration_structure_build(gpu_acceleration_structure_t *acc
vkBindBufferMemory(device, instances_buffer, instances_mem, 0);
void *data;
vkMapMemory(device, instances_mem, 0, sizeof(VkAccelerationStructureInstanceKHR), 0, (void **)&data);
vkMapMemory(device, instances_mem, 0, (gpu_raytrace_multi ? instances_count : 1) * sizeof(VkAccelerationStructureInstanceKHR), 0, (void **)&data);
for (int i = 0; i < instances_count; ++i) {
VkTransformMatrixKHR transform_matrix = {instances[i].m.m[0], instances[i].m.m[4], instances[i].m.m[8], instances[i].m.m[12],
@@ -2442,7 +2452,7 @@ void gpu_raytrace_acceleration_structure_build(gpu_acceleration_structure_t *acc
int ib_off = 0;
for (int j = 0; j < instances[i].i; ++j) {
ib_off += ib[j]->count * 4;
ib_off += ib[j]->count;
}
instance.instanceCustomIndex = ib_off;
@@ -2619,128 +2629,8 @@ void gpu_raytrace_acceleration_structure_build(gpu_acceleration_structure_t *acc
accel->impl.instances_mem = instances_mem;
}
{
// if (vb_full != NULL) {
// vkFreeMemory(device, vb_full_mem, NULL);
// vkDestroyBuffer(device, vb_full, NULL);
// }
// VkBufferCreateInfo buf_info = {
// .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
// .pNext = NULL,
// .size = vert_count * vb[0]->stride,
// .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
// .usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
// .usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
// .usage |= VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
// .flags = 0,
// };
// VkMemoryAllocateInfo mem_alloc = {
// .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
// .pNext = NULL,
// .allocationSize = 0,
// .memoryTypeIndex = 0,
// };
// vkCreateBuffer(device, &buf_info, NULL, &vb_full);
// VkMemoryRequirements mem_reqs = {0};
// vkGetBufferMemoryRequirements(device, vb_full, &mem_reqs);
// mem_alloc.allocationSize = mem_reqs.size;
// mem_alloc.memoryTypeIndex = memory_type_from_properties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
// VkMemoryAllocateFlagsInfo memory_allocate_flags_info = {
// .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
// .flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR,
// };
// mem_alloc.pNext = &memory_allocate_flags_info;
// vkAllocateMemory(device, &mem_alloc, NULL, &vb_full_mem);
// vkBindBufferMemory(device, vb_full, vb_full_mem, 0);
// float *data;
// vkMapMemory(device, vb_full_mem, 0, vert_count * vb[0]->stride, 0, (void **)&data);
// vkUnmapMemory(device, vb_full_mem);
////
#ifdef is_forge
vb_full = _vb_full->impl.buf;
vb_full_mem = _vb_full->impl.mem;
#else
vb_full = vb[0]->impl.buf;
vb_full_mem = vb[0]->impl.mem;
#endif
}
{
// if (ib_full != NULL) {
// vkFreeMemory(device, ib_full_mem, NULL);
// vkDestroyBuffer(device, ib_full, NULL);
// }
// VkBufferCreateInfo buf_info = {
// .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
// .pNext = NULL,
// .size = prim_count * 3 * sizeof(uint32_t),
// .usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
// .usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
// .usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
// .usage |= VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
// .flags = 0,
// };
// VkMemoryAllocateInfo mem_alloc = {
// .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
// .pNext = NULL,
// .allocationSize = 0,
// .memoryTypeIndex = 0,
// };
// vkCreateBuffer(device, &buf_info, NULL, &ib_full);
// VkMemoryRequirements mem_reqs = {0};
// vkGetBufferMemoryRequirements(device, ib_full, &mem_reqs);
// mem_alloc.allocationSize = mem_reqs.size;
// mem_alloc.memoryTypeIndex = memory_type_from_properties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
// VkMemoryAllocateFlagsInfo memory_allocate_flags_info = {
// .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
// .flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR,
// };
// mem_alloc.pNext = &memory_allocate_flags_info;
// vkAllocateMemory(device, &mem_alloc, NULL, &ib_full_mem);
// vkBindBufferMemory(device, ib_full, ib_full_mem, 0);
// uint8_t *data;
// vkMapMemory(device, ib_full_mem, 0, mem_alloc.allocationSize, 0, (void **)&data);
// for (int i = 0; i < instances_count; ++i) {
// memcpy(data, ib[i]->impl., sizeof(VkAccelerationStructureInstanceKHR));
// }
// vkUnmapMemory(device, ib_full_mem);
////
#ifdef is_forge
ib_full = _ib_full->impl.buf;
ib_full_mem = _ib_full->impl.mem;
#else
ib_full = ib[0]->impl.buf;
ib_full_mem = ib[0]->impl.mem;
#endif
}
vb_full = gpu_raytrace_multi ? _vb_full->impl.buf : vb[0]->impl.buf;
ib_full = gpu_raytrace_multi ? _ib_full->impl.buf : ib[0]->impl.buf;
}
void gpu_raytrace_acceleration_structure_destroy(gpu_acceleration_structure_t *accel) {
+6 -4
View File
@@ -5,6 +5,8 @@
#include <stdint.h>
#include <vulkan/vulkan_core.h>
#define GPU_RAYTRACE_MAX_OBJECTS 64
typedef struct gpu_pipeline_impl {
VkPipeline pipeline;
VkPipelineLayout pipeline_layout;
@@ -33,12 +35,12 @@ typedef struct {
typedef struct {
VkAccelerationStructureKHR top_level_acceleration_structure;
VkAccelerationStructureKHR bottom_level_acceleration_structure[16];
VkAccelerationStructureKHR bottom_level_acceleration_structure[GPU_RAYTRACE_MAX_OBJECTS];
uint64_t top_level_acceleration_structure_handle;
uint64_t bottom_level_acceleration_structure_handle[16];
uint64_t bottom_level_acceleration_structure_handle[GPU_RAYTRACE_MAX_OBJECTS];
VkBuffer bottom_level_buffer[16];
VkDeviceMemory bottom_level_mem[16];
VkBuffer bottom_level_buffer[GPU_RAYTRACE_MAX_OBJECTS];
VkDeviceMemory bottom_level_mem[GPU_RAYTRACE_MAX_OBJECTS];
VkBuffer top_level_buffer;
VkDeviceMemory top_level_mem;
VkBuffer instances_buffer;