diff --git a/ref_vk/TODO.md b/ref_vk/TODO.md index 69ce8b0c..773dcd1e 100644 --- a/ref_vk/TODO.md +++ b/ref_vk/TODO.md @@ -4,20 +4,24 @@ - [x] remove types from resources FIXME - [x] E214: ~tentative~ - [x] integrate sebastian into waf -- [ ] E215: - - [ ] serialize binding image format - - [ ] serialize all resources with in/out and formats for images +- [x] E215: + - [x] serialize binding image format +- [ ] E216: + - [ ] meatpipe resource tracking + - [ ] name -> index mapping + - [x] validate image formats - [ ] create images on meatpipe load + - [ ] begin Rake Yuri migration ->E215 +>=E217 - [ ] automatic resource creation + - [ ] serialize all resources with in/out and formats for images - [ ] resource management refactoring: - [ ] resource object: name, metadata(type, etc.), producer, status (ready, barriers, etc) - [ ] resource automatic resolution: prducing, barriers, etc - [ ] register existing resources (tlas, buffers, temp images, ...) - [ ] resource destruction - [ ] create resources on demand -- [ ] Rake Yuri # Programmable render - [x] parse spirv -> get bindings with names diff --git a/ref_vk/ray_resources.c b/ref_vk/ray_resources.c index 7d672d48..9d13035b 100644 --- a/ref_vk/ray_resources.c +++ b/ref_vk/ray_resources.c @@ -1,6 +1,8 @@ #include "ray_resources.h" #include "vk_core.h" +#include "shaders/ray_interop.h" // FIXME temp for type validation + #include #define MAX_BARRIERS 16 @@ -95,46 +97,74 @@ void RayResourcesFill(VkCommandBuffer cmdbuf, ray_resources_fill_t fill) { 0, 0, NULL, 0, NULL, image_barriers_count, image_barriers); } } - -#define FIXME_DESC(name_, semantic_, count_) \ - { .name = name_, \ - .desc.semantic = (RayResource_##semantic_ + 1), \ - .desc.count = count_, \ - } - static const struct { const char *name; + ray_resource_type_e type; + int image_format; ray_resource_binding_desc_fixme_t desc; } fixme_descs[] = { + +#define FIXME_DESC_BUFFER(name_, semantic_, count_) \ + { .name = name_, \ + .type = ResourceBuffer, \ + .desc.semantic = (RayResource_##semantic_ + 1), \ + .desc.count = count_, \ + } + // External - FIXME_DESC("ubo", ubo, 1), - FIXME_DESC("tlas", tlas, 1), - FIXME_DESC("kusochki", kusochki, 1), - FIXME_DESC("indices", indices, 1), - FIXME_DESC("vertices", vertices, 1), - FIXME_DESC("textures", all_textures, MAX_TEXTURES), - FIXME_DESC("skybox", skybox, 1), - FIXME_DESC("lights", lights, 1), - FIXME_DESC("light_clusters", light_clusters, 1), - FIXME_DESC("light_grid", light_clusters, 1), - FIXME_DESC("dest", denoised, 1), + 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_) \ + { .name = name_, \ + .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 - FIXME_DESC("base_color_a", base_color_a, 1), - FIXME_DESC("position_t", position_t, 1), - FIXME_DESC("normals_gs", normals_gs, 1), - FIXME_DESC("material_rmxx", material_rmxx, 1), - FIXME_DESC("emissive", emissive, 1), - FIXME_DESC("light_poly_diffuse", light_poly_diffuse, 1), - FIXME_DESC("light_poly_specular", light_poly_specular, 1), - FIXME_DESC("light_point_diffuse", light_point_diffuse, 1), - FIXME_DESC("light_point_specular", light_point_specular, 1), +#define DECLARE_IMAGE(_, name_, format_) \ + { .name = #name_, \ + .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) }; -const ray_resource_binding_desc_fixme_t *RayResouceGetBindingForName_FIXME(const char *name) { +const ray_resource_binding_desc_fixme_t *RayResouceGetBindingForName_FIXME(const char *name, ray_resource_desc_t desc) { for (int i = 0; i < COUNTOF(fixme_descs); ++i) { - if (strcmp(name, fixme_descs[i].name) == 0) - return &fixme_descs[i].desc; + if (strcmp(name, fixme_descs[i].name) != 0) + continue; + + if (fixme_descs[i].type != desc.type) { + gEngine.Con_Printf(S_ERROR "Incompatible resource types for name %s: want %d, have %d\n", name, desc.type, fixme_descs[i].type); + return NULL; + } + + if (fixme_descs[i].type == ResourceImage && fixme_descs[i].image_format != VK_FORMAT_UNDEFINED && desc.image_format != fixme_descs[i].image_format) { + gEngine.Con_Printf(S_ERROR "Incompatible image formats for name %s: want %d, have %d\n", name, desc.image_format, fixme_descs[i].image_format); + return NULL; + } + + return &fixme_descs[i].desc; } return NULL; } diff --git a/ref_vk/ray_resources.h b/ref_vk/ray_resources.h index 2451fd66..2fe6b1b6 100644 --- a/ref_vk/ray_resources.h +++ b/ref_vk/ray_resources.h @@ -65,4 +65,15 @@ typedef struct { int count; } ray_resource_binding_desc_fixme_t; -const ray_resource_binding_desc_fixme_t *RayResouceGetBindingForName_FIXME(const char *name); +typedef enum { + ResourceUnknown, + ResourceBuffer, + ResourceImage, +} ray_resource_type_e; + +typedef struct { + ray_resource_type_e type; + int image_format; // if type == ResourceImage +} ray_resource_desc_t; + +const ray_resource_binding_desc_fixme_t *RayResouceGetBindingForName_FIXME(const char *name, ray_resource_desc_t desc); diff --git a/ref_vk/sebastian.py b/ref_vk/sebastian.py index a56ff2bd..0904e929 100755 --- a/ref_vk/sebastian.py +++ b/ref_vk/sebastian.py @@ -102,6 +102,33 @@ class Serializer: else: i.serialize(self) +class ImageFormat: + VK_FORMAT_UNDEFINED = 0 + VK_FORMAT_R8G8B8A8_UNORM = 37 + VK_FORMAT_R16G16B16A16_SFLOAT = 97 + VK_FORMAT_R32G32B32A32_SFLOAT = 109 + + __map = { + 'Unknown': VK_FORMAT_UNDEFINED, + 'Rgba32f' : VK_FORMAT_R32G32B32A32_SFLOAT, + 'Rgba16f' : VK_FORMAT_R16G16B16A16_SFLOAT, + 'Rgba8' : VK_FORMAT_R8G8B8A8_UNORM, + # TODO map more + } + + __revmap = None + + def mapToVk(fmt): + if not ImageFormat.__revmap: + revmap = {} + formats = spv['ImageFormat'] + for k, v in formats.items(): + if k in ImageFormat.__map: + revmap[v] = ImageFormat.__map[k] + ImageFormat.__revmap = revmap + + return ImageFormat.__revmap[fmt] + class TypeInfo: TYPE_SAMPLER = 0 TYPE_COMBINED_IMAGE_SAMPLER = 1 @@ -145,7 +172,7 @@ class TypeInfo: def serialize(self, out): out.writeU32(self.type) if self.is_image: - out.writeU32(self.image_format) + out.writeU32(ImageFormat.mapToVk(self.image_format)) class SpirvNode: def __init__(self): diff --git a/ref_vk/vk_meatpipe.c b/ref_vk/vk_meatpipe.c index 711d606a..8f0ced44 100644 --- a/ref_vk/vk_meatpipe.c +++ b/ref_vk/vk_meatpipe.c @@ -20,8 +20,8 @@ typedef struct { typedef struct { char name[64]; uint32_t type; - qboolean is_image; - uint32_t image_format; + int count; + int semantic; } res_t; typedef struct { @@ -193,22 +193,16 @@ static int readBindings(load_context_t *ctx, VkDescriptorSetLayoutBinding *bindi const char *name = res->name; - const ray_resource_binding_desc_fixme_t *binding_fixme = RayResouceGetBindingForName_FIXME(name); - if (!binding_fixme) { - gEngine.Con_Printf(S_ERROR "Couldn't find fixme desc for binding %s\n", name); - return 0; - } - bindings[i] = (VkDescriptorSetLayoutBinding){ .binding = binding, .descriptorType = res->type, - .descriptorCount = binding_fixme->count, + .descriptorCount = res->count, .stageFlags = stages, .pImmutableSamplers = NULL, }; - semantics[i] = write ? -binding_fixme->semantic : binding_fixme->semantic; + semantics[i] = write ? -res->semantic : res->semantic; - gEngine.Con_Reportf("Binding %d: %s ds=%d b=%d s=%08x res=%d type=%d semantic=%d\n", i, name, descriptor_set, binding, stages, res_index, res->type, binding_fixme->semantic); + gEngine.Con_Reportf("Binding %d: %s ds=%d b=%d s=%08x res=%d type=%d semantic=%d\n", i, name, descriptor_set, binding, stages, res_index, res->type, res->semantic); } return count; @@ -263,13 +257,28 @@ static qboolean readResources(load_context_t *ctx) { res->type = READ_U32("Couldn't read resource %d:%s type", i, res->name); - res->is_image = res->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || res->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + const qboolean is_image = res->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || res->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - if (res->is_image) { - res->image_format = READ_U32("Couldn't read image format for res %d:%s", i, res->name); + ray_resource_desc_t rrdesc = { + .type = is_image ? ResourceImage : ResourceBuffer, + .image_format = VK_FORMAT_UNDEFINED, + }; + + + if (is_image) { + rrdesc.image_format = READ_U32("Couldn't read image format for res %d:%s", i, res->name); } - gEngine.Con_Reportf("Resource %d:%s = %08x is_image=%d image_format=%08x\n", i, res->name, res->type, res->is_image, res->image_format); + const ray_resource_binding_desc_fixme_t *binding_fixme = RayResouceGetBindingForName_FIXME(res->name, rrdesc); + if (!binding_fixme) { + gEngine.Con_Printf(S_ERROR "Couldn't find fixme desc for binding %s\n", res->name); + return 0; + } + + res->count = binding_fixme->count; + res->semantic = binding_fixme->semantic; + + gEngine.Con_Reportf("Resource %d:%s = %08x is_image=%d image_format=%08x count=%d semantic=%d\n", i, res->name, res->type, is_image, rrdesc.image_format, res->count, res->semantic); } return true;