rt: make it paint things again

missing:
- proper resource destruction at exit and at meatpipe recreation time
This commit is contained in:
Ivan 'provod' Avdeev 2023-01-21 13:03:57 -08:00
parent 3e194c7c6d
commit 3b77a84746
6 changed files with 80 additions and 122 deletions

View File

@ -251,19 +251,16 @@ static void performCompute( VkCommandBuffer cmdbuf, int set_slot, const ray_pass
}
void RayPassPerform(struct ray_pass_s *pass, VkCommandBuffer cmdbuf, ray_pass_perform_args_t args ) {
for (int i = 0; i < pass->desc.riptors.num_bindings; ++i) {
vk_resource_p resource = args.resources[args.resources_map ? args.resources_map[i] : i];
vk_descriptor_value_t *value = pass->desc.riptors.values + i;
R_VkResourceWriteToDescriptorValue(cmdbuf,
(vk_resource_write_descriptor_args_t){
.pipeline = pass->pipeline_type,
.resource = resource,
.value = value,
.write = i >= pass->desc.write_from,
}
);
}
R_VkResourcesPrepareDescriptorsValues(cmdbuf,
(vk_resources_write_descriptors_args_t){
.pipeline = pass->pipeline_type,
.resources = args.resources,
.resources_map = args.resources_map,
.values = pass->desc.riptors.values,
.count = pass->desc.riptors.num_bindings,
.write_begin = pass->desc.write_from,
}
);
VK_DescriptorsWrite(&pass->desc.riptors, args.frame_set_slot);

View File

@ -1,5 +1,6 @@
#include "ray_resources.h"
#include "vk_core.h"
#include "vk_image.h"
#include "shaders/ray_interop.h" // FIXME temp for type validation
@ -7,19 +8,19 @@
#define MAX_BARRIERS 16
#if 0
void RayResourcesFill(VkCommandBuffer cmdbuf, ray_resources_fill_t fill) {
void R_VkResourcesPrepareDescriptorsValues(VkCommandBuffer cmdbuf, vk_resources_write_descriptors_args_t args) {
VkImageMemoryBarrier image_barriers[MAX_BARRIERS];
int image_barriers_count = 0;
VkPipelineStageFlags src_stage_mask = VK_PIPELINE_STAGE_NONE_KHR;
for (int i = 0; i < fill.count; ++i) {
const qboolean write = fill.indices[i] < 0;
const int index = abs(fill.indices[i]) - 1;
ray_resource_t *const res = g_resources.resources + index;
for (int i = 0; i < args.count; ++i) {
const int index = args.resources_map ? args.resources_map[i] : i;
vk_resource_t* const res = args.resources[index];
ASSERT(index >= 0);
ASSERT(index < RayResource__COUNT);
const vk_descriptor_value_t *const src_value = &res->value;
vk_descriptor_value_t *const dst_value = args.values + i;
const qboolean write = i >= args.write_begin;
if (res->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
if (write) {
@ -29,12 +30,12 @@ void RayResourcesFill(VkCommandBuffer cmdbuf, ray_resources_fill_t fill) {
res->write = (ray_resource_state_t) {
.access_mask = VK_ACCESS_SHADER_WRITE_BIT,
.image_layout = VK_IMAGE_LAYOUT_GENERAL,
.pipelines = fill.dest_pipeline,
.pipelines = args.pipeline,
};
image_barriers[image_barriers_count++] = (VkImageMemoryBarrier) {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.image = res->image->image,
.image = src_value->image_object->image,
.srcAccessMask = 0,
.dstAccessMask = res->write.access_mask,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
@ -53,16 +54,16 @@ void RayResourcesFill(VkCommandBuffer cmdbuf, ray_resources_fill_t fill) {
ASSERT(res->write.pipelines != 0);
// No barrier was issued
if (!(res->read.pipelines & fill.dest_pipeline)) {
if (!(res->read.pipelines & args.pipeline)) {
res->read.access_mask = VK_ACCESS_SHADER_READ_BIT;
res->read.pipelines |= fill.dest_pipeline;
res->read.pipelines |= args.pipeline;
res->read.image_layout = VK_IMAGE_LAYOUT_GENERAL;
src_stage_mask |= res->write.pipelines;
image_barriers[image_barriers_count++] = (VkImageMemoryBarrier) {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.image = res->image->image,
.image = src_value->image_object->image,
.srcAccessMask = res->write.access_mask,
.dstAccessMask = res->read.access_mask,
.oldLayout = res->write.image_layout,
@ -77,13 +78,14 @@ void RayResourcesFill(VkCommandBuffer cmdbuf, ray_resources_fill_t fill) {
};
}
}
fill.out_values[i].image = (VkDescriptorImageInfo) {
dst_value->image = (VkDescriptorImageInfo) {
.imageLayout = write ? res->write.image_layout : res->read.image_layout,
.imageView = res->image->view,
.imageView = src_value->image_object->view,
.sampler = VK_NULL_HANDLE,
};
} else {
fill.out_values[i] = res->value;
*dst_value = *src_value;
}
}
@ -93,87 +95,8 @@ void RayResourcesFill(VkCommandBuffer cmdbuf, ray_resources_fill_t fill) {
vkCmdPipelineBarrier(cmdbuf,
src_stage_mask,
fill.dest_pipeline,
args.pipeline,
0, 0, NULL, 0, NULL, image_barriers_count, image_barriers);
}
}
#if 0
static const struct {
ray_resource_binding_desc_fixme_t desc;
} fixme_descs[] = {
#define FIXME_DESC_BUFFER(name_, semantic_, count_) \
{ \
.type = ResourceBuffer, \
.desc.semantic = (RayResource_##semantic_ + 1), \
.desc.count = count_, \
}
// External
FIXME_DESC_BUFFER("ubo", ubo, 1),
FIXME_DESC_BUFFER("tlas", tlas, 1),
FIXME_DESC_BUFFER("kusochki", kusochki, 1),
FIXME_DESC_BUFFER("indices", indices, 1),
FIXME_DESC_BUFFER("vertices", vertices, 1),
FIXME_DESC_BUFFER("lights", lights, 1),
FIXME_DESC_BUFFER("light_clusters", light_clusters, 1),
FIXME_DESC_BUFFER("light_grid", light_clusters, 1),
#define FIXME_DESC_IMAGE(name_, semantic_, image_format_, count_) \
{ \
.type = ResourceImage, \
.image_format = image_format_, \
.desc.semantic = (RayResource_##semantic_ + 1), \
.desc.count = count_, \
}
FIXME_DESC_IMAGE("textures", all_textures, VK_FORMAT_UNDEFINED, MAX_TEXTURES),
FIXME_DESC_IMAGE("skybox", skybox, VK_FORMAT_UNDEFINED, 1),
FIXME_DESC_IMAGE("dest", denoised, VK_FORMAT_UNDEFINED,1),
// Internal, temporary
#define DECLARE_IMAGE(_, name_, format_) \
{ \
.type = ResourceImage, \
.image_format = format_, \
.desc.semantic = (RayResource_##name_ + 1), \
.desc.count = 1, \
},
#define rgba8 VK_FORMAT_R8G8B8A8_UNORM
#define rgba32f VK_FORMAT_R32G32B32A32_SFLOAT
#define rgba16f VK_FORMAT_R16G16B16A16_SFLOAT
RAY_PRIMARY_OUTPUTS(DECLARE_IMAGE)
RAY_LIGHT_DIRECT_POLY_OUTPUTS(DECLARE_IMAGE)
RAY_LIGHT_DIRECT_POINT_OUTPUTS(DECLARE_IMAGE)
};
#endif
/*
ray_resource_binding_desc_fixme_t RayResouceGetBindingForName_FIXME(const char *name, ray_resource_desc_t desc) {
for (int i = 0; i < MAX_RESOURCES; ++i) {
const vk_named_resource_t *const res = g_resources.named + i;
if (strcmp(name, res->name) != 0)
continue;
if (res->desc_fixme.type != desc.type) {
gEngine.Con_Printf(S_ERROR "Incompatible resource types for name %s: want %d, have %d\n", name, desc.type, res->desc_fixme.type);
break;
}
if (res->desc_fixme.type == ResourceImage && res->desc_fixme.image_format != VK_FORMAT_UNDEFINED && desc.image_format != res->desc_fixme.image_format) {
gEngine.Con_Printf(S_ERROR "Incompatible image formats for name %s: want %d, have %d\n", name, desc.image_format, res->desc_fixme.image_format);
break;
}
return (ray_resource_binding_desc_fixme_t){i, res->count};
}
return (ray_resource_binding_desc_fixme_t){-1,-1};
}
*/
#endif
void R_VkResourceWriteToDescriptorValue(VkCommandBuffer cmdbuf, vk_resource_write_descriptor_args_t args) {
ASSERT(!"Not implemented");
}

View File

@ -20,9 +20,13 @@ typedef struct vk_resource_s *vk_resource_p;
typedef struct {
VkPipelineStageFlagBits pipeline;
vk_resource_p resource;
vk_descriptor_value_t* value;
qboolean write;
} vk_resource_write_descriptor_args_t;
const vk_resource_p *resources;
const int *resources_map;
vk_descriptor_value_t* values;
int count;
int write_begin; // Entries starting at this index are written into by the pass
} vk_resources_write_descriptors_args_t;
void R_VkResourcesPrepareDescriptorsValues(VkCommandBuffer cmdbuf, vk_resources_write_descriptors_args_t args);
void R_VkResourceWriteToDescriptorValue(VkCommandBuffer cmdbuf, vk_resource_write_descriptor_args_t args);

View File

@ -25,11 +25,13 @@ extern descriptor_pool_t vk_desc;
qboolean VK_DescriptorInit( void );
void VK_DescriptorShutdown( void );
struct xvk_image_s;
typedef union {
VkDescriptorBufferInfo buffer;
VkDescriptorImageInfo image;
VkDescriptorImageInfo *image_array;
VkWriteDescriptorSetAccelerationStructureKHR accel;
const struct xvk_image_s *image_object;
} vk_descriptor_value_t;
typedef struct {

View File

@ -2,7 +2,7 @@
#include "vk_core.h"
#include "vk_devmem.h"
typedef struct {
typedef struct xvk_image_s {
vk_devmem_t devmem;
VkImage image;
VkImageView view;

View File

@ -228,6 +228,15 @@ static void performTracing(VkCommandBuffer cmdbuf, const perform_tracing_args_t*
0, 0, NULL, ARRAYSIZE(bmb), bmb, 0, NULL);
}
// Clear intra-frame resources
for (int i = ExternalResource_COUNT; i < MAX_RESOURCES; ++i) {
rt_resource_t* const res = g_rtx.res + i;
if (!res->name[0] || !res->image.image)
continue;
res->resource.read = res->resource.write = (ray_resource_state_t){0};
}
DEBUG_BEGIN(cmdbuf, "yay tracing");
RT_VkAccelPrepareTlas(cmdbuf);
prepareUniformBuffer(args->render_args, args->frame_index, args->fov_angle_y);
@ -265,7 +274,12 @@ static void performTracing(VkCommandBuffer cmdbuf, const perform_tracing_args_t*
0, 0, NULL, ARRAYSIZE(bmb), bmb, 0, NULL);
}
// FIXME R_VkMeatpipePerform(&g_rtx.mainpipe, cmdbuf, args->frame_index, &res);
R_VkMeatpipePerform(g_rtx.mainpipe, cmdbuf, (vk_meatpipe_perfrom_args_t) {
.frame_set_slot = args->frame_index,
.width = FRAME_WIDTH,
.height = FRAME_HEIGHT,
.resources = g_rtx.mainpipe_resources,
});
{
const r_vkimage_blit_args blit_args = {
@ -310,6 +324,9 @@ static void reloadMainpipe(void) {
const qboolean create = !!(mr->flags & MEATPIPE_RES_CREATE);
// FIXME no assert, just complain
ASSERT(!create || mr->descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
// FIXME this should be specified as a flag, from rt.json
const qboolean output = Q_strcmp("dest", mr->name) == 0;
@ -319,10 +336,12 @@ static void reloadMainpipe(void) {
goto fail;
}
if (output)
newpipe_out = g_rtx.res + index;
rt_resource_t *const res = g_rtx.res + index;
if (create && g_rtx.res[index].image.image == VK_NULL_HANDLE) {
if (output)
newpipe_out = res;
if (create && res->image.image == VK_NULL_HANDLE) {
const xvk_image_create_t create = {
.debug_name = mr->name,
.width = FRAME_WIDTH,
@ -335,11 +354,22 @@ static void reloadMainpipe(void) {
.has_alpha = true,
.is_cubemap = false,
};
g_rtx.res[index].image = XVK_ImageCreate(&create);
Q_strncpy(g_rtx.res[index].name, mr->name, sizeof(g_rtx.res[index].name));
res->image = XVK_ImageCreate(&create);
Q_strncpy(res->name, mr->name, sizeof(res->name));
}
newpipe_resources[i] = &g_rtx.res[index].resource;
newpipe_resources[i] = &res->resource;
if (create) {
if (mr->descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
newpipe_resources[i]->value.image_object = &res->image;
res->resource.type = mr->descriptor_type;
} else {
// TODO no assert, complain and exit
// can't do before all resources are properly registered by their producers and not all this temp crap we have right now
// ASSERT(res->resource.type == mr->descriptor_type);
}
}
if (!newpipe_out) {
@ -360,6 +390,8 @@ static void reloadMainpipe(void) {
g_rtx.mainpipe_resources = newpipe_resources;
g_rtx.mainpipe_out = newpipe_out;
return;
fail:
if (newpipe_resources) {
for (int i = 0; i < newpipe->resources_count; ++i) {