rt: passify light direct poly

This commit is contained in:
Ivan Avdeev 2022-01-27 17:47:00 -08:00
parent b3c69851dc
commit c3a7a01620
5 changed files with 50 additions and 135 deletions

View File

@ -94,6 +94,7 @@ static ray_pass_t *createRayPass( const ray_pass_create_t *create ) {
ASSERT(miss_index < MAX_MISS_GROUPS);
// TODO handle duplicate filenames
// TODO really, there should be a global table of shader modules as some of them are used across several passes (e.g. any hit alpha test)
misses[miss_index++] = stage_index;
stages[stage_index++] = (vk_shader_stage_t) {
.filename = *shader,

View File

@ -1,11 +1,7 @@
#include "vk_ray_light_direct.h"
#include "vk_ray_internal.h"
#include "vk_descriptor.h"
#include "vk_pipeline.h"
#include "vk_buffer.h"
#include "shaders/ray_interop.h"
#include "vk_ray_resources.h"
#include "ray_pass.h"
enum {
// TODO set 0 ?
@ -31,41 +27,12 @@ enum {
RtLDir_Desc_COUNT
};
#define LIST_SHADER_MODULES(X) \
X(RayGen, "ray_light_poly_direct.rgen", RAYGEN) \
X(AlphaTest, "ray_common_alphatest.rahit", ANY_HIT) \
X(Miss, "ray_shadow.rmiss", MISS) \
static struct {
struct {
vk_descriptors_t riptors;
VkDescriptorSetLayoutBinding bindings[RtLDir_Desc_COUNT];
vk_descriptor_value_t values[RtLDir_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_light_direct;
static VkDescriptorSetLayoutBinding bindings[RtLDir_Desc_COUNT];
static void initDescriptors( void ) {
g_ray_light_direct.desc.riptors = (vk_descriptors_t) {
.bindings = g_ray_light_direct.desc.bindings,
.num_bindings = COUNTOF(g_ray_light_direct.desc.bindings),
.values = g_ray_light_direct.desc.values,
.num_sets = COUNTOF(g_ray_light_direct.desc.sets),
.desc_sets = g_ray_light_direct.desc.sets,
/* .push_constants = (VkPushConstantRange){ */
/* .offset = 0, */
/* .size = sizeof(vk_rtx_push_constants_t), */
/* .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, */
/* }, */
};
// FIXME more conservative shader stages
#define INIT_BINDING(index, name, type, count) \
g_ray_light_direct.desc.bindings[RtLDir_Desc_##name] = (VkDescriptorSetLayoutBinding){ \
bindings[RtLDir_Desc_##name] = (VkDescriptorSetLayoutBinding){ \
.binding = index, \
.descriptorType = type, \
.descriptorCount = count, \
@ -89,13 +56,11 @@ static void initDescriptors( void ) {
RAY_LIGHT_DIRECT_OUTPUTS(X)
#undef X
#undef INIT_BINDING
VK_DescriptorsCreate(&g_ray_light_direct.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_light_direct.desc.values[RtLDir_Desc_##name].image = (VkDescriptorImageInfo){ \
values[RtLDir_Desc_##name].image = (VkDescriptorImageInfo){ \
.sampler = VK_NULL_HANDLE, \
.imageView = res->name, \
.imageLayout = VK_IMAGE_LAYOUT_GENERAL, \
@ -104,7 +69,7 @@ static void updateDescriptors( const vk_ray_resources_t *res ) {
#undef X
#define X(index, name, ...) \
g_ray_light_direct.desc.values[RtLDir_Desc_##name].image = (VkDescriptorImageInfo){ \
values[RtLDir_Desc_##name].image = (VkDescriptorImageInfo){ \
.sampler = VK_NULL_HANDLE, \
.imageView = res->name, \
.imageLayout = VK_IMAGE_LAYOUT_GENERAL, \
@ -112,14 +77,14 @@ static void updateDescriptors( const vk_ray_resources_t *res ) {
RAY_LIGHT_DIRECT_OUTPUTS(X)
#undef X
g_ray_light_direct.desc.values[RtLDir_Desc_TLAS].accel = (VkWriteDescriptorSetAccelerationStructureKHR){
values[RtLDir_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_light_direct.desc.values[index].buffer = (VkDescriptorBufferInfo){ \
values[index].buffer = (VkDescriptorBufferInfo){ \
.buffer = res->scene.buffer_.buffer, \
.offset = res->scene.buffer_.offset, \
.range = res->scene.buffer_.size, \
@ -134,12 +99,10 @@ static void updateDescriptors( const vk_ray_resources_t *res ) {
#undef DESC_SET_BUFFER
g_ray_light_direct.desc.values[RtLDir_Desc_Textures].image_array = res->scene.all_textures;
VK_DescriptorsWrite(&g_ray_light_direct.desc.riptors);
values[RtLDir_Desc_Textures].image_array = res->scene.all_textures;
}
static vk_pipeline_ray_t createPipeline( void ) {
struct ray_pass_s *R_VkRayLightDirectPolyPassCreate( void ) {
// FIXME move this into vk_pipeline
const struct SpecializationData {
uint32_t sbt_record_size;
@ -156,80 +119,34 @@ static vk_pipeline_ray_t createPipeline( void ) {
.pData = &spec_data,
};
enum {
#define X(name, file, type) \
ShaderStageIndex_##name,
LIST_SHADER_MODULES(X)
#undef X
};
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 ray_pass_shader_t miss[] = {
"ray_shadow.rmiss.spv"
};
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 = -1,
.any = -1,
},
{ // 1: materials w/ alpha mask: need alpha test
.closest = -1,
.any = ShaderStageIndex_AlphaTest, // TODO these can directly be a string
const ray_pass_hit_group_t hit[] = { {
.closest = NULL,
.any = "ray_common_alphatest.rahit.spv",
},
};
const vk_pipeline_ray_create_info_t prtc = {
.debug_name = "light direct",
.stages = stages,
.stages_count = COUNTOF(stages),
.groups = {
.miss = misses,
.miss_count = COUNTOF(misses),
.hit = hits,
.hit_count = COUNTOF(hits),
const ray_pass_create_t rpc = {
.debug_name = "light direct poly",
.layout = {
.bindings = bindings,
.bindings_count = COUNTOF(bindings),
.write_values_func = writeValues,
.push_constants = {0},
},
.tracing = {
.raygen = "ray_light_poly_direct.rgen.spv",
.miss = miss,
.miss_count = COUNTOF(miss),
.hit = hit,
.hit_count = COUNTOF(hit),
.specialization = &spec,
},
.layout = g_ray_light_direct.desc.riptors.pipeline_layout,
};
return VK_PipelineRayTracingCreate(&prtc);
}
qboolean XVK_RayTraceLightDirectInit( void ) {
initDescriptors();
g_ray_light_direct.pipeline = createPipeline();
ASSERT(g_ray_light_direct.pipeline.pipeline != VK_NULL_HANDLE);
return true;
return RayPassCreate( &rpc );
}
void XVK_RayTraceLightDirectDestroy( void ) {
VK_PipelineRayTracingDestroy(&g_ray_light_direct.pipeline);
VK_DescriptorsDestroy(&g_ray_light_direct.desc.riptors);
}
void XVK_RayTraceLightDirectReloadPipeline( void ) {
const vk_pipeline_ray_t new_pipeline = createPipeline();
if (new_pipeline.pipeline == VK_NULL_HANDLE)
return;
VK_PipelineRayTracingDestroy(&g_ray_light_direct.pipeline);
g_ray_light_direct.pipeline = new_pipeline;
}
void XVK_RayTraceLightDirect( VkCommandBuffer cmdbuf, const vk_ray_resources_t *res ) {
updateDescriptors( res );
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, g_ray_light_direct.pipeline.pipeline);
vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, g_ray_light_direct.desc.riptors.pipeline_layout, 0, 1, g_ray_light_direct.desc.riptors.desc_sets + 0, 0, NULL);
VK_PipelineRayTracingTrace(cmdbuf, &g_ray_light_direct.pipeline, res->width, res->height);
}

View File

@ -1,8 +1,3 @@
#pragma once
#include "vk_ray_resources.h"
qboolean XVK_RayTraceLightDirectInit( void );
void XVK_RayTraceLightDirectDestroy( void );
void XVK_RayTraceLightDirectReloadPipeline( void );
void XVK_RayTraceLightDirect( VkCommandBuffer cmdbuf, const vk_ray_resources_t *res );
struct ray_pass_s *R_VkRayLightDirectPolyPassCreate( void );

View File

@ -1,7 +1,5 @@
#include "vk_ray_primary.h"
#include "vk_ray_internal.h"
#include "vk_descriptor.h"
#include "vk_ray_resources.h"
#include "ray_pass.h"

View File

@ -165,6 +165,7 @@ static struct {
struct {
struct ray_pass_s *primary_ray;
struct ray_pass_s *light_direct_poly;
} pass;
qboolean reload_pipeline;
@ -1095,7 +1096,7 @@ static void performTracing( VkCommandBuffer cmdbuf, const vk_ray_frame_render_ar
0, 0, NULL, 0, NULL, ARRAYSIZE(image_barriers), image_barriers);
}
XVK_RayTraceLightDirect( cmdbuf, &res );
RayPassPerform( cmdbuf, g_rtx.pass.light_direct_poly, &res );
{
const VkImageMemoryBarrier image_barriers[] = {
@ -1140,6 +1141,14 @@ static void performTracing( VkCommandBuffer cmdbuf, const vk_ray_frame_render_ar
qboolean initVk2d(void);
void deinitVk2d(void);
static void reloadPass( struct ray_pass_s **slot, struct ray_pass_s *new_pass ) {
if (!new_pass)
return;
RayPassDestroy( *slot );
*slot = new_pass;
}
void VK_RayFrameEnd(const vk_ray_frame_render_args_t* args)
{
const VkCommandBuffer cmdbuf = args->cmdbuf;
@ -1163,15 +1172,9 @@ void VK_RayFrameEnd(const vk_ray_frame_render_args_t* args)
//vkDestroyPipeline(vk_core.device, g_rtx.pipeline, NULL);
createPipeline();
{
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;
}
}
reloadPass( &g_rtx.pass.primary_ray, R_VkRayPrimaryPassCreate());
reloadPass( &g_rtx.pass.light_direct_poly, R_VkRayLightDirectPolyPassCreate());
XVK_RayTraceLightDirectReloadPipeline();
XVK_DenoiserReloadPipeline();
g_rtx.reload_pipeline = false;
}
@ -1342,9 +1345,10 @@ qboolean VK_RayInit( void )
// TODO complain and cleanup on failure
g_rtx.pass.primary_ray = R_VkRayPrimaryPassCreate();
ASSERT(g_rtx.pass.primary_ray);
ASSERT(XVK_RayTraceLightDirectInit());
g_rtx.pass.light_direct_poly = R_VkRayLightDirectPolyPassCreate();
ASSERT(g_rtx.pass.light_direct_poly);
g_rtx.sbt_record_size = vk_core.physical_device.sbt_record_size;
g_rtx.uniform_unit_size = ALIGN_UP(sizeof(struct UniformBuffer), vk_core.physical_device.properties.limits.minUniformBufferOffsetAlignment);
@ -1464,7 +1468,7 @@ RAY_LIGHT_DIRECT_OUTPUTS(X)
void VK_RayShutdown( void ) {
ASSERT(vk_core.rtx);
XVK_RayTraceLightDirectDestroy();
RayPassDestroy(g_rtx.pass.light_direct_poly);
RayPassDestroy(g_rtx.pass.primary_ray);
for (int i = 0; i < ARRAYSIZE(g_rtx.frames); ++i) {