diff --git a/ref_vk/vk_core.c b/ref_vk/vk_core.c index b8feadee..2026fd77 100644 --- a/ref_vk/vk_core.c +++ b/ref_vk/vk_core.c @@ -715,6 +715,9 @@ qboolean R_VkInit( void ) return false; VK_LightsInit(); + + if (!XVK_DenoiserInit()) + return false; } return true; @@ -724,6 +727,7 @@ void R_VkShutdown( void ) { if (vk_core.rtx) { + XVK_DenoiserDestroy(); VK_LightsShutdown(); VK_RayShutdown(); } diff --git a/ref_vk/vk_denoiser.c b/ref_vk/vk_denoiser.c new file mode 100644 index 00000000..077d56d0 --- /dev/null +++ b/ref_vk/vk_denoiser.c @@ -0,0 +1,58 @@ +#include "vk_denoiser.h" + +#include "eiface.h" // ARRAYSIZE + +static void blitImage( VkCommandBuffer cmdbuf, VkImage src, VkImage dst, int src_width, int src_height, int dst_width, int dst_height ) +{ + // Blit raytraced image to frame buffer + { + VkImageBlit region = {0}; + region.srcOffsets[1].x = src_width; + region.srcOffsets[1].y = src_height; + region.srcOffsets[1].z = 1; + region.dstOffsets[1].x = dst_width; + region.dstOffsets[1].y = dst_height; + region.dstOffsets[1].z = 1; + region.srcSubresource.aspectMask = region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.srcSubresource.layerCount = region.dstSubresource.layerCount = 1; + vkCmdBlitImage(cmdbuf, src, VK_IMAGE_LAYOUT_GENERAL, + dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion, + VK_FILTER_NEAREST); + } + + { + VkImageMemoryBarrier image_barriers[] = { + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .image = dst, + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .subresourceRange = + (VkImageSubresourceRange){ + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + }}; + vkCmdPipelineBarrier(cmdbuf, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + 0, 0, NULL, 0, NULL, ARRAYSIZE(image_barriers), image_barriers); + } +} + +void XVK_DenoiserDenoise( const xvk_denoiser_args_t* args ) { + // Blit RTX frame onto swapchain image + blitImage(args->cmdbuf, args->in.image, args->out.image, args->in.width, args->in.height, args->out.width, args->out.height); +} + +qboolean XVK_DenoiserInit( void ) { + return true; +} + +void XVK_DenoiserDestroy( void ) { +} diff --git a/ref_vk/vk_denoiser.h b/ref_vk/vk_denoiser.h new file mode 100644 index 00000000..1200948a --- /dev/null +++ b/ref_vk/vk_denoiser.h @@ -0,0 +1,22 @@ +#pragma once + +#include "vk_core.h" + +qboolean XVK_DenoiserInit( void ); +void XVK_DenoiserDestroy( void ); + +typedef struct { + VkCommandBuffer cmdbuf; + + struct { + VkImage image; + uint32_t width, height; + } in; + + struct { + VkImage image; + uint32_t width, height; + } out; +} xvk_denoiser_args_t; + +void XVK_DenoiserDenoise( const xvk_denoiser_args_t* args ); diff --git a/ref_vk/vk_rtx.c b/ref_vk/vk_rtx.c index e5367b1a..21815b32 100644 --- a/ref_vk/vk_rtx.c +++ b/ref_vk/vk_rtx.c @@ -9,6 +9,7 @@ #include "vk_light.h" #include "vk_descriptor.h" #include "vk_ray_internal.h" +#include "vk_denoiser.h" #include "eiface.h" #include "xash3d_mathlib.h" @@ -753,49 +754,6 @@ static void updateLights( void ) } } -static void blitImage( VkCommandBuffer cmdbuf, VkImage src, VkImage dst, int src_width, int src_height, int dst_width, int dst_height ) -{ - // Blit raytraced image to frame buffer - { - VkImageBlit region = {0}; - region.srcOffsets[1].x = src_width; - region.srcOffsets[1].y = src_height; - region.srcOffsets[1].z = 1; - region.dstOffsets[1].x = dst_width; - region.dstOffsets[1].y = dst_height; - region.dstOffsets[1].z = 1; - region.srcSubresource.aspectMask = region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - region.srcSubresource.layerCount = region.dstSubresource.layerCount = 1; - vkCmdBlitImage(cmdbuf, src, VK_IMAGE_LAYOUT_GENERAL, - dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion, - VK_FILTER_NEAREST); - } - - { - VkImageMemoryBarrier image_barriers[] = { - { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .image = dst, - .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .subresourceRange = - (VkImageSubresourceRange){ - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - }}; - vkCmdPipelineBarrier(cmdbuf, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - 0, 0, NULL, 0, NULL, ARRAYSIZE(image_barriers), image_barriers); - } -} - static void clearVkImage( VkCommandBuffer cmdbuf, VkImage image ) { const VkImageMemoryBarrier image_barriers[] = { { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, @@ -921,8 +879,24 @@ void VK_RayFrameEnd(const vk_ray_frame_render_args_t* args) } } - // Blit RTX frame onto swapchain image - blitImage(cmdbuf, frame_src->image, args->dst.image, FRAME_WIDTH, FRAME_HEIGHT, args->dst.width, args->dst.height); + { + const xvk_denoiser_args_t denoiser_args = { + .cmdbuf = cmdbuf, + .in = { + .image = frame_src->image, + .width = FRAME_WIDTH, + .height = FRAME_HEIGHT, + }, + .out = { + .image = args->dst.image, + .width = args->dst.width, + .height = args->dst.height, + }, + }; + + XVK_DenoiserDenoise( &denoiser_args ); + } + } static void createLayouts( void ) {