rt: start splitting tracer into passes; add primary pass stub

renders only uv gradient as a test

empty rgen, 6900xt: 12.3us, 6/16 vgpr, 20/128 sgpr, 16/16 occupancy
This commit is contained in:
Ivan Avdeev 2022-01-07 18:51:59 -08:00
parent 9adf9e1779
commit cd47861d9b
11 changed files with 432 additions and 130 deletions

View File

@ -68,7 +68,7 @@ void main() {
const float material_index = imageLoad(src_diffuse_gi, pix).a;
//imageStore(dest, pix, vec4(aces_tonemap(base_color.rgb), 0.)); return;
//imageStore(dest, pix, vec4((base_color.rgb), 0.)); return;
imageStore(dest, pix, vec4((base_color.rgb), 0.)); return;
//imageStore(dest, pix, vec4((imageLoad(src_diffuse_gi, pix).rgb), 0.)); return;
//imageStore(dest, pix, vec4(aces_tonemap(imageLoad(src_diffuse_gi, pix).rgb), 0.)); return;
//imageStore(dest, pix, vec4(aces_tonemap(imageLoad(src_specular, pix).rgb), 0.)); return;

View File

@ -0,0 +1,4 @@
#version 460 core
#extension GL_EXT_ray_tracing: require
void main() {}

View File

@ -0,0 +1,12 @@
#version 460 core
#extension GL_EXT_ray_tracing: require
layout(set = 0, binding = 0, rgba8) uniform image2D out_image_base_color_r;
void main() {
vec2 uv = (gl_LaunchIDEXT.xy + .5) / gl_LaunchSizeEXT.xy * 2. - 1.;
vec4 out_base_color_r = vec4(uv, 0., 0.);
imageStore(out_image_base_color_r, ivec2(gl_LaunchIDEXT.xy), out_base_color_r);
}

View File

@ -0,0 +1,4 @@
#version 460 core
#extension GL_EXT_ray_tracing: require
void main() {}

View File

@ -92,3 +92,8 @@ void VK_RingBuffer_ClearFrame(vk_ring_buffer_t* buf) {
buf->offset_free = buf->permanent_size;
buf->free = buf->size - buf->permanent_size;
}
VkDeviceAddress XVK_BufferGetDeviceAddress(VkBuffer buffer) {
const VkBufferDeviceAddressInfo bdai = {.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, .buffer = buffer};
return vkGetBufferDeviceAddress(vk_core.device, &bdai);
}

View File

@ -4,6 +4,8 @@
qboolean createBuffer(const char *debug_name, vk_buffer_t *buf, uint32_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlags flags);
void destroyBuffer(vk_buffer_t *buf);
VkDeviceAddress XVK_BufferGetDeviceAddress(VkBuffer buffer);
// v -- begin of ring buffer|permanent_size
// |XXXMAPLIFETME|<......|FRAME1|FRAME2|FRAMEN|......................>|

View File

@ -598,6 +598,11 @@ static qboolean createDevice( void ) {
vk_core.physical_device.properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
vkGetPhysicalDeviceProperties2(vk_core.physical_device.device, &vk_core.physical_device.properties2);
if (vk_core.rtx) {
//g_rtx.sbt_record_size = ALIGN_UP(vk_core.physical_device.properties_ray_tracing_pipeline.shaderGroupHandleSize, vk_core.physical_device.properties_ray_tracing_pipeline.shaderGroupHandleAlignment);
vk_core.physical_device.sbt_record_size = ALIGN_UP(vk_core.physical_device.properties_ray_tracing_pipeline.shaderGroupHandleSize, vk_core.physical_device.properties_ray_tracing_pipeline.shaderGroupBaseAlignment);
}
vkGetDeviceQueue(vk_core.device, 0, 0, &vk_core.queue);
return true;
}

View File

@ -45,6 +45,7 @@ typedef struct physical_device_s {
VkPhysicalDeviceAccelerationStructurePropertiesKHR properties_accel;
VkPhysicalDeviceRayTracingPipelinePropertiesKHR properties_ray_tracing_pipeline;
qboolean anisotropy_enabled;
uint32_t sbt_record_size;
} physical_device_t;
typedef struct vulkan_core_s {

223
ref_vk/vk_ray_primary.c Normal file
View File

@ -0,0 +1,223 @@
#include "vk_ray_primary.h"
#include "vk_descriptor.h"
#include "vk_pipeline.h"
#include "vk_buffer.h"
#include "eiface.h" // ARRAYSIZE
enum {
RtPrim_SBT_RayGen,
RtPrim_SBT_RayMiss,
RtPrim_SBT_RayHit,
RtPrim_SBT_COUNT,
};
enum {
RtPrim_Desc_Out_BaseColorR,
RtPrim_Desc_COUNT
};
static struct {
struct {
vk_descriptors_t riptors;
VkDescriptorSetLayoutBinding bindings[RtPrim_Desc_COUNT];
vk_descriptor_value_t values[RtPrim_Desc_COUNT];
VkDescriptorSet sets[1];
} desc;
vk_buffer_t sbt_buffer;
VkPipeline pipeline;
} g_ray_primary;
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, type, count, stages) \
g_ray_primary.desc.bindings[index] = (VkDescriptorSetLayoutBinding){ \
.binding = index, \
.descriptorType = type, \
.descriptorCount = count, \
.stageFlags = stages, \
}
INIT_BINDING(RtPrim_Desc_Out_BaseColorR, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR);
VK_DescriptorsCreate(&g_ray_primary.desc.riptors);
}
static void initPipeline( void ) {
enum {
ShaderStageIndex_RayGen,
ShaderStageIndex_RayMiss,
ShaderStageIndex_RayClosestHit,
ShaderStageIndex_COUNT,
};
VkPipelineShaderStageCreateInfo shaders[ShaderStageIndex_COUNT];
VkRayTracingShaderGroupCreateInfoKHR shader_groups[RtPrim_SBT_COUNT];
const VkRayTracingPipelineCreateInfoKHR rtpci = {
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR,
//TODO .flags = VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR ....
.stageCount = ARRAYSIZE(shaders),
.pStages = shaders,
.groupCount = ARRAYSIZE(shader_groups),
.pGroups = shader_groups,
.maxPipelineRayRecursionDepth = 1,
.layout = g_ray_primary.desc.riptors.pipeline_layout,
};
#define DEFINE_SHADER(filename, bit, sbt_index) \
shaders[sbt_index] = (VkPipelineShaderStageCreateInfo){ \
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, \
.stage = VK_SHADER_STAGE_##bit##_BIT_KHR, \
.module = loadShader(filename ".spv"), \
.pName = "main", \
.pSpecializationInfo = NULL, \
}
DEFINE_SHADER("ray_primary.rgen", RAYGEN, ShaderStageIndex_RayGen);
DEFINE_SHADER("ray_primary.rchit", CLOSEST_HIT, ShaderStageIndex_RayClosestHit);
DEFINE_SHADER("ray_primary.rmiss", MISS, ShaderStageIndex_RayMiss);
// TODO static assert
/* #define ASSERT_SHADER_OFFSET(sbt_kind, sbt_index, offset) \ */
/* ASSERT((offset) == (sbt_index - sbt_kind)) */
/* */
/* ASSERT_SHADER_OFFSET(ShaderBindingTable_RayGen, ShaderBindingTable_RayGen, 0); */
/* ASSERT_SHADER_OFFSET(ShaderBindingTable_Miss, ShaderBindingTable_Miss, SHADER_OFFSET_MISS_REGULAR); */
/* ASSERT_SHADER_OFFSET(ShaderBindingTable_Miss, ShaderBindingTable_Miss_Shadow, SHADER_OFFSET_MISS_SHADOW); */
/* */
/* ASSERT_SHADER_OFFSET(ShaderBindingTable_Hit_Base, ShaderBindingTable_Hit_Base, SHADER_OFFSET_HIT_REGULAR_BASE + SHADER_OFFSET_HIT_REGULAR); */
/* ASSERT_SHADER_OFFSET(ShaderBindingTable_Hit_Base, ShaderBindingTable_Hit_WithAlphaTest, SHADER_OFFSET_HIT_REGULAR_BASE + SHADER_OFFSET_HIT_ALPHA_TEST); */
/* ASSERT_SHADER_OFFSET(ShaderBindingTable_Hit_Base, ShaderBindingTable_Hit_Additive, SHADER_OFFSET_HIT_REGULAR_BASE + SHADER_OFFSET_HIT_ADDITIVE); */
/* */
/* ASSERT_SHADER_OFFSET(ShaderBindingTable_Hit_Base, ShaderBindingTable_Hit_Shadow_Base, SHADER_OFFSET_HIT_SHADOW_BASE + 0); */
/* ASSERT_SHADER_OFFSET(ShaderBindingTable_Hit_Base, ShaderBindingTable_Hit_Shadow_AlphaTest, SHADER_OFFSET_HIT_SHADOW_BASE + SHADER_OFFSET_HIT_ALPHA_TEST); */
shader_groups[RtPrim_SBT_RayGen] = (VkRayTracingShaderGroupCreateInfoKHR) {
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,
.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR,
.anyHitShader = VK_SHADER_UNUSED_KHR,
.closestHitShader = VK_SHADER_UNUSED_KHR,
.generalShader = ShaderStageIndex_RayGen,
.intersectionShader = VK_SHADER_UNUSED_KHR,
};
shader_groups[RtPrim_SBT_RayHit] = (VkRayTracingShaderGroupCreateInfoKHR) {
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,
.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR,
.anyHitShader = VK_SHADER_UNUSED_KHR,
.closestHitShader = ShaderStageIndex_RayClosestHit,
.generalShader = VK_SHADER_UNUSED_KHR,
.intersectionShader = VK_SHADER_UNUSED_KHR,
};
shader_groups[RtPrim_SBT_RayMiss] = (VkRayTracingShaderGroupCreateInfoKHR) {
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,
.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR,
.anyHitShader = VK_SHADER_UNUSED_KHR,
.closestHitShader = VK_SHADER_UNUSED_KHR,
.generalShader = ShaderStageIndex_RayMiss,
.intersectionShader = VK_SHADER_UNUSED_KHR,
};
XVK_CHECK(vkCreateRayTracingPipelinesKHR(vk_core.device, VK_NULL_HANDLE, g_pipeline_cache, 1, &rtpci, NULL, &g_ray_primary.pipeline));
ASSERT(g_ray_primary.pipeline != VK_NULL_HANDLE);
{
const uint32_t sbt_handle_size = vk_core.physical_device.properties_ray_tracing_pipeline.shaderGroupHandleSize;
const uint32_t sbt_handles_buffer_size = ARRAYSIZE(shader_groups) * sbt_handle_size;
uint8_t *sbt_handles = Mem_Malloc(vk_core.pool, sbt_handles_buffer_size);
XVK_CHECK(vkGetRayTracingShaderGroupHandlesKHR(vk_core.device, g_ray_primary.pipeline, 0, ARRAYSIZE(shader_groups), sbt_handles_buffer_size, sbt_handles));
for (int i = 0; i < ARRAYSIZE(shader_groups); ++i)
{
uint8_t *sbt_dst = g_ray_primary.sbt_buffer.mapped;
memcpy(sbt_dst + vk_core.physical_device.sbt_record_size * i, sbt_handles + sbt_handle_size * i, sbt_handle_size);
}
Mem_Free(sbt_handles);
}
for (int i = 0; i < ARRAYSIZE(shaders); ++i)
vkDestroyShaderModule(vk_core.device, shaders[i].module, NULL);
}
qboolean XVK_RayTracePrimaryInit( void ) {
if (!createBuffer("primary ray sbt_buffer", &g_ray_primary.sbt_buffer, RtPrim_SBT_COUNT * vk_core.physical_device.sbt_record_size,
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
{
return false;
}
initDescriptors();
initPipeline();
return true;
}
void XVK_RayTracePrimaryDestroy( void ) {
vkDestroyPipeline(vk_core.device, g_ray_primary.pipeline, NULL);
VK_DescriptorsDestroy(&g_ray_primary.desc.riptors);
destroyBuffer(&g_ray_primary.sbt_buffer);
}
static void updateDescriptors( const xvk_ray_trace_primary_t* args ) {
g_ray_primary.desc.values[RtPrim_Desc_Out_BaseColorR].image = (VkDescriptorImageInfo){
.sampler = VK_NULL_HANDLE,
.imageView = args->out.base_color_r,
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
};
VK_DescriptorsWrite(&g_ray_primary.desc.riptors);
}
void XVK_RayTracePrimary( VkCommandBuffer cmdbuf, const xvk_ray_trace_primary_t *args ) {
updateDescriptors( args );
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, g_ray_primary.pipeline);
/* { */
/* vk_rtx_push_constants_t push_constants = { */
/* .time = gpGlobals->time, */
/* .random_seed = (uint32_t)gEngine.COM_RandomLong(0, INT32_MAX), */
/* .bounces = vk_rtx_bounces->value, */
/* .pixel_cone_spread_angle = atanf((2.0f*tanf(DEG2RAD(fov_angle_y) * 0.5f)) / (float)FRAME_HEIGHT), */
/* .debug_light_index_begin = (uint32_t)(vk_rtx_light_begin->value), */
/* .debug_light_index_end = (uint32_t)(vk_rtx_light_end->value), */
/* .flags = r_lightmap->value ? PUSH_FLAG_LIGHTMAP_ONLY : 0, */
/* }; */
/* vkCmdPushConstants(cmdbuf, g_ray_primary.descriptors.pipeline_layout, VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR, 0, sizeof(push_constants), &push_constants); */
/* } */
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);
{
const uint32_t sbt_record_size = vk_core.physical_device.sbt_record_size;
#define SBT_INDEX(index, count) { \
.deviceAddress = XVK_BufferGetDeviceAddress(g_ray_primary.sbt_buffer.buffer) + sbt_record_size * index, \
.size = sbt_record_size * (count), \
.stride = sbt_record_size, \
}
const VkStridedDeviceAddressRegionKHR sbt_raygen = SBT_INDEX(RtPrim_SBT_RayGen, 1);
const VkStridedDeviceAddressRegionKHR sbt_miss = SBT_INDEX(RtPrim_SBT_RayMiss, 1); //ShaderBindingTable_Miss_Empty - ShaderBindingTable_Miss);
const VkStridedDeviceAddressRegionKHR sbt_hit = SBT_INDEX(RtPrim_SBT_RayHit, 1); //ShaderBindingTable_Hit__END - ShaderBindingTable_Hit_Base);
const VkStridedDeviceAddressRegionKHR sbt_callable = { 0 };
vkCmdTraceRaysKHR(cmdbuf, &sbt_raygen, &sbt_miss, &sbt_hit, &sbt_callable, args->width, args->height, 1 );
}
}

