2021-02-27 22:43:49 +01:00
|
|
|
#include "vk_rtx.h"
|
|
|
|
|
2022-01-27 08:52:14 +01:00
|
|
|
#include "ray_pass.h"
|
2022-02-01 05:50:39 +01:00
|
|
|
#include "ray_resources.h"
|
2022-08-27 21:30:53 +02:00
|
|
|
#include "vk_ray_accel.h"
|
2022-01-31 07:24:55 +01:00
|
|
|
|
2022-01-08 03:51:59 +01:00
|
|
|
#include "vk_ray_primary.h"
|
rt: draft direct light compute shader
it's bad:
direct light: 1.8ms, 183(184)v, 59(128)s, LDS=0, 2/16o
(-56 vgpr => +1 wavefront??)
also, thread group size = 16, 8, 1, wave64
while ray tracing pipeline = 8, 4, 1, wave32
2022-01-11 04:13:08 +01:00
|
|
|
#include "vk_ray_light_direct.h"
|
2022-01-08 03:51:59 +01:00
|
|
|
|
2021-02-27 22:43:49 +01:00
|
|
|
#include "vk_core.h"
|
|
|
|
#include "vk_common.h"
|
|
|
|
#include "vk_buffer.h"
|
2021-03-13 21:29:17 +01:00
|
|
|
#include "vk_pipeline.h"
|
2022-08-20 22:56:29 +02:00
|
|
|
#include "vk_staging.h"
|
2021-03-15 17:44:15 +01:00
|
|
|
#include "vk_cvar.h"
|
2021-03-17 17:15:33 +01:00
|
|
|
#include "vk_textures.h"
|
2021-03-28 22:52:25 +02:00
|
|
|
#include "vk_light.h"
|
2021-05-01 20:48:24 +02:00
|
|
|
#include "vk_descriptor.h"
|
2021-07-05 19:59:14 +02:00
|
|
|
#include "vk_ray_internal.h"
|
2021-11-05 17:11:40 +01:00
|
|
|
#include "vk_denoiser.h"
|
2022-01-08 22:44:02 +01:00
|
|
|
#include "vk_math.h"
|
2021-02-27 22:43:49 +01:00
|
|
|
|
2022-07-15 09:35:19 +02:00
|
|
|
#include "alolcator.h"
|
|
|
|
|
2022-01-31 07:24:55 +01:00
|
|
|
|
2021-02-27 22:43:49 +01:00
|
|
|
#include "eiface.h"
|
2021-03-17 17:15:33 +01:00
|
|
|
#include "xash3d_mathlib.h"
|
2021-02-27 22:43:49 +01:00
|
|
|
|
2021-03-21 00:21:26 +01:00
|
|
|
#include <string.h>
|
|
|
|
|
2022-01-08 22:44:02 +01:00
|
|
|
#define MAX_FRAMES_IN_FLIGHT 2
|
2021-02-27 22:43:49 +01:00
|
|
|
|
2021-03-20 19:15:57 +01:00
|
|
|
// TODO settings/realtime modifiable/adaptive
|
2022-07-09 20:40:26 +02:00
|
|
|
#if 1
|
2021-03-20 19:15:57 +01:00
|
|
|
#define FRAME_WIDTH 1280
|
|
|
|
#define FRAME_HEIGHT 720
|
2022-08-20 22:56:29 +02:00
|
|
|
#elif 0
|
2022-07-09 20:40:26 +02:00
|
|
|
#define FRAME_WIDTH 2560
|
|
|
|
#define FRAME_HEIGHT 1440
|
2022-08-20 22:56:29 +02:00
|
|
|
#else
|
|
|
|
#define FRAME_WIDTH 1920
|
|
|
|
#define FRAME_HEIGHT 1080
|
2022-07-09 20:40:26 +02:00
|
|
|
#endif
|
2021-03-20 19:15:57 +01:00
|
|
|
|
2021-03-01 19:52:08 +01:00
|
|
|
// TODO sync with shaders
|
2021-03-20 19:15:57 +01:00
|
|
|
// TODO optimal values
|
2021-03-01 19:52:08 +01:00
|
|
|
#define WG_W 16
|
|
|
|
#define WG_H 8
|
|
|
|
|
2021-03-07 01:40:35 +01:00
|
|
|
typedef struct {
|
|
|
|
vec3_t pos;
|
|
|
|
float radius;
|
|
|
|
vec3_t color;
|
|
|
|
float padding_;
|
|
|
|
} vk_light_t;
|
|
|
|
|
2021-10-03 19:30:06 +02:00
|
|
|
typedef struct PushConstants vk_rtx_push_constants_t;
|
2021-03-15 17:44:15 +01:00
|
|
|
|
2021-11-07 21:46:27 +01:00
|
|
|
typedef struct {
|
2021-11-21 22:40:11 +01:00
|
|
|
xvk_image_t denoised;
|
2022-01-08 07:43:27 +01:00
|
|
|
|
2022-01-10 04:50:43 +01:00
|
|
|
#define X(index, name, ...) xvk_image_t name;
|
|
|
|
RAY_PRIMARY_OUTPUTS(X)
|
2022-01-28 04:14:56 +01:00
|
|
|
RAY_LIGHT_DIRECT_POLY_OUTPUTS(X)
|
|
|
|
RAY_LIGHT_DIRECT_POINT_OUTPUTS(X)
|
2022-01-10 04:50:43 +01:00
|
|
|
#undef X
|
2022-01-08 07:43:27 +01:00
|
|
|
|
2021-11-21 22:40:11 +01:00
|
|
|
xvk_image_t diffuse_gi;
|
|
|
|
xvk_image_t specular;
|
|
|
|
xvk_image_t additive;
|
2021-11-07 21:46:27 +01:00
|
|
|
} xvk_ray_frame_images_t;
|
|
|
|
|
2021-02-27 22:43:49 +01:00
|
|
|
static struct {
|
2022-01-08 22:44:02 +01:00
|
|
|
// Holds UniformBuffer data
|
|
|
|
vk_buffer_t uniform_buffer;
|
2022-01-18 06:12:14 +01:00
|
|
|
uint32_t uniform_unit_size;
|
2022-01-08 22:44:02 +01:00
|
|
|
|
2022-05-29 09:01:43 +02:00
|
|
|
// TODO with proper intra-cmdbuf sync we don't really need 2x images
|
2021-03-20 21:42:15 +01:00
|
|
|
unsigned frame_number;
|
2022-01-08 22:44:02 +01:00
|
|
|
xvk_ray_frame_images_t frames[MAX_FRAMES_IN_FLIGHT];
|
2021-03-20 19:15:57 +01:00
|
|
|
|
2022-01-27 08:52:14 +01:00
|
|
|
struct {
|
|
|
|
struct ray_pass_s *primary_ray;
|
2022-01-28 02:47:00 +01:00
|
|
|
struct ray_pass_s *light_direct_poly;
|
2022-01-28 04:14:56 +01:00
|
|
|
struct ray_pass_s *light_direct_point;
|
2022-01-31 07:24:55 +01:00
|
|
|
struct ray_pass_s *denoiser;
|
2022-01-27 08:52:14 +01:00
|
|
|
} pass;
|
|
|
|
|
2021-03-13 21:29:17 +01:00
|
|
|
qboolean reload_pipeline;
|
2021-09-14 19:24:27 +02:00
|
|
|
qboolean reload_lighting;
|
2021-05-24 20:14:03 +02:00
|
|
|
} g_rtx = {0};
|
2021-02-27 22:43:49 +01:00
|
|
|
|
2021-05-26 18:35:36 +02:00
|
|
|
|
2021-04-09 23:59:04 +02:00
|
|
|
void VK_RayNewMap( void ) {
|
2022-08-27 21:30:53 +02:00
|
|
|
RT_VkAccelNewMap();
|
2022-05-29 09:01:43 +02:00
|
|
|
RT_RayModel_Clear();
|
2021-02-27 22:43:49 +01:00
|
|
|
}
|
|
|
|
|
2021-04-09 23:59:04 +02:00
|
|
|
void VK_RayFrameBegin( void )
|
2021-03-01 20:22:58 +01:00
|
|
|
{
|
|
|
|
ASSERT(vk_core.rtx);
|
|
|
|
|
2022-08-27 21:30:53 +02:00
|
|
|
RT_VkAccelFrameBegin();
|
2021-05-08 23:34:42 +02:00
|
|
|
|
2021-07-05 19:59:14 +02:00
|
|
|
if (g_ray_model_state.freeze_models)
|
|
|
|
return;
|
2021-04-24 21:53:42 +02:00
|
|
|
|
2021-07-05 19:59:14 +02:00
|
|
|
XVK_RayModel_ClearForNextFrame();
|
2021-05-03 20:17:01 +02:00
|
|
|
|
2021-12-27 08:12:50 +01:00
|
|
|
// TODO: move all lighting update to scene?
|
2021-09-14 19:24:27 +02:00
|
|
|
if (g_rtx.reload_lighting) {
|
|
|
|
g_rtx.reload_lighting = false;
|
2022-01-15 08:48:57 +01:00
|
|
|
// FIXME temporarily not supported VK_LightsLoadMapStaticLights();
|
2021-09-14 19:24:27 +02:00
|
|
|
}
|
|
|
|
|
2021-07-05 19:59:14 +02:00
|
|
|
// TODO shouldn't we do this in freeze models mode anyway?
|
2022-07-30 20:37:06 +02:00
|
|
|
RT_LightsFrameBegin();
|
2021-03-01 20:22:58 +01:00
|
|
|
}
|
|
|
|
|
2022-01-08 22:44:02 +01:00
|
|
|
static void prepareUniformBuffer( const vk_ray_frame_render_args_t *args, int frame_index, float fov_angle_y ) {
|
2022-01-18 06:12:14 +01:00
|
|
|
struct UniformBuffer *ubo = (struct UniformBuffer*)((char*)g_rtx.uniform_buffer.mapped + frame_index * g_rtx.uniform_unit_size);
|
2022-01-08 22:44:02 +01:00
|
|
|
|
|
|
|
matrix4x4 proj_inv, view_inv;
|
|
|
|
Matrix4x4_Invert_Full(proj_inv, *args->projection);
|
|
|
|
Matrix4x4_ToArrayFloatGL(proj_inv, (float*)ubo->inv_proj);
|
|
|
|
|
|
|
|
// TODO there's a more efficient way to construct an inverse view matrix
|
|
|
|
// from vforward/right/up vectors and origin in g_camera
|
|
|
|
Matrix4x4_Invert_Full(view_inv, *args->view);
|
|
|
|
Matrix4x4_ToArrayFloatGL(view_inv, (float*)ubo->inv_view);
|
|
|
|
|
|
|
|
ubo->ray_cone_width = atanf((2.0f*tanf(DEG2RAD(fov_angle_y) * 0.5f)) / (float)FRAME_HEIGHT);
|
2022-01-16 08:15:29 +01:00
|
|
|
ubo->random_seed = (uint32_t)gEngine.COM_RandomLong(0, INT32_MAX);
|
2022-01-08 22:44:02 +01:00
|
|
|
}
|
|
|
|
|
2022-08-07 18:45:54 +02:00
|
|
|
typedef struct {
|
|
|
|
const vk_ray_frame_render_args_t* render_args;
|
|
|
|
int frame_index;
|
|
|
|
const xvk_ray_frame_images_t *current_frame;
|
|
|
|
float fov_angle_y;
|
|
|
|
const vk_lights_bindings_t *light_bindings;
|
|
|
|
} perform_tracing_args_t;
|
|
|
|
|
|
|
|
static void performTracing(VkCommandBuffer cmdbuf, const perform_tracing_args_t* args) {
|
2022-02-01 05:40:41 +01:00
|
|
|
vk_ray_resources_t res = {
|
2022-01-22 05:55:43 +01:00
|
|
|
.width = FRAME_WIDTH,
|
|
|
|
.height = FRAME_HEIGHT,
|
2022-02-01 05:40:41 +01:00
|
|
|
.resources = {
|
2022-01-29 07:58:07 +01:00
|
|
|
[RayResource_tlas] = {
|
2022-02-01 05:40:41 +01:00
|
|
|
.type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
|
|
|
|
.value.accel = (VkWriteDescriptorSetAccelerationStructureKHR){
|
2022-01-29 07:58:07 +01:00
|
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
|
|
|
|
.accelerationStructureCount = 1,
|
2022-08-27 21:30:53 +02:00
|
|
|
.pAccelerationStructures = &g_accel.tlas,
|
2022-01-29 07:58:07 +01:00
|
|
|
.pNext = NULL,
|
|
|
|
},
|
2022-01-22 05:55:43 +01:00
|
|
|
},
|
2022-02-01 05:40:41 +01:00
|
|
|
#define RES_SET_BUFFER(name, type_, source_, offset_, size_) \
|
|
|
|
[RayResource_##name] = { \
|
|
|
|
.type = type_, \
|
|
|
|
.value.buffer = (VkDescriptorBufferInfo) { \
|
2022-08-07 18:45:54 +02:00
|
|
|
.buffer = (source_), \
|
2022-02-01 05:40:41 +01:00
|
|
|
.offset = (offset_), \
|
|
|
|
.range = (size_), \
|
|
|
|
} \
|
|
|
|
}
|
2022-08-07 18:45:54 +02:00
|
|
|
RES_SET_BUFFER(ubo, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, g_rtx.uniform_buffer.buffer, args->frame_index * g_rtx.uniform_unit_size, sizeof(struct UniformBuffer)),
|
2022-02-01 05:40:41 +01:00
|
|
|
|
|
|
|
#define RES_SET_SBUFFER_FULL(name, source_) \
|
2022-08-07 18:45:54 +02:00
|
|
|
RES_SET_BUFFER(name, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, source_.buffer, 0, source_.size)
|
2022-02-01 05:40:41 +01:00
|
|
|
RES_SET_SBUFFER_FULL(kusochki, g_ray_model_state.kusochki_buffer),
|
2022-08-07 18:45:54 +02:00
|
|
|
RES_SET_SBUFFER_FULL(indices, args->render_args->geometry_data),
|
|
|
|
RES_SET_SBUFFER_FULL(vertices, args->render_args->geometry_data),
|
|
|
|
RES_SET_BUFFER(lights, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, args->light_bindings->buffer, args->light_bindings->metadata.offset, args->light_bindings->metadata.size),
|
|
|
|
RES_SET_BUFFER(light_clusters, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, args->light_bindings->buffer, args->light_bindings->grid.offset, args->light_bindings->grid.size),
|
2022-02-01 05:40:41 +01:00
|
|
|
#undef RES_SET_SBUFFER_FULL
|
2022-01-29 07:58:07 +01:00
|
|
|
#undef RES_SET_BUFFER
|
2022-02-01 05:40:41 +01:00
|
|
|
|
|
|
|
[RayResource_all_textures] = {
|
|
|
|
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
|
|
.value.image_array = tglob.dii_all_textures,
|
|
|
|
},
|
|
|
|
|
2022-02-03 06:47:40 +01:00
|
|
|
[RayResource_skybox] = {
|
|
|
|
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
|
|
.value.image = {
|
|
|
|
.sampler = vk_core.default_sampler,
|
|
|
|
.imageView = tglob.skybox_cube.vk.image.view ? tglob.skybox_cube.vk.image.view : tglob.cubemap_placeholder.vk.image.view,
|
|
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
2022-02-01 05:40:41 +01:00
|
|
|
#define RES_SET_IMAGE(index, name, ...) \
|
|
|
|
[RayResource_##name] = { \
|
|
|
|
.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, \
|
|
|
|
.write = {0}, \
|
|
|
|
.read = {0}, \
|
2022-08-07 18:45:54 +02:00
|
|
|
.image = &args->current_frame->name, \
|
2022-02-01 05:40:41 +01:00
|
|
|
},
|
|
|
|
RAY_PRIMARY_OUTPUTS(RES_SET_IMAGE)
|
|
|
|
RAY_LIGHT_DIRECT_POLY_OUTPUTS(RES_SET_IMAGE)
|
|
|
|
RAY_LIGHT_DIRECT_POINT_OUTPUTS(RES_SET_IMAGE)
|
|
|
|
RES_SET_IMAGE(-1, denoised)
|
|
|
|
#undef RES_SET_IMAGE
|
2022-01-29 07:58:07 +01:00
|
|
|
},
|
2022-01-22 05:55:43 +01:00
|
|
|
};
|
|
|
|
|
2022-08-20 22:56:29 +02:00
|
|
|
// Upload kusochki updates
|
|
|
|
{
|
|
|
|
const VkBufferMemoryBarrier bmb[] = { {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR,
|
|
|
|
.buffer = g_ray_model_state.kusochki_buffer.buffer,
|
|
|
|
.offset = 0,
|
|
|
|
.size = VK_WHOLE_SIZE,
|
|
|
|
} };
|
|
|
|
|
|
|
|
vkCmdPipelineBarrier(cmdbuf,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR | VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
|
|
|
|
0, 0, NULL, ARRAYSIZE(bmb), bmb, 0, NULL);
|
|
|
|
}
|
2022-01-22 05:55:43 +01:00
|
|
|
|
2022-01-19 07:21:14 +01:00
|
|
|
DEBUG_BEGIN(cmdbuf, "yay tracing");
|
2022-08-27 21:30:53 +02:00
|
|
|
RT_VkAccelPrepareTlas(cmdbuf);
|
2022-08-07 18:45:54 +02:00
|
|
|
prepareUniformBuffer(args->render_args, args->frame_index, args->fov_angle_y);
|
2022-01-08 03:51:59 +01:00
|
|
|
|
2022-08-20 22:56:29 +02:00
|
|
|
// 4. Barrier for TLAS build
|
2022-01-08 03:51:59 +01:00
|
|
|
{
|
2022-08-20 22:56:29 +02:00
|
|
|
const VkBufferMemoryBarrier bmb[] = { {
|
2022-01-08 03:51:59 +01:00
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
|
|
|
.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
2022-08-27 21:30:53 +02:00
|
|
|
.buffer = g_accel.accels_buffer.buffer,
|
2022-01-08 03:51:59 +01:00
|
|
|
.offset = 0,
|
|
|
|
.size = VK_WHOLE_SIZE,
|
|
|
|
} };
|
|
|
|
vkCmdPipelineBarrier(cmdbuf,
|
|
|
|
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
|
|
|
|
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
|
2022-02-01 05:40:41 +01:00
|
|
|
0, 0, NULL, ARRAYSIZE(bmb), bmb, 0, NULL);
|
2022-01-08 03:51:59 +01:00
|
|
|
}
|
|
|
|
|
2022-08-07 18:45:54 +02:00
|
|
|
RayPassPerform( cmdbuf, args->frame_index, g_rtx.pass.primary_ray, &res );
|
2022-08-15 18:20:42 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
//const uint32_t size = sizeof(struct Lights);
|
|
|
|
//const uint32_t size = sizeof(struct LightsMetadata); // + 8 * sizeof(uint32_t);
|
|
|
|
const VkBufferMemoryBarrier bmb[] = {{
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
|
|
|
.buffer = args->light_bindings->buffer,
|
|
|
|
.offset = 0,
|
|
|
|
.size = VK_WHOLE_SIZE,
|
|
|
|
}};
|
|
|
|
vkCmdPipelineBarrier(cmdbuf,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
|
|
|
|
0, 0, NULL, ARRAYSIZE(bmb), bmb, 0, NULL);
|
|
|
|
}
|
|
|
|
|
2022-08-07 18:45:54 +02:00
|
|
|
RayPassPerform( cmdbuf, args->frame_index, g_rtx.pass.light_direct_poly, &res );
|
|
|
|
RayPassPerform( cmdbuf, args->frame_index, g_rtx.pass.light_direct_point, &res );
|
|
|
|
RayPassPerform( cmdbuf, args->frame_index, g_rtx.pass.denoiser, &res );
|
2022-01-08 03:51:59 +01:00
|
|
|
|
|
|
|
{
|
2022-08-27 20:39:29 +02:00
|
|
|
const r_vkimage_blit_args blit_args = {
|
2022-01-08 03:51:59 +01:00
|
|
|
.in_stage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
|
|
|
.src = {
|
2022-08-07 18:45:54 +02:00
|
|
|
.image = args->current_frame->denoised.image,
|
2022-01-08 03:51:59 +01:00
|
|
|
.width = FRAME_WIDTH,
|
|
|
|
.height = FRAME_HEIGHT,
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
|
|
|
},
|
|
|
|
.dst = {
|
2022-08-07 18:45:54 +02:00
|
|
|
.image = args->render_args->dst.image,
|
|
|
|
.width = args->render_args->dst.width,
|
|
|
|
.height = args->render_args->dst.height,
|
2022-01-08 03:51:59 +01:00
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
|
.srcAccessMask = 0,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2022-08-27 20:39:29 +02:00
|
|
|
R_VkImageBlit( cmdbuf, &blit_args );
|
2022-01-08 03:51:59 +01:00
|
|
|
}
|
2022-01-19 07:21:14 +01:00
|
|
|
DEBUG_END(cmdbuf);
|
2022-01-08 03:51:59 +01:00
|
|
|
}
|
|
|
|
|
2022-01-28 02:47:00 +01:00
|
|
|
static void reloadPass( struct ray_pass_s **slot, struct ray_pass_s *new_pass ) {
|
|
|
|
if (!new_pass)
|
|
|
|
return;
|
|
|
|
|
|
|
|
RayPassDestroy( *slot );
|
|
|
|
*slot = new_pass;
|
|
|
|
}
|
|
|
|
|
2021-07-17 20:45:28 +02:00
|
|
|
void VK_RayFrameEnd(const vk_ray_frame_render_args_t* args)
|
|
|
|
{
|
|
|
|
const VkCommandBuffer cmdbuf = args->cmdbuf;
|
2021-11-07 21:46:27 +01:00
|
|
|
const xvk_ray_frame_images_t* current_frame = g_rtx.frames + (g_rtx.frame_number % 2);
|
2021-07-17 20:45:28 +02:00
|
|
|
|
|
|
|
ASSERT(vk_core.rtx);
|
|
|
|
// ubo should contain two matrices
|
|
|
|
// FIXME pass these matrices explicitly to let RTX module handle ubo itself
|
|
|
|
|
2022-07-30 20:37:06 +02:00
|
|
|
RT_LightsFrameEnd();
|
2022-08-07 18:45:54 +02:00
|
|
|
const vk_lights_bindings_t light_bindings = VK_LightsUpload(cmdbuf);
|
2022-07-30 20:37:06 +02:00
|
|
|
|
2021-07-17 20:45:28 +02:00
|
|
|
g_rtx.frame_number++;
|
|
|
|
|
2021-10-19 19:13:33 +02:00
|
|
|
// if (vk_core.debug)
|
|
|
|
// XVK_RayModel_Validate();
|
2021-07-17 20:45:28 +02:00
|
|
|
|
|
|
|
if (g_rtx.reload_pipeline) {
|
|
|
|
gEngine.Con_Printf(S_WARN "Reloading RTX shaders/pipelines\n");
|
2022-08-12 21:32:52 +02:00
|
|
|
XVK_CHECK(vkDeviceWaitIdle(vk_core.device));
|
2021-11-07 21:46:27 +01:00
|
|
|
|
2022-01-28 02:47:00 +01:00
|
|
|
reloadPass( &g_rtx.pass.primary_ray, R_VkRayPrimaryPassCreate());
|
|
|
|
reloadPass( &g_rtx.pass.light_direct_poly, R_VkRayLightDirectPolyPassCreate());
|
2022-01-28 04:14:56 +01:00
|
|
|
reloadPass( &g_rtx.pass.light_direct_point, R_VkRayLightDirectPointPassCreate());
|
2022-01-31 07:24:55 +01:00
|
|
|
reloadPass( &g_rtx.pass.denoiser, R_VkRayDenoiserCreate());
|
2022-01-27 08:52:14 +01:00
|
|
|
|
2021-07-17 20:45:28 +02:00
|
|
|
g_rtx.reload_pipeline = false;
|
2021-03-20 19:15:57 +01:00
|
|
|
}
|
2021-07-04 20:18:28 +02:00
|
|
|
|
2021-11-07 21:46:27 +01:00
|
|
|
if (g_ray_model_state.frame.num_models == 0) {
|
2022-08-27 20:39:29 +02:00
|
|
|
const r_vkimage_blit_args blit_args = {
|
2021-11-07 21:46:27 +01:00
|
|
|
.in_stage = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
.src = {
|
|
|
|
.image = current_frame->denoised.image,
|
|
|
|
.width = FRAME_WIDTH,
|
|
|
|
.height = FRAME_HEIGHT,
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
},
|
|
|
|
.dst = {
|
2021-07-17 21:40:26 +02:00
|
|
|
.image = args->dst.image,
|
2021-11-07 21:46:27 +01:00
|
|
|
.width = args->dst.width,
|
|
|
|
.height = args->dst.height,
|
2021-07-17 21:40:26 +02:00
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
2021-11-07 21:46:27 +01:00
|
|
|
.srcAccessMask = 0,
|
|
|
|
},
|
|
|
|
};
|
2021-07-17 21:40:26 +02:00
|
|
|
|
2022-08-27 20:39:29 +02:00
|
|
|
R_VkImageClear( cmdbuf, current_frame->denoised.image );
|
|
|
|
R_VkImageBlit( cmdbuf, &blit_args );
|
2021-07-17 20:45:28 +02:00
|
|
|
} else {
|
2022-08-07 18:45:54 +02:00
|
|
|
const perform_tracing_args_t trace_args = {
|
|
|
|
.render_args = args,
|
|
|
|
.frame_index = (g_rtx.frame_number % 2),
|
|
|
|
.current_frame = current_frame,
|
|
|
|
.fov_angle_y = args->fov_angle_y,
|
|
|
|
.light_bindings = &light_bindings,
|
|
|
|
};
|
|
|
|
performTracing( cmdbuf, &trace_args );
|
2021-11-07 19:07:01 +01:00
|
|
|
}
|
2021-03-01 19:52:08 +01:00
|
|
|
}
|
|
|
|
|
2021-03-13 21:29:17 +01:00
|
|
|
static void reloadPipeline( void ) {
|
|
|
|
g_rtx.reload_pipeline = true;
|
2021-02-27 22:43:49 +01:00
|
|
|
}
|
|
|
|
|
2021-09-14 19:24:27 +02:00
|
|
|
static void reloadLighting( void ) {
|
|
|
|
g_rtx.reload_lighting = true;
|
|
|
|
}
|
|
|
|
|
2021-05-08 23:34:42 +02:00
|
|
|
static void freezeModels( void ) {
|
2021-07-05 19:59:14 +02:00
|
|
|
g_ray_model_state.freeze_models = !g_ray_model_state.freeze_models;
|
2021-05-08 23:34:42 +02:00
|
|
|
}
|
|
|
|
|
2021-02-27 22:43:49 +01:00
|
|
|
qboolean VK_RayInit( void )
|
|
|
|
{
|
|
|
|
ASSERT(vk_core.rtx);
|
|
|
|
// TODO complain and cleanup on failure
|
2021-07-05 22:24:57 +02:00
|
|
|
|
2022-08-27 21:30:53 +02:00
|
|
|
if (!RT_VkAccelInit())
|
|
|
|
return false;
|
|
|
|
|
2022-01-27 08:52:14 +01:00
|
|
|
g_rtx.pass.primary_ray = R_VkRayPrimaryPassCreate();
|
|
|
|
ASSERT(g_rtx.pass.primary_ray);
|
2022-01-28 02:47:00 +01:00
|
|
|
|
|
|
|
g_rtx.pass.light_direct_poly = R_VkRayLightDirectPolyPassCreate();
|
|
|
|
ASSERT(g_rtx.pass.light_direct_poly);
|
2022-01-08 03:51:59 +01:00
|
|
|
|
2022-01-28 04:14:56 +01:00
|
|
|
g_rtx.pass.light_direct_point = R_VkRayLightDirectPointPassCreate();
|
|
|
|
ASSERT(g_rtx.pass.light_direct_point);
|
|
|
|
|
2022-01-31 07:24:55 +01:00
|
|
|
g_rtx.pass.denoiser = R_VkRayDenoiserCreate();
|
|
|
|
ASSERT(g_rtx.pass.denoiser);
|
|
|
|
|
2022-01-18 06:12:14 +01:00
|
|
|
g_rtx.uniform_unit_size = ALIGN_UP(sizeof(struct UniformBuffer), vk_core.physical_device.properties.limits.minUniformBufferOffsetAlignment);
|
2021-07-05 22:24:57 +02:00
|
|
|
|
2022-01-18 08:04:06 +01:00
|
|
|
if (!VK_BufferCreate("ray uniform_buffer", &g_rtx.uniform_buffer, g_rtx.uniform_unit_size * MAX_FRAMES_IN_FLIGHT,
|
2022-01-08 22:44:02 +01:00
|
|
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
|
|
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-01-09 20:14:44 +01:00
|
|
|
if (!VK_BufferCreate("ray kusochki_buffer", &g_ray_model_state.kusochki_buffer, sizeof(vk_kusok_data_t) * MAX_KUSOCHKI,
|
2022-08-20 21:13:03 +02:00
|
|
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
|
|
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
|
2021-03-08 21:09:11 +01:00
|
|
|
// FIXME complain, handle
|
|
|
|
return false;
|
|
|
|
}
|
2022-05-29 09:01:43 +02:00
|
|
|
RT_RayModel_Clear();
|
2021-05-03 20:17:01 +02:00
|
|
|
|
2021-03-20 19:15:57 +01:00
|
|
|
for (int i = 0; i < ARRAYSIZE(g_rtx.frames); ++i) {
|
2021-11-21 22:40:11 +01:00
|
|
|
#define CREATE_GBUFFER_IMAGE(name, format_, add_usage_bits) \
|
|
|
|
do { \
|
|
|
|
char debug_name[64]; \
|
|
|
|
const xvk_image_create_t create = { \
|
|
|
|
.debug_name = debug_name, \
|
|
|
|
.width = FRAME_WIDTH, \
|
|
|
|
.height = FRAME_HEIGHT, \
|
|
|
|
.mips = 1, \
|
2021-11-21 23:53:51 +01:00
|
|
|
.layers = 1, \
|
2021-11-21 22:40:11 +01:00
|
|
|
.format = format_, \
|
|
|
|
.tiling = VK_IMAGE_TILING_OPTIMAL, \
|
|
|
|
.usage = VK_IMAGE_USAGE_STORAGE_BIT | add_usage_bits, \
|
|
|
|
.has_alpha = true, \
|
2021-11-21 23:53:51 +01:00
|
|
|
.is_cubemap = false, \
|
2021-11-21 22:40:11 +01:00
|
|
|
}; \
|
|
|
|
Q_snprintf(debug_name, sizeof(debug_name), "rtx frames[%d] " # name, i); \
|
|
|
|
g_rtx.frames[i].name = XVK_ImageCreate(&create); \
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
CREATE_GBUFFER_IMAGE(denoised, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
2022-01-08 07:43:27 +01:00
|
|
|
|
2022-01-10 04:50:43 +01:00
|
|
|
#define rgba8 VK_FORMAT_R8G8B8A8_UNORM
|
|
|
|
#define rgba32f VK_FORMAT_R32G32B32A32_SFLOAT
|
2022-01-10 05:02:27 +01:00
|
|
|
#define rgba16f VK_FORMAT_R16G16B16A16_SFLOAT
|
2022-01-10 04:50:43 +01:00
|
|
|
#define X(index, name, format) CREATE_GBUFFER_IMAGE(name, format, 0);
|
rt: draft direct light compute shader
it's bad:
direct light: 1.8ms, 183(184)v, 59(128)s, LDS=0, 2/16o
(-56 vgpr => +1 wavefront??)
also, thread group size = 16, 8, 1, wave64
while ray tracing pipeline = 8, 4, 1, wave32
2022-01-11 04:13:08 +01:00
|
|
|
// TODO better format for normals VK_FORMAT_R16G16B16A16_SNORM
|
|
|
|
// TODO make sure this format and usage is suppported
|
2022-01-28 04:14:56 +01:00
|
|
|
RAY_PRIMARY_OUTPUTS(X)
|
|
|
|
RAY_LIGHT_DIRECT_POLY_OUTPUTS(X)
|
|
|
|
RAY_LIGHT_DIRECT_POINT_OUTPUTS(X)
|
2022-01-10 04:50:43 +01:00
|
|
|
#undef X
|
|
|
|
#undef rgba8
|
|
|
|
#undef rgba32f
|
2022-01-10 05:02:27 +01:00
|
|
|
#undef rgba16f
|
2021-11-21 22:40:11 +01:00
|
|
|
CREATE_GBUFFER_IMAGE(diffuse_gi, VK_FORMAT_R16G16B16A16_SFLOAT, 0);
|
|
|
|
CREATE_GBUFFER_IMAGE(specular, VK_FORMAT_R16G16B16A16_SFLOAT, 0);
|
|
|
|
CREATE_GBUFFER_IMAGE(additive, VK_FORMAT_R16G16B16A16_SFLOAT, 0);
|
|
|
|
#undef CREATE_GBUFFER_IMAGE
|
2021-03-20 19:15:57 +01:00
|
|
|
}
|
|
|
|
|
2021-11-30 16:53:12 +01:00
|
|
|
gEngine.Cmd_AddCommand("vk_rtx_reload", reloadPipeline, "Reload RTX shader");
|
|
|
|
gEngine.Cmd_AddCommand("vk_rtx_reload_rad", reloadLighting, "Reload RAD files for static lights");
|
|
|
|
gEngine.Cmd_AddCommand("vk_rtx_freeze", freezeModels, "Freeze models, do not update/add/delete models from to-draw list");
|
2021-03-13 21:29:17 +01:00
|
|
|
|
2021-02-27 22:43:49 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-11-07 21:46:27 +01:00
|
|
|
void VK_RayShutdown( void ) {
|
2021-02-27 22:43:49 +01:00
|
|
|
ASSERT(vk_core.rtx);
|
2021-02-28 00:40:57 +01:00
|
|
|
|
2022-01-31 07:24:55 +01:00
|
|
|
RayPassDestroy(g_rtx.pass.denoiser);
|
2022-01-28 02:47:00 +01:00
|
|
|
RayPassDestroy(g_rtx.pass.light_direct_poly);
|
2022-01-28 04:14:56 +01:00
|
|
|
RayPassDestroy(g_rtx.pass.light_direct_point);
|
2022-01-27 08:52:14 +01:00
|
|
|
RayPassDestroy(g_rtx.pass.primary_ray);
|
2022-01-08 03:51:59 +01:00
|
|
|
|
2021-11-07 21:46:27 +01:00
|
|
|
for (int i = 0; i < ARRAYSIZE(g_rtx.frames); ++i) {
|
2021-11-21 22:40:11 +01:00
|
|
|
XVK_ImageDestroy(&g_rtx.frames[i].denoised);
|
2022-01-10 04:50:43 +01:00
|
|
|
#define X(index, name, ...) XVK_ImageDestroy(&g_rtx.frames[i].name);
|
2022-01-28 04:14:56 +01:00
|
|
|
RAY_PRIMARY_OUTPUTS(X)
|
|
|
|
RAY_LIGHT_DIRECT_POLY_OUTPUTS(X)
|
|
|
|
RAY_LIGHT_DIRECT_POINT_OUTPUTS(X)
|
2022-01-10 04:50:43 +01:00
|
|
|
#undef X
|
2021-11-21 22:40:11 +01:00
|
|
|
XVK_ImageDestroy(&g_rtx.frames[i].diffuse_gi);
|
|
|
|
XVK_ImageDestroy(&g_rtx.frames[i].specular);
|
|
|
|
XVK_ImageDestroy(&g_rtx.frames[i].additive);
|
2021-11-07 21:46:27 +01:00
|
|
|
}
|
2021-03-01 19:52:08 +01:00
|
|
|
|
2022-01-09 20:14:44 +01:00
|
|
|
VK_BufferDestroy(&g_ray_model_state.kusochki_buffer);
|
2022-01-18 08:04:06 +01:00
|
|
|
VK_BufferDestroy(&g_rtx.uniform_buffer);
|
2022-07-15 09:35:19 +02:00
|
|
|
|
2022-08-27 21:30:53 +02:00
|
|
|
RT_VkAccelShutdown();
|
2021-02-27 22:43:49 +01:00
|
|
|
}
|