rt: tie pass binding to resource semantic

this allows removing pass write function and moves us closer to
auto-solving pass dependencies
This commit is contained in:
Ivan Avdeev 2022-01-30 20:49:37 -08:00
parent 6c6e6e191d
commit 950b1ff6cf
5 changed files with 76 additions and 105 deletions

View File

@ -12,8 +12,8 @@ typedef struct ray_pass_s {
struct {
vk_descriptors_t riptors;
ray_pass_write_values_f write_values_func;
VkDescriptorSet sets[1];
int *binding_semantics;
} desc;
union {
@ -150,8 +150,12 @@ static ray_pass_t *createRayPass( const ray_pass_create_t *create ) {
}
pass->desc.riptors.values = Mem_Malloc(vk_core.pool, sizeof(pass->desc.riptors.values[0]) * create->layout.bindings_count);
pass->desc.write_values_func = create->layout.write_values_func;
ASSERT(create->layout.write_values_func);
{
const size_t semantics_size = sizeof(int) * create->layout.bindings_count;
pass->desc.binding_semantics = Mem_Malloc(vk_core.pool, semantics_size);
memcpy(pass->desc.binding_semantics, create->layout.bindings_semantics, semantics_size);
}
return pass;
}
@ -169,7 +173,14 @@ void RayPassDestroy( struct ray_pass_s *pass ) {
void RayPassPerform( VkCommandBuffer cmdbuf, struct ray_pass_s *pass, const struct vk_ray_resources_s *res) {
pass->desc.write_values_func( pass->desc.riptors.values, res );
for (int i = 0; i < pass->desc.riptors.num_bindings; ++i) {
const int res_index = pass->desc.binding_semantics[i];
// TODO check early
ASSERT(res_index >= 0);
ASSERT(res_index < RayResource__COUNT);
pass->desc.riptors.values[i] = res->values[res_index];
}
VK_DescriptorsWrite(&pass->desc.riptors);
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pass->tracing.pipeline);

View File

@ -33,17 +33,12 @@ typedef struct {
// - parse the entire layout from shaders
// - expose it as a struct[] interface of the pass
// - resource/interface should prepare descriptors outside of pass code and just pass them to pass
struct vk_ray_resources_s;
typedef void (*ray_pass_write_values_f)( vk_descriptor_value_t *values, const struct vk_ray_resources_s *resources );
// TODO parse this out from shaders
typedef struct {
VkDescriptorSetLayoutBinding *bindings;
const int *bindings_semantics; // RayResource_something
const VkDescriptorSetLayoutBinding *bindings;
int bindings_count;
VkPushConstantRange push_constants;
ray_pass_write_values_f write_values_func;
} ray_pass_layout_t;
typedef struct {

View File

@ -34,7 +34,7 @@ typedef union {
typedef struct {
int num_bindings;
VkDescriptorSetLayoutBinding *bindings;
const VkDescriptorSetLayoutBinding *bindings;
// Used in Write only
vk_descriptor_value_t *values;

View File

@ -3,53 +3,54 @@
#include "vk_ray_resources.h"
#include "ray_pass.h"
#define LIST_SCENE_BINDINGS(X) \
X(1, tlas, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1) \
X(2, ubo, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1) \
X(3, kusochki, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1) \
X(4, indices, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1) \
X(5, vertices, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1) \
X(6, all_textures, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MAX_TEXTURES) \
X(7, lights, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1) \
X(8, light_clusters, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1) \
#define LIST_COMMON_BINDINGS(X) \
LIST_SCENE_BINDINGS(X) \
RAY_LIGHT_DIRECT_INPUTS(X)
enum {
// TODO set 0 ?
RtLDir_Desc_tlas,
RtLDir_Desc_ubo,
RtLDir_Desc_kusochki,
RtLDir_Desc_indices,
RtLDir_Desc_vertices,
RtLDir_Desc_all_textures,
// TODO set 1
RtLDir_Desc_lights,
RtLDir_Desc_light_clusters,
// TODO set 1
#define X(index, name, ...) RtLDir_Desc_##name,
RAY_LIGHT_DIRECT_INPUTS(X)
#define X(index, name, ...) Binding_##name,
LIST_COMMON_BINDINGS(X)
// FIXME it's an artifact that point and poly outputs have same bindings indices
RAY_LIGHT_DIRECT_POLY_OUTPUTS(X)
#undef X
// FIXME it's an artifact that point and poly outputs have same bindings
#define X(index, name, ...) RtLDir_Desc_##name,
RAY_LIGHT_DIRECT_POLY_OUTPUTS(X)
#undef X
RtLDir_Desc_COUNT
Binding__COUNT
};
static VkDescriptorSetLayoutBinding bindings[RtLDir_Desc_COUNT];
static VkDescriptorSetLayoutBinding bindings[Binding__COUNT];
static const int semantics_poly[Binding__COUNT] = {
#define X(index, name, ...) RayResource_##name,
LIST_COMMON_BINDINGS(X)
RAY_LIGHT_DIRECT_POLY_OUTPUTS(X)
#undef X
};
static const int semantics_point[Binding__COUNT] = {
#define X(index, name, ...) RayResource_##name,
LIST_COMMON_BINDINGS(X)
RAY_LIGHT_DIRECT_POINT_OUTPUTS(X)
#undef X
};
static void initDescriptors( void ) {
// FIXME more conservative shader stages
#define INIT_BINDING(index, name, type, count) \
bindings[RtLDir_Desc_##name] = (VkDescriptorSetLayoutBinding){ \
bindings[Binding_##name] = (VkDescriptorSetLayoutBinding){ \
.binding = index, \
.descriptorType = type, \
.descriptorCount = count, \
.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR, \
}
INIT_BINDING(1, tlas, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1);
INIT_BINDING(2, ubo, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1);
INIT_BINDING(3, kusochki, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1);
INIT_BINDING(4, indices, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1);
INIT_BINDING(5, vertices, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1);
INIT_BINDING(6, all_textures, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MAX_TEXTURES);
INIT_BINDING(7, lights, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1);
INIT_BINDING(8, light_clusters, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1);
};
LIST_SCENE_BINDINGS(INIT_BINDING)
#define X(index, name, ...) INIT_BINDING(index, name, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1);
RAY_LIGHT_DIRECT_INPUTS(X)
RAY_LIGHT_DIRECT_POLY_OUTPUTS(X)
@ -57,22 +58,6 @@ static void initDescriptors( void ) {
#undef INIT_BINDING
}
static void writeValues( vk_descriptor_value_t *values, const vk_ray_resources_t* res ) {
#define X(index, name, ...) \
values[RtLDir_Desc_##name] = res->values[RayResource_##name];
RAY_LIGHT_DIRECT_INPUTS(X)
RAY_LIGHT_DIRECT_POLY_OUTPUTS(X)
X(-1, tlas)
X(-1, ubo);
X(-1, kusochki);
X(-1, indices);
X(-1, vertices);
X(-1, all_textures);
X(-1, lights);
X(-1, light_clusters);
#undef X
}
struct ray_pass_s *R_VkRayLightDirectPolyPassCreate( void ) {
// FIXME move this into vk_pipeline
const struct SpecializationData {
@ -104,8 +89,8 @@ struct ray_pass_s *R_VkRayLightDirectPolyPassCreate( void ) {
.debug_name = "light direct poly",
.layout = {
.bindings = bindings,
.bindings_semantics = semantics_poly,
.bindings_count = COUNTOF(bindings),
.write_values_func = writeValues,
.push_constants = {0},
},
.tracing = {
@ -122,12 +107,6 @@ struct ray_pass_s *R_VkRayLightDirectPolyPassCreate( void ) {
return RayPassCreate( &rpc );
}
static void writePointValues( vk_descriptor_value_t *values, const vk_ray_resources_t* res ) {
writeValues( values, res );
values[RtLDir_Desc_light_poly_diffuse] = res->values[RayResource_light_point_diffuse];
values[RtLDir_Desc_light_poly_specular] = res->values[RayResource_light_point_specular];
}
struct ray_pass_s *R_VkRayLightDirectPointPassCreate( void ) {
// FIXME move this into vk_pipeline
const struct SpecializationData {
@ -159,8 +138,8 @@ struct ray_pass_s *R_VkRayLightDirectPointPassCreate( void ) {
.debug_name = "light direct point",
.layout = {
.bindings = bindings,
.bindings_semantics = semantics_point,
.bindings_count = COUNTOF(bindings),
.write_values_func = writePointValues,
.push_constants = {0},
},
.tracing = {

View File

@ -3,24 +3,30 @@
#include "vk_ray_resources.h"
#include "ray_pass.h"
enum {
// TODO set 0
RtPrim_Desc_tlas,
RtPrim_Desc_ubo,
RtPrim_Desc_kusochki,
RtPrim_Desc_indices,
RtPrim_Desc_vertices,
RtPrim_Desc_all_textures,
#define LIST_COMMON_BINDINGS(X) \
X(1, tlas, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR) \
X(2, ubo, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR) \
X(3, kusochki, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR) \
X(4, indices, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR) \
X(5, vertices, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR) \
X(6, all_textures, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MAX_TEXTURES, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR) \
// TODO set 1
enum {
#define X(index, name, ...) RtPrim_Desc_##name,
RAY_PRIMARY_OUTPUTS(X)
LIST_COMMON_BINDINGS(X)
RAY_PRIMARY_OUTPUTS(X)
#undef X
RtPrim_Desc_COUNT
};
static VkDescriptorSetLayoutBinding bindings[RtPrim_Desc_COUNT];
static const int semantics[RtPrim_Desc_COUNT] = {
#define X(index, name, ...) RayResource_##name,
LIST_COMMON_BINDINGS(X)
RAY_PRIMARY_OUTPUTS(X)
#undef X
};
static void initDescriptors( void ) {
#define INIT_BINDING(index, name, type, count, stages) \
@ -29,35 +35,15 @@ static void initDescriptors( void ) {
.descriptorType = type, \
.descriptorCount = count, \
.stageFlags = stages, \
}
INIT_BINDING(1, tlas, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR);
INIT_BINDING(2, ubo, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
INIT_BINDING(3, kusochki, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
INIT_BINDING(4, indices, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
INIT_BINDING(5, vertices, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
INIT_BINDING(6, all_textures, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MAX_TEXTURES, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
};
LIST_COMMON_BINDINGS(INIT_BINDING)
#define X(index, name, ...) \
INIT_BINDING(index, name, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR);
INIT_BINDING(index, name, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR);
RAY_PRIMARY_OUTPUTS(X)
#undef X
#undef INIT_BINDING
}
static void writeValues( vk_descriptor_value_t *values, const vk_ray_resources_t* res ) {
#define X(index, name, ...) \
values[RtPrim_Desc_##name] = res->values[RayResource_##name];
RAY_PRIMARY_OUTPUTS(X)
X(-1, tlas)
X(-1, ubo);
X(-1, kusochki);
X(-1, indices);
X(-1, vertices);
X(-1, all_textures);
#undef X
}
struct ray_pass_s *R_VkRayPrimaryPassCreate( void ) {
// FIXME move this into vk_pipeline or something
const struct SpecializationData {
@ -92,8 +78,8 @@ struct ray_pass_s *R_VkRayPrimaryPassCreate( void ) {
.debug_name = "primary ray",
.layout = {
.bindings = bindings,
.bindings_semantics = semantics,
.bindings_count = COUNTOF(bindings),
.write_values_func = writeValues,
.push_constants = {0},
},
.tracing = {