21
ref_vk/vk_ray_primary.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include "vk_core.h"
qboolean XVK_RayTracePrimaryInit( void );
void XVK_RayTracePrimaryDestroy( void );
typedef struct {
uint32_t width, height;
struct {
VkAccelerationStructureKHR tlas;
} in;
struct {
VkImageView base_color_r;
//VkImageView normals;
} out;
} xvk_ray_trace_primary_t;
void XVK_RayTracePrimary( VkCommandBuffer cmdbuf, const xvk_ray_trace_primary_t *args );

View File

@ -1,5 +1,7 @@
#include "vk_rtx.h"
#include "vk_ray_primary.h"
#include "vk_core.h"
#include "vk_common.h"
#include "vk_buffer.h"
@ -610,7 +612,7 @@ static void prepareTlas( VkCommandBuffer cmdbuf ) {
createTlas(cmdbuf);
}
static void updateDescriptors( VkCommandBuffer cmdbuf, const vk_ray_frame_render_args_t *args, const xvk_ray_frame_images_t *frame_dst ) {
static void updateDescriptors( const vk_ray_frame_render_args_t *args, const xvk_ray_frame_images_t *frame_dst ) {
// 3. Update descriptor sets (bind dest image, tlas, projection matrix)
VkDescriptorImageInfo dii_all_textures[MAX_TEXTURES];
@ -708,46 +710,6 @@ static void updateDescriptors( VkCommandBuffer cmdbuf, const vk_ray_frame_render
}
static qboolean rayTrace( VkCommandBuffer cmdbuf, const xvk_ray_frame_images_t *current_frame, float fov_angle_y ) {
#define LIST_GBUFFER_IMAGES(X) \
X(base_color) \
X(diffuse_gi) \
X(specular) \
X(additive) \
X(normals) \
// 4. Barrier for TLAS build and dest image layout transfer
{
VkBufferMemoryBarrier bmb[] = { {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
.buffer = g_rtx.accels_buffer.buffer,
.offset = 0,
.size = VK_WHOLE_SIZE,
} };
VkImageMemoryBarrier image_barrier[] = {
#define GBUFFER_WRITE_BARRIER(img) { \
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, \
.image = current_frame->img.image, \
.srcAccessMask = 0, \
.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT, \
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, \
.newLayout = VK_IMAGE_LAYOUT_GENERAL, \
.subresourceRange = (VkImageSubresourceRange) { \
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
.baseMipLevel = 0, \
.levelCount = 1, \
.baseArrayLayer = 0, \
.layerCount = 1, \
}, \
},
LIST_GBUFFER_IMAGES(GBUFFER_WRITE_BARRIER)
};
vkCmdPipelineBarrier(cmdbuf,
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
0, 0, NULL, ARRAYSIZE(bmb), bmb, ARRAYSIZE(image_barrier), image_barrier);
}
// 4. dispatch ray tracing
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, g_rtx.pipeline);
@ -955,6 +917,151 @@ static void blitImage( const xvk_blit_args *blit_args ) {
}
}
static void performTracing( VkCommandBuffer cmdbuf, const vk_ray_frame_render_args_t* args, const xvk_ray_frame_images_t *current_frame, float fov_angle_y) {
uploadLights();
prepareTlas(cmdbuf);
updateDescriptors(args, current_frame);
#define LIST_GBUFFER_IMAGES(X) \
X(base_color) \
X(diffuse_gi) \
X(specular) \
X(additive) \
X(normals) \
// 4. Barrier for TLAS build and dest image layout transfer
{
VkBufferMemoryBarrier bmb[] = { {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
.buffer = g_rtx.accels_buffer.buffer,
.offset = 0,
.size = VK_WHOLE_SIZE,
} };
VkImageMemoryBarrier image_barrier[] = {
#define GBUFFER_WRITE_BARRIER(img) { \
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, \
.image = current_frame->img.image, \
.srcAccessMask = 0, \
.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT, \
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, \
.newLayout = VK_IMAGE_LAYOUT_GENERAL, \
.subresourceRange = (VkImageSubresourceRange) { \
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
.baseMipLevel = 0, \
.levelCount = 1, \
.baseArrayLayer = 0, \
.layerCount = 1, \
}, \
},
LIST_GBUFFER_IMAGES(GBUFFER_WRITE_BARRIER)
};
vkCmdPipelineBarrier(cmdbuf,
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
0, 0, NULL, ARRAYSIZE(bmb), bmb, ARRAYSIZE(image_barrier), image_barrier);
}
{
const xvk_ray_trace_primary_t primary_args = {
.width = FRAME_WIDTH,
.height = FRAME_HEIGHT,
.in = {
.tlas = g_rtx.tlas,
},
.out = {
.base_color_r = current_frame->base_color.view,
},
};
XVK_RayTracePrimary( cmdbuf, &primary_args );
}
//rayTrace(cmdbuf, current_frame, fov_angle_y);
{
const VkImageMemoryBarrier image_barriers[] = {
#define GBUFFER_READ_BARRIER(img) { \
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, \
.image = current_frame->img.image, \
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, \
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT, \
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, \
.newLayout = VK_IMAGE_LAYOUT_GENERAL, \
.subresourceRange = (VkImageSubresourceRange) { \
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
.baseMipLevel = 0, \
.levelCount = 1, \
.baseArrayLayer = 0, \
.layerCount = 1, \
}, \
},
LIST_GBUFFER_IMAGES(GBUFFER_READ_BARRIER)
{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.image = current_frame->denoised.image,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
.subresourceRange =
(VkImageSubresourceRange){
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
} };
vkCmdPipelineBarrier(args->cmdbuf,
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0, 0, NULL, 0, NULL, ARRAYSIZE(image_barriers), image_barriers);
}
{
const xvk_denoiser_args_t denoiser_args = {
.cmdbuf = cmdbuf,
.width = FRAME_WIDTH,
.height = FRAME_HEIGHT,
.src = {
.base_color_view = current_frame->base_color.view,
.diffuse_gi_view = current_frame->diffuse_gi.view,
.specular_view = current_frame->specular.view,
.additive_view = current_frame->additive.view,
.normals_view = current_frame->normals.view,
},
.dst_view = current_frame->denoised.view,
};
XVK_DenoiserDenoise( &denoiser_args );
}
{
const xvk_blit_args blit_args = {
.cmdbuf = args->cmdbuf,
.in_stage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
.src = {
.image = current_frame->denoised.image,
.width = FRAME_WIDTH,
.height = FRAME_HEIGHT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
},
.dst = {
.image = args->dst.image,
.width = args->dst.width,
.height = args->dst.height,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.srcAccessMask = 0,
},
};
blitImage( &blit_args );
}
}
qboolean initVk2d(void);
void deinitVk2d(void);
@ -986,8 +1093,6 @@ void VK_RayFrameEnd(const vk_ray_frame_render_args_t* args)
g_rtx.reload_pipeline = false;
}
uploadLights();
if (g_ray_model_state.frame.num_models == 0) {
const xvk_blit_args blit_args = {
.cmdbuf = args->cmdbuf,
@ -1011,90 +1116,7 @@ void VK_RayFrameEnd(const vk_ray_frame_render_args_t* args)
clearVkImage( cmdbuf, current_frame->denoised.image );
blitImage( &blit_args );
} else {
prepareTlas(cmdbuf);
updateDescriptors(cmdbuf, args, current_frame);
rayTrace(cmdbuf, current_frame, args->fov_angle_y);
{
const VkImageMemoryBarrier image_barriers[] = {
#define GBUFFER_READ_BARRIER(img) { \
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, \
.image = current_frame->img.image, \
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, \
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT, \
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, \
.newLayout = VK_IMAGE_LAYOUT_GENERAL, \
.subresourceRange = (VkImageSubresourceRange) { \
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, \
.baseMipLevel = 0, \
.levelCount = 1, \
.baseArrayLayer = 0, \
.layerCount = 1, \
}, \
},
LIST_GBUFFER_IMAGES(GBUFFER_READ_BARRIER)
{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.image = current_frame->denoised.image,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
.subresourceRange =
(VkImageSubresourceRange){
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
} };
vkCmdPipelineBarrier(args->cmdbuf,
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0, 0, NULL, 0, NULL, ARRAYSIZE(image_barriers), image_barriers);
}
{
const xvk_denoiser_args_t denoiser_args = {
.cmdbuf = cmdbuf,
.width = FRAME_WIDTH,
.height = FRAME_HEIGHT,
.src = {
.base_color_view = current_frame->base_color.view,
.diffuse_gi_view = current_frame->diffuse_gi.view,
.specular_view = current_frame->specular.view,
.additive_view = current_frame->additive.view,
.normals_view = current_frame->normals.view,
},
.dst_view = current_frame->denoised.view,
};
XVK_DenoiserDenoise( &denoiser_args );
}
{
const xvk_blit_args blit_args = {
.cmdbuf = args->cmdbuf,
.in_stage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
.src = {
.image = current_frame->denoised.image,
.width = FRAME_WIDTH,
.height = FRAME_HEIGHT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
},
.dst = {
.image = args->dst.image,
.width = args->dst.width,
.height = args->dst.height,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.srcAccessMask = 0,
},
};
blitImage( &blit_args );
}
performTracing( cmdbuf, args, current_frame, args->fov_angle_y );
}
}
@ -1236,8 +1258,9 @@ qboolean VK_RayInit( void )
ASSERT(vk_core.rtx);
// TODO complain and cleanup on failure
//g_rtx.sbt_record_size = ALIGN_UP(vk_core.physical_device.properties_ray_tracing_pipeline.shaderGroupHandleSize, vk_core.physical_device.properties_ray_tracing_pipeline.shaderGroupHandleAlignment);
g_rtx.sbt_record_size = ALIGN_UP(vk_core.physical_device.properties_ray_tracing_pipeline.shaderGroupHandleSize, vk_core.physical_device.properties_ray_tracing_pipeline.shaderGroupBaseAlignment);
ASSERT(XVK_RayTracePrimaryInit());
g_rtx.sbt_record_size = vk_core.physical_device.sbt_record_size;
if (!createBuffer("ray sbt_buffer", &g_rtx.sbt_buffer, ShaderBindingTable_COUNT * g_rtx.sbt_record_size,
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR,
@ -1337,6 +1360,8 @@ qboolean VK_RayInit( void )
void VK_RayShutdown( void ) {
ASSERT(vk_core.rtx);
XVK_RayTracePrimaryDestroy();
for (int i = 0; i < ARRAYSIZE(g_rtx.frames); ++i) {
XVK_ImageDestroy(&g_rtx.frames[i].denoised);
XVK_ImageDestroy(&g_rtx.frames[i].base_color);