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:
parent
9adf9e1779
commit
cd47861d9b
|
@ -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;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#version 460 core
|
||||
#extension GL_EXT_ray_tracing: require
|
||||
|
||||
void main() {}
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#version 460 core
|
||||
#extension GL_EXT_ray_tracing: require
|
||||
|
||||
void main() {}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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|......................>|
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
@ -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 );
|
283
ref_vk/vk_rtx.c
283
ref_vk/vk_rtx.c
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue