rt: draft a universal pass sketch
allows easily creating arbitrary ray tracing pipelines out of sets of bindings and shaders what's missing: - optimal handling of duplicate shaders - reading bindings from shaders (parse SPIR-V) instead of specifying in code - automatic resource creation according to binding definitions - automatic barriers according to bindings interface
This commit is contained in:
parent
e384f2e1f7
commit
b3c69851dc
|
@ -0,0 +1,177 @@
|
|||
#include "ray_pass.h"
|
||||
#include "vk_descriptor.h"
|
||||
#include "vk_ray_resources.h"
|
||||
#include "vk_ray_resources.h"
|
||||
|
||||
#define MAX_STAGES 16
|
||||
#define MAX_MISS_GROUPS 8
|
||||
#define MAX_HIT_GROUPS 8
|
||||
|
||||
typedef struct ray_pass_s {
|
||||
// TODO enum type
|
||||
|
||||
struct {
|
||||
vk_descriptors_t riptors;
|
||||
ray_pass_write_values_f write_values_func;
|
||||
VkDescriptorSet sets[1];
|
||||
} desc;
|
||||
|
||||
union {
|
||||
vk_pipeline_ray_t tracing;
|
||||
};
|
||||
} ray_pass_t;
|
||||
|
||||
#if 0 // TODO
|
||||
qboolean createLayout( const ray_pass_layout_t *layout, ray_pass_t *pass ){
|
||||
// TODO return false on fail instead of crashing
|
||||
{
|
||||
const VkDescriptorSetLayoutCreateInfo dslci = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.bindingCount = layout->bindings_count,
|
||||
.pBindings = layout->bindings,
|
||||
};
|
||||
XVK_CHECK(vkCreateDescriptorSetLayout(vk_core.device, &dslci, NULL, &pass->desc_set_layout));
|
||||
}
|
||||
|
||||
{
|
||||
const VkPipelineLayoutCreateInfo plci = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.setLayoutCount = 1,
|
||||
.pSetLayouts = &pass->desc_set_layout,
|
||||
.pushConstantRangeCount = layout->push_constants.size > 0 ? 1 : 0,
|
||||
.pPushConstantRanges = &layout->push_constants,
|
||||
};
|
||||
XVK_CHECK(vkCreatePipelineLayout(vk_core.device, &plci, NULL, &pass->pipeline_layout));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static ray_pass_t *createRayPass( const ray_pass_create_t *create ) {
|
||||
ray_pass_t *pass = Mem_Malloc(vk_core.pool, sizeof(*pass));
|
||||
|
||||
{
|
||||
pass->desc.riptors = (vk_descriptors_t) {
|
||||
.bindings = create->layout.bindings,
|
||||
.num_bindings = create->layout.bindings_count,
|
||||
.num_sets = COUNTOF(pass->desc.sets),
|
||||
.desc_sets = pass->desc.sets,
|
||||
.push_constants = create->layout.push_constants,
|
||||
};
|
||||
|
||||
VK_DescriptorsCreate(&pass->desc.riptors);
|
||||
}
|
||||
|
||||
{
|
||||
int stage_index = 0;
|
||||
vk_shader_stage_t stages[MAX_STAGES];
|
||||
int miss_index = 0;
|
||||
int misses[MAX_MISS_GROUPS];
|
||||
int hit_index = 0;
|
||||
vk_pipeline_ray_hit_group_t hits[MAX_HIT_GROUPS];
|
||||
|
||||
vk_pipeline_ray_create_info_t prci = {
|
||||
.debug_name = create->debug_name,
|
||||
.layout = pass->desc.riptors.pipeline_layout,
|
||||
.stages = stages,
|
||||
.groups = {
|
||||
.hit = hits,
|
||||
.miss = misses,
|
||||
},
|
||||
};
|
||||
|
||||
stages[stage_index++] = (vk_shader_stage_t) {
|
||||
.filename = create->tracing.raygen,
|
||||
.stage = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
|
||||
.specialization_info = create->tracing.specialization,
|
||||
};
|
||||
|
||||
for (int i = 0; i < create->tracing.miss_count; ++i) {
|
||||
const ray_pass_shader_t *const shader = create->tracing.miss + i;
|
||||
|
||||
ASSERT(stage_index < MAX_STAGES);
|
||||
ASSERT(miss_index < MAX_MISS_GROUPS);
|
||||
|
||||
// TODO handle duplicate filenames
|
||||
misses[miss_index++] = stage_index;
|
||||
stages[stage_index++] = (vk_shader_stage_t) {
|
||||
.filename = *shader,
|
||||
.stage = VK_SHADER_STAGE_MISS_BIT_KHR,
|
||||
.specialization_info = create->tracing.specialization,
|
||||
};
|
||||
}
|
||||
|
||||
for (int i = 0; i < create->tracing.hit_count; ++i) {
|
||||
const ray_pass_hit_group_t *const group = create->tracing.hit + i;
|
||||
|
||||
ASSERT(hit_index < MAX_HIT_GROUPS);
|
||||
|
||||
// TODO handle duplicate filenames
|
||||
if (group->any) {
|
||||
ASSERT(stage_index < MAX_STAGES);
|
||||
hits[hit_index].any = stage_index;
|
||||
stages[stage_index++] = (vk_shader_stage_t) {
|
||||
.filename = group->any,
|
||||
.stage = VK_SHADER_STAGE_ANY_HIT_BIT_KHR,
|
||||
.specialization_info = create->tracing.specialization,
|
||||
};
|
||||
} else {
|
||||
hits[hit_index].any = -1;
|
||||
}
|
||||
|
||||
if (group->closest) {
|
||||
ASSERT(stage_index < MAX_STAGES);
|
||||
hits[hit_index].closest = stage_index;
|
||||
stages[stage_index++] = (vk_shader_stage_t) {
|
||||
.filename = group->closest,
|
||||
.stage = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,
|
||||
.specialization_info = create->tracing.specialization,
|
||||
};
|
||||
} else {
|
||||
hits[hit_index].closest = -1;
|
||||
}
|
||||
|
||||
++hit_index;
|
||||
}
|
||||
|
||||
prci.groups.hit_count = hit_index;
|
||||
prci.groups.miss_count = miss_index;
|
||||
prci.stages_count = stage_index;
|
||||
|
||||
pass->tracing = VK_PipelineRayTracingCreate(&prci);
|
||||
}
|
||||
|
||||
if (pass->tracing.pipeline == VK_NULL_HANDLE) {
|
||||
VK_DescriptorsDestroy(&pass->desc.riptors);
|
||||
Mem_Free(pass);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pass->desc.riptors.values = Mem_Malloc(vk_core.pool, sizeof(pass->desc.riptors.values[0]) * create->layout.bindings_count);
|
||||
pass->desc.write_values_func = create->layout.write_values_func;
|
||||
ASSERT(create->layout.write_values_func);
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
struct ray_pass_s *RayPassCreate( const ray_pass_create_t *create ) {
|
||||
return createRayPass(create);
|
||||
}
|
||||
|
||||
void RayPassDestroy( struct ray_pass_s *pass ) {
|
||||
VK_PipelineRayTracingDestroy(&pass->tracing);
|
||||
VK_DescriptorsDestroy(&pass->desc.riptors);
|
||||
Mem_Free(pass->desc.riptors.values);
|
||||
Mem_Free(pass);
|
||||
}
|
||||
|
||||
|
||||
void RayPassPerform( VkCommandBuffer cmdbuf, struct ray_pass_s *pass, const struct vk_ray_resources_s *res) {
|
||||
pass->desc.write_values_func( pass->desc.riptors.values, res );
|
||||
VK_DescriptorsWrite(&pass->desc.riptors);
|
||||
|
||||
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pass->tracing.pipeline);
|
||||
vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pass->desc.riptors.pipeline_layout, 0, 1, pass->desc.riptors.desc_sets + 0, 0, NULL);
|
||||
VK_PipelineRayTracingTrace(cmdbuf, &pass->tracing, res->width, res->height);
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
#pragma once
|
||||
|
||||
#include "vk_core.h"
|
||||
#include "vk_pipeline.h"
|
||||
#include "vk_descriptor.h"
|
||||
|
||||
typedef const char* ray_pass_shader_t;
|
||||
|
||||
typedef struct {
|
||||
ray_pass_shader_t closest;
|
||||
ray_pass_shader_t any;
|
||||
} ray_pass_hit_group_t;
|
||||
|
||||
typedef struct {
|
||||
ray_pass_shader_t raygen;
|
||||
|
||||
const ray_pass_shader_t *miss;
|
||||
int miss_count;
|
||||
|
||||
const ray_pass_hit_group_t *hit;
|
||||
int hit_count;
|
||||
|
||||
const VkSpecializationInfo *specialization;
|
||||
} ray_pass_tracing_t;
|
||||
|
||||
// enum {
|
||||
// RVkRayPassType_Compute,
|
||||
// RVkRayPassType_Tracing,
|
||||
// };
|
||||
|
||||
|
||||
// TODO these should be like:
|
||||
// - parse the entire layout from shaders
|
||||
// - expose it as a struct[] interface of the pass
|
||||
// - resource/interface should prepare descriptors outside of pass code and just pass them to pass
|
||||
struct vk_ray_resources_s;
|
||||
typedef void (*ray_pass_write_values_f)( vk_descriptor_value_t *values, const struct vk_ray_resources_s *resources );
|
||||
|
||||
// TODO parse this out from shaders
|
||||
typedef struct {
|
||||
VkDescriptorSetLayoutBinding *bindings;
|
||||
int bindings_count;
|
||||
|
||||
VkPushConstantRange push_constants;
|
||||
|
||||
ray_pass_write_values_f write_values_func;
|
||||
} ray_pass_layout_t;
|
||||
|
||||
typedef struct {
|
||||
// TODO enum type
|
||||
|
||||
const char *debug_name;
|
||||
ray_pass_layout_t layout;
|
||||
|
||||
union {
|
||||
ray_pass_tracing_t tracing;
|
||||
};
|
||||
} ray_pass_create_t;
|
||||
|
||||
struct ray_pass_s;
|
||||
struct ray_pass_s *RayPassCreate( const ray_pass_create_t *create );
|
||||
void RayPassDestroy( struct ray_pass_s *pass );
|
||||
|
||||
struct vk_ray_resources_s;
|
||||
void RayPassPerform( VkCommandBuffer cmdbuf, struct ray_pass_s *pass, const struct vk_ray_resources_s *res);
|
|
@ -1,10 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "vk_core.h"
|
||||
#include "vk_buffer.h"
|
||||
|
||||
typedef struct {
|
||||
const char *filename;
|
||||
VkShaderStageFlagBits stage;
|
||||
VkSpecializationInfo *specialization_info;
|
||||
const VkSpecializationInfo *specialization_info;
|
||||
} vk_shader_stage_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
#include "vk_ray_internal.h"
|
||||
|
||||
#include "vk_descriptor.h"
|
||||
#include "vk_pipeline.h"
|
||||
#include "vk_buffer.h"
|
||||
|
||||
#include "eiface.h" // ARRAYSIZE
|
||||
#include "vk_ray_resources.h"
|
||||
#include "ray_pass.h"
|
||||
|
||||
enum {
|
||||
// TODO set 0
|
||||
|
@ -24,35 +22,11 @@ RAY_PRIMARY_OUTPUTS(X)
|
|||
RtPrim_Desc_COUNT
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct {
|
||||
vk_descriptors_t riptors;
|
||||
VkDescriptorSetLayoutBinding bindings[RtPrim_Desc_COUNT];
|
||||
vk_descriptor_value_t values[RtPrim_Desc_COUNT];
|
||||
|
||||
// TODO: split into two sets, one common to all rt passes (tlas, kusochki, etc), another one this pass only
|
||||
VkDescriptorSet sets[1];
|
||||
} desc;
|
||||
|
||||
vk_pipeline_ray_t pipeline;
|
||||
} g_ray_primary;
|
||||
static VkDescriptorSetLayoutBinding bindings[RtPrim_Desc_COUNT];
|
||||
|
||||
static void initDescriptors( void ) {
|
||||
g_ray_primary.desc.riptors = (vk_descriptors_t) {
|
||||
.bindings = g_ray_primary.desc.bindings,
|
||||
.num_bindings = ARRAYSIZE(g_ray_primary.desc.bindings),
|
||||
.values = g_ray_primary.desc.values,
|
||||
.num_sets = ARRAYSIZE(g_ray_primary.desc.sets),
|
||||
.desc_sets = g_ray_primary.desc.sets,
|
||||
/* .push_constants = (VkPushConstantRange){ */
|
||||
/* .offset = 0, */
|
||||
/* .size = sizeof(vk_rtx_push_constants_t), */
|
||||
/* .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR, */
|
||||
/* }, */
|
||||
};
|
||||
|
||||
#define INIT_BINDING(index, name, type, count, stages) \
|
||||
g_ray_primary.desc.bindings[RtPrim_Desc_##name] = (VkDescriptorSetLayoutBinding){ \
|
||||
bindings[RtPrim_Desc_##name] = (VkDescriptorSetLayoutBinding){ \
|
||||
.binding = index, \
|
||||
.descriptorType = type, \
|
||||
.descriptorCount = count, \
|
||||
|
@ -71,13 +45,11 @@ static void initDescriptors( void ) {
|
|||
RAY_PRIMARY_OUTPUTS(X)
|
||||
#undef X
|
||||
#undef INIT_BINDING
|
||||
|
||||
VK_DescriptorsCreate(&g_ray_primary.desc.riptors);
|
||||
}
|
||||
|
||||
static void updateDescriptors( const vk_ray_resources_t* res ) {
|
||||
static void writeValues( vk_descriptor_value_t *values, const vk_ray_resources_t* res ) {
|
||||
#define X(index, name, ...) \
|
||||
g_ray_primary.desc.values[RtPrim_Desc_Out_##name].image = (VkDescriptorImageInfo){ \
|
||||
values[RtPrim_Desc_Out_##name].image = (VkDescriptorImageInfo){ \
|
||||
.sampler = VK_NULL_HANDLE, \
|
||||
.imageView = res->name, \
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL, \
|
||||
|
@ -85,14 +57,14 @@ static void updateDescriptors( const vk_ray_resources_t* res ) {
|
|||
RAY_PRIMARY_OUTPUTS(X)
|
||||
#undef X
|
||||
|
||||
g_ray_primary.desc.values[RtPrim_Desc_TLAS].accel = (VkWriteDescriptorSetAccelerationStructureKHR){
|
||||
values[RtPrim_Desc_TLAS].accel = (VkWriteDescriptorSetAccelerationStructureKHR){
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
|
||||
.accelerationStructureCount = 1,
|
||||
.pAccelerationStructures = &res->scene.tlas,
|
||||
};
|
||||
|
||||
#define DESC_SET_BUFFER(index, buffer_) \
|
||||
g_ray_primary.desc.values[index].buffer = (VkDescriptorBufferInfo){ \
|
||||
values[index].buffer = (VkDescriptorBufferInfo){ \
|
||||
.buffer = res->scene.buffer_.buffer, \
|
||||
.offset = res->scene.buffer_.offset, \
|
||||
.range = res->scene.buffer_.size, \
|
||||
|
@ -105,13 +77,11 @@ RAY_PRIMARY_OUTPUTS(X)
|
|||
|
||||
#undef DESC_SET_BUFFER
|
||||
|
||||
g_ray_primary.desc.values[RtPrim_Desc_Textures].image_array = res->scene.all_textures;
|
||||
|
||||
VK_DescriptorsWrite(&g_ray_primary.desc.riptors);
|
||||
values[RtPrim_Desc_Textures].image_array = res->scene.all_textures;
|
||||
}
|
||||
|
||||
static vk_pipeline_ray_t createPipeline( void ) {
|
||||
// FIXME move this into vk_pipeline
|
||||
struct ray_pass_s *R_VkRayPrimaryPassCreate( void ) {
|
||||
// FIXME move this into vk_pipeline or something
|
||||
const struct SpecializationData {
|
||||
uint32_t sbt_record_size;
|
||||
} spec_data = {
|
||||
|
@ -120,94 +90,44 @@ static vk_pipeline_ray_t createPipeline( void ) {
|
|||
const VkSpecializationMapEntry spec_map[] = {
|
||||
{.constantID = SPEC_SBT_RECORD_SIZE_INDEX, .offset = offsetof(struct SpecializationData, sbt_record_size), .size = sizeof(uint32_t) },
|
||||
};
|
||||
VkSpecializationInfo spec = {
|
||||
const VkSpecializationInfo spec = {
|
||||
.mapEntryCount = COUNTOF(spec_map),
|
||||
.pMapEntries = spec_map,
|
||||
.dataSize = sizeof(spec_data),
|
||||
.pData = &spec_data,
|
||||
};
|
||||
|
||||
#define LIST_SHADER_MODULES(X) \
|
||||
X(RayGen, "ray_primary.rgen", RAYGEN) \
|
||||
X(Miss, "ray_primary.rmiss", MISS) \
|
||||
X(HitClosest, "ray_primary.rchit", CLOSEST_HIT) \
|
||||
X(HitAnyAlphaTest, "ray_common_alphatest.rahit", ANY_HIT) \
|
||||
|
||||
enum {
|
||||
#define X(name, file, type) \
|
||||
ShaderStageIndex_##name,
|
||||
LIST_SHADER_MODULES(X)
|
||||
#undef X
|
||||
const ray_pass_shader_t miss[] = {
|
||||
"ray_primary.rmiss.spv"
|
||||
};
|
||||
|
||||
const vk_shader_stage_t stages[] = {
|
||||
#define X(name, file, type) \
|
||||
{.filename = file ".spv", .stage = VK_SHADER_STAGE_##type##_BIT_KHR, .specialization_info = &spec},
|
||||
LIST_SHADER_MODULES(X)
|
||||
#undef X
|
||||
};
|
||||
|
||||
const int misses[] = {
|
||||
ShaderStageIndex_Miss,
|
||||
};
|
||||
|
||||
const vk_pipeline_ray_hit_group_t hits[] = {
|
||||
// TODO rigidly specify the expected sbt structure w/ offsets and materials
|
||||
{ // 0: fully opaque: no need for closest nor any hits
|
||||
.closest = ShaderStageIndex_HitClosest,
|
||||
.any = -1,
|
||||
},
|
||||
{ // 1: materials w/ alpha mask: need alpha test
|
||||
.closest = ShaderStageIndex_HitClosest,
|
||||
.any = ShaderStageIndex_HitAnyAlphaTest, // TODO these can directly be a string
|
||||
const ray_pass_hit_group_t hit[] = { {
|
||||
.closest = "ray_primary.rchit.spv",
|
||||
.any = NULL,
|
||||
}, {
|
||||
.closest = "ray_primary.rchit.spv",
|
||||
.any = "ray_common_alphatest.rahit.spv",
|
||||
},
|
||||
};
|
||||
|
||||
const vk_pipeline_ray_create_info_t prtc = {
|
||||
const ray_pass_create_t rpc = {
|
||||
.debug_name = "primary ray",
|
||||
.stages = stages,
|
||||
.stages_count = COUNTOF(stages),
|
||||
.groups = {
|
||||
.miss = misses,
|
||||
.miss_count = COUNTOF(misses),
|
||||
.hit = hits,
|
||||
.hit_count = COUNTOF(hits),
|
||||
.layout = {
|
||||
.bindings = bindings,
|
||||
.bindings_count = COUNTOF(bindings),
|
||||
.write_values_func = writeValues,
|
||||
.push_constants = {0},
|
||||
},
|
||||
.tracing = {
|
||||
.raygen = "ray_primary.rgen.spv",
|
||||
.miss = miss,
|
||||
.miss_count = COUNTOF(miss),
|
||||
.hit = hit,
|
||||
.hit_count = COUNTOF(hit),
|
||||
.specialization = &spec,
|
||||
},
|
||||
.layout = g_ray_primary.desc.riptors.pipeline_layout,
|
||||
};
|
||||
|
||||
return VK_PipelineRayTracingCreate(&prtc);
|
||||
}
|
||||
|
||||
qboolean XVK_RayTracePrimaryInit( void ) {
|
||||
initDescriptors();
|
||||
|
||||
g_ray_primary.pipeline = createPipeline();
|
||||
ASSERT(g_ray_primary.pipeline.pipeline != VK_NULL_HANDLE);
|
||||
|
||||
return true;
|
||||
return RayPassCreate( &rpc );
|
||||
}
|
||||
|
||||
void XVK_RayTracePrimaryDestroy( void ) {
|
||||
VK_PipelineRayTracingDestroy(&g_ray_primary.pipeline);
|
||||
VK_DescriptorsDestroy(&g_ray_primary.desc.riptors);
|
||||
}
|
||||
|
||||
void XVK_RayTracePrimaryReloadPipeline( void ) {
|
||||
const vk_pipeline_ray_t new_pipeline = createPipeline();
|
||||
if (new_pipeline.pipeline == VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
VK_PipelineRayTracingDestroy(&g_ray_primary.pipeline);
|
||||
|
||||
g_ray_primary.pipeline = new_pipeline;
|
||||
}
|
||||
|
||||
void XVK_RayTracePrimary( VkCommandBuffer cmdbuf, const vk_ray_resources_t *res ) {
|
||||
updateDescriptors( res );
|
||||
|
||||
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, g_ray_primary.pipeline.pipeline);
|
||||
vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, g_ray_primary.desc.riptors.pipeline_layout, 0, 1, g_ray_primary.desc.riptors.desc_sets + 0, 0, NULL);
|
||||
VK_PipelineRayTracingTrace(cmdbuf, &g_ray_primary.pipeline, res->width, res->height);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
#include "vk_ray_resources.h"
|
||||
|
||||
qboolean XVK_RayTracePrimaryInit( void );
|
||||
void XVK_RayTracePrimaryDestroy( void );
|
||||
void XVK_RayTracePrimaryReloadPipeline( void );
|
||||
|
||||
void XVK_RayTracePrimary( VkCommandBuffer cmdbuf, const vk_ray_resources_t *res );
|
||||
struct ray_pass_s *R_VkRayPrimaryPassCreate( void );
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "vk_const.h"
|
||||
#include "shaders/ray_interop.h"
|
||||
|
||||
typedef struct {
|
||||
typedef struct vk_ray_resources_s {
|
||||
uint32_t width, height;
|
||||
|
||||
struct {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "vk_rtx.h"
|
||||
|
||||
#include "ray_pass.h"
|
||||
#include "vk_ray_primary.h"
|
||||
#include "vk_ray_light_direct.h"
|
||||
|
||||
|
@ -162,6 +163,10 @@ static struct {
|
|||
unsigned frame_number;
|
||||
xvk_ray_frame_images_t frames[MAX_FRAMES_IN_FLIGHT];
|
||||
|
||||
struct {
|
||||
struct ray_pass_s *primary_ray;
|
||||
} pass;
|
||||
|
||||
qboolean reload_pipeline;
|
||||
qboolean reload_lighting;
|
||||
} g_rtx = {0};
|
||||
|
@ -1075,7 +1080,7 @@ static void performTracing( VkCommandBuffer cmdbuf, const vk_ray_frame_render_ar
|
|||
0, 0, NULL, ARRAYSIZE(bmb), bmb, ARRAYSIZE(image_barrier), image_barrier);
|
||||
}
|
||||
|
||||
XVK_RayTracePrimary( cmdbuf, &res );
|
||||
RayPassPerform( cmdbuf, g_rtx.pass.primary_ray, &res );
|
||||
|
||||
{
|
||||
const VkImageMemoryBarrier image_barriers[] = {
|
||||
|
@ -1158,7 +1163,14 @@ void VK_RayFrameEnd(const vk_ray_frame_render_args_t* args)
|
|||
//vkDestroyPipeline(vk_core.device, g_rtx.pipeline, NULL);
|
||||
createPipeline();
|
||||
|
||||
XVK_RayTracePrimaryReloadPipeline();
|
||||
{
|
||||
struct ray_pass_s *new_primary_pass = R_VkRayPrimaryPassCreate();
|
||||
if (new_primary_pass) {
|
||||
RayPassDestroy(g_rtx.pass.primary_ray);
|
||||
g_rtx.pass.primary_ray = new_primary_pass;
|
||||
}
|
||||
}
|
||||
|
||||
XVK_RayTraceLightDirectReloadPipeline();
|
||||
XVK_DenoiserReloadPipeline();
|
||||
g_rtx.reload_pipeline = false;
|
||||
|
@ -1329,7 +1341,9 @@ qboolean VK_RayInit( void )
|
|||
ASSERT(vk_core.rtx);
|
||||
// TODO complain and cleanup on failure
|
||||
|
||||
ASSERT(XVK_RayTracePrimaryInit());
|
||||
g_rtx.pass.primary_ray = R_VkRayPrimaryPassCreate();
|
||||
|
||||
ASSERT(g_rtx.pass.primary_ray);
|
||||
ASSERT(XVK_RayTraceLightDirectInit());
|
||||
|
||||
g_rtx.sbt_record_size = vk_core.physical_device.sbt_record_size;
|
||||
|
@ -1451,7 +1465,7 @@ void VK_RayShutdown( void ) {
|
|||
ASSERT(vk_core.rtx);
|
||||
|
||||
XVK_RayTraceLightDirectDestroy();
|
||||
XVK_RayTracePrimaryDestroy();
|
||||
RayPassDestroy(g_rtx.pass.primary_ray);
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(g_rtx.frames); ++i) {
|
||||
XVK_ImageDestroy(&g_rtx.frames[i].denoised);
|
||||
|
|
Loading…
Reference in New Issue