Skip to content

Commit

Permalink
Add SPV_GOOGLE_user_type support (#247)
Browse files Browse the repository at this point in the history
  • Loading branch information
spencer-lunarg authored Jan 12, 2024
1 parent be73aee commit 42878ed
Show file tree
Hide file tree
Showing 9 changed files with 561 additions and 3 deletions.
63 changes: 63 additions & 0 deletions common/output_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,65 @@ std::string ToStringSpvImageFormat(SpvImageFormat fmt) {
return "???";
}

std::string ToStringUserType(SpvReflectUserType user_type) {
switch (user_type) {
case SPV_REFLECT_USER_TYPE_CBUFFER:
return "cbuffer";
case SPV_REFLECT_USER_TYPE_TBUFFER:
return "tbuffer";
case SPV_REFLECT_USER_TYPE_APPEND_STRUCTURED_BUFFER:
return "AppendStructuredBuffer";
case SPV_REFLECT_USER_TYPE_BUFFER:
return "Buffer";
case SPV_REFLECT_USER_TYPE_BYTE_ADDRESS_BUFFER:
return "ByteAddressBuffer";
case SPV_REFLECT_USER_TYPE_CONSUME_STRUCTURED_BUFFER:
return "ConsumeStructuredBuffer";
case SPV_REFLECT_USER_TYPE_INPUT_PATCH:
return "InputPatch";
case SPV_REFLECT_USER_TYPE_OUTPUT_PATCH:
return "OutputPatch";
case SPV_REFLECT_USER_TYPE_RW_BUFFER:
return "RWBuffer";
case SPV_REFLECT_USER_TYPE_RW_BYTE_ADDRESS_BUFFER:
return "RWByteAddressBuffer";
case SPV_REFLECT_USER_TYPE_RW_STRUCTURED_BUFFER:
return "RWStructuredBuffer";
case SPV_REFLECT_USER_TYPE_RW_TEXTURE_1D:
return "RWTexture1D";
case SPV_REFLECT_USER_TYPE_RW_TEXTURE_1D_ARRAY:
return "RWTexture1DArray";
case SPV_REFLECT_USER_TYPE_RW_TEXTURE_2D:
return "RWTexture2D";
case SPV_REFLECT_USER_TYPE_RW_TEXTURE_2D_ARRAY:
return "RWTexture2DArray";
case SPV_REFLECT_USER_TYPE_RW_TEXTURE_3D:
return "RWTexture3D";
case SPV_REFLECT_USER_TYPE_STRUCTURED_BUFFER:
return "StructuredBuffer";
case SPV_REFLECT_USER_TYPE_TEXTURE_1D:
return "Texture1D";
case SPV_REFLECT_USER_TYPE_TEXTURE_1D_ARRAY:
return "Texture1DArray";
case SPV_REFLECT_USER_TYPE_TEXTURE_2D:
return "Texture2D";
case SPV_REFLECT_USER_TYPE_TEXTURE_2D_ARRAY:
return "Texture2DArray";
case SPV_REFLECT_USER_TYPE_TEXTURE_2DMS:
return "Texture2DMS";
case SPV_REFLECT_USER_TYPE_TEXTURE_2DMS_ARRAY:
return "Texture2DMSArray";
case SPV_REFLECT_USER_TYPE_TEXTURE_3D:
return "Texture3D";
case SPV_REFLECT_USER_TYPE_TEXTURE_CUBE:
return "TextureCube";
case SPV_REFLECT_USER_TYPE_TEXTURE_CUBE_ARRAY:
return "TextureCubeArray";
default:
return "???";
}
}

std::string ToStringTypeFlags(SpvReflectTypeFlags type_flags) {
if (type_flags == SPV_REFLECT_TYPE_FLAG_UNDEFINED) {
return "UNDEFINED";
Expand Down Expand Up @@ -1877,6 +1936,10 @@ void SpvReflectToYaml::WriteDescriptorBinding(std::ostream& os, const SpvReflect
// } word_offset;
os << t1 << "word_offset: { binding: " << db.word_offset.binding;
os << ", set: " << db.word_offset.set << " }" << std::endl;

if (db.user_type != SPV_REFLECT_USER_TYPE_INVALID) {
os << t1 << "user_type: " << ToStringUserType(db.user_type) << std::endl;
}
// } SpvReflectDescriptorBinding;
}

Expand Down
70 changes: 67 additions & 3 deletions spirv_reflect.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ typedef struct SpvReflectPrvDecorations {
bool is_per_task;
bool is_weight_texture;
bool is_block_match_texture;
SpvReflectUserType user_type;
SpvReflectPrvNumberDecoration set;
SpvReflectPrvNumberDecoration binding;
SpvReflectPrvNumberDecoration input_attachment_index;
Expand Down Expand Up @@ -1357,9 +1358,8 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser, SpvRefle
for (uint32_t i = 0; i < p_parser->node_count; ++i) {
SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);

if (((uint32_t)p_node->op != (uint32_t)SpvOpDecorate) && ((uint32_t)p_node->op != (uint32_t)SpvOpMemberDecorate) &&
((uint32_t)p_node->op != (uint32_t)SpvOpDecorateId) && ((uint32_t)p_node->op != (uint32_t)SpvOpDecorateString) &&
((uint32_t)p_node->op != (uint32_t)SpvOpMemberDecorateString)) {
if ((p_node->op != SpvOpDecorate) && (p_node->op != SpvOpMemberDecorate) && (p_node->op != SpvOpDecorateId) &&
(p_node->op != SpvOpDecorateString) && (p_node->op != SpvOpMemberDecorateString)) {
continue;
}

Expand Down Expand Up @@ -1404,6 +1404,7 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser, SpvRefle
case SpvDecorationSpecId:
case SpvDecorationWeightTextureQCOM:
case SpvDecorationBlockMatchTextureQCOM:
case SpvDecorationUserTypeGOOGLE:
case SpvDecorationHlslCounterBufferGOOGLE:
case SpvDecorationHlslSemanticGOOGLE: {
skip = false;
Expand Down Expand Up @@ -1562,6 +1563,68 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser, SpvRefle
p_target_decorations->is_block_match_texture = true;
} break;
}

if (p_node->op == SpvOpDecorateString && decoration == SpvDecorationUserTypeGOOGLE) {
uint32_t terminator = 0;
SpvReflectResult result = ReadStr(p_parser, p_node->word_offset + 3, 0, p_node->word_count, &terminator, NULL);
if (result != SPV_REFLECT_RESULT_SUCCESS) {
return result;
}
const char* name = (const char*)(p_parser->spirv_code + p_node->word_offset + 3);
if (strcmp(name, "cbuffer") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_CBUFFER;
} else if (strcmp(name, "tbuffer") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TBUFFER;
} else if (strcmp(name, "appendstructuredbuffer") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_APPEND_STRUCTURED_BUFFER;
} else if (strcmp(name, "buffer") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_BUFFER;
} else if (strcmp(name, "byteaddressbuffer") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_BYTE_ADDRESS_BUFFER;
} else if (strcmp(name, "consumestructuredbuffer") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_CONSUME_STRUCTURED_BUFFER;
} else if (strcmp(name, "inputpatch") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_INPUT_PATCH;
} else if (strcmp(name, "outputpatch") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_OUTPUT_PATCH;
} else if (strcmp(name, "rwbuffer") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_BUFFER;
} else if (strcmp(name, "rwbyteaddressbuffer") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_BYTE_ADDRESS_BUFFER;
} else if (strcmp(name, "rwstructuredbuffer") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_STRUCTURED_BUFFER;
} else if (strcmp(name, "rwtexture1d") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_TEXTURE_1D;
} else if (strcmp(name, "rwtexture1darray") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_TEXTURE_1D_ARRAY;
} else if (strcmp(name, "rwtexture2d") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_TEXTURE_2D;
} else if (strcmp(name, "rwtexture2darray") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_TEXTURE_2D_ARRAY;
} else if (strcmp(name, "rwtexture3d") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_RW_TEXTURE_3D;
} else if (strcmp(name, "structuredbuffer") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_STRUCTURED_BUFFER;
} else if (strcmp(name, "texture1d") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_1D;
} else if (strcmp(name, "texture1darray") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_1D_ARRAY;
} else if (strcmp(name, "texture2d") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_2D;
} else if (strcmp(name, "texture2darray") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_2D_ARRAY;
} else if (strcmp(name, "texture2dms") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_2DMS;
} else if (strcmp(name, "texture2dmsarray") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_2DMS_ARRAY;
} else if (strcmp(name, "texture3d") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_3D;
} else if (strcmp(name, "texturecube") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_CUBE;
} else if (strcmp(name, "texturecubearray") == 0) {
p_target_decorations->user_type = SPV_REFLECT_USER_TYPE_TEXTURE_CUBE_ARRAY;
}
}
}

if (spec_constant_count > 0) {
Expand Down Expand Up @@ -2053,6 +2116,7 @@ static SpvReflectResult ParseDescriptorBindings(SpvReflectPrvParser* p_parser, S
p_descriptor->uav_counter_id = p_node->decorations.uav_counter_buffer.value;
p_descriptor->type_description = p_type;
p_descriptor->decoration_flags = ApplyDecorations(&p_node->decorations);
p_descriptor->user_type = p_node->decorations.user_type;

// If this is in the StorageBuffer storage class, it's for sure a storage
// buffer descriptor. We need to handle this case earlier because in SPIR-V
Expand Down
33 changes: 33 additions & 0 deletions spirv_reflect.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,37 @@ typedef enum SpvReflectDecorationFlagBits {

typedef uint32_t SpvReflectDecorationFlags;

// Based of SPV_GOOGLE_user_type
typedef enum SpvReflectUserType {
SPV_REFLECT_USER_TYPE_INVALID = 0,
SPV_REFLECT_USER_TYPE_CBUFFER,
SPV_REFLECT_USER_TYPE_TBUFFER,
SPV_REFLECT_USER_TYPE_APPEND_STRUCTURED_BUFFER,
SPV_REFLECT_USER_TYPE_BUFFER,
SPV_REFLECT_USER_TYPE_BYTE_ADDRESS_BUFFER,
SPV_REFLECT_USER_TYPE_CONSUME_STRUCTURED_BUFFER,
SPV_REFLECT_USER_TYPE_INPUT_PATCH,
SPV_REFLECT_USER_TYPE_OUTPUT_PATCH,
SPV_REFLECT_USER_TYPE_RW_BUFFER,
SPV_REFLECT_USER_TYPE_RW_BYTE_ADDRESS_BUFFER,
SPV_REFLECT_USER_TYPE_RW_STRUCTURED_BUFFER,
SPV_REFLECT_USER_TYPE_RW_TEXTURE_1D,
SPV_REFLECT_USER_TYPE_RW_TEXTURE_1D_ARRAY,
SPV_REFLECT_USER_TYPE_RW_TEXTURE_2D,
SPV_REFLECT_USER_TYPE_RW_TEXTURE_2D_ARRAY,
SPV_REFLECT_USER_TYPE_RW_TEXTURE_3D,
SPV_REFLECT_USER_TYPE_STRUCTURED_BUFFER,
SPV_REFLECT_USER_TYPE_TEXTURE_1D,
SPV_REFLECT_USER_TYPE_TEXTURE_1D_ARRAY,
SPV_REFLECT_USER_TYPE_TEXTURE_2D,
SPV_REFLECT_USER_TYPE_TEXTURE_2D_ARRAY,
SPV_REFLECT_USER_TYPE_TEXTURE_2DMS,
SPV_REFLECT_USER_TYPE_TEXTURE_2DMS_ARRAY,
SPV_REFLECT_USER_TYPE_TEXTURE_3D,
SPV_REFLECT_USER_TYPE_TEXTURE_CUBE,
SPV_REFLECT_USER_TYPE_TEXTURE_CUBE_ARRAY,
} SpvReflectUserType;

/*! @enum SpvReflectResourceType
*/
Expand Down Expand Up @@ -459,6 +490,8 @@ typedef struct SpvReflectDescriptorBinding {
} word_offset;

SpvReflectDecorationFlags decoration_flags;
// Requires SPV_GOOGLE_user_type
SpvReflectUserType user_type;
} SpvReflectDescriptorBinding;

/*! @struct SpvReflectDescriptorSet
Expand Down
48 changes: 48 additions & 0 deletions tests/user_type/byte_address_buffer.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// dxc -spirv -fspv-reflect -T lib_6_4 -fspv-target-env=vulkan1.2
struct MaterialData_t
{
float4 g_vTest;
float2 g_vTest2; // accessed
float3 g_vTest3;
uint g_tTexture1; // accessed
uint g_tTexture2;
bool g_bTest1; // accessed
bool g_bTest2;
};

static MaterialData_t _g_MaterialData;

ByteAddressBuffer g_MaterialData : register ( t4 , space1 );

struct Payload_t
{
float2 vTest;
bool bTest;
uint tTest;
};

struct PayloadShadow_t
{
float m_flVisibility;
};

[ shader ( "closesthit" ) ]
void ClosestHit0 ( inout Payload_t payload , in BuiltInTriangleIntersectionAttributes attrs )
{
_g_MaterialData = g_MaterialData.Load<MaterialData_t>( InstanceIndex() );

payload.vTest = _g_MaterialData.g_vTest2;
payload.bTest = _g_MaterialData.g_bTest1;
payload.tTest = _g_MaterialData.g_tTexture1;
}

[ shader ( "anyhit" ) ]
void AnyHit1 ( inout PayloadShadow_t payload , in BuiltInTriangleIntersectionAttributes attrs )
{
_g_MaterialData = g_MaterialData.Load<MaterialData_t>( InstanceIndex() );

{
payload . m_flVisibility = 0.0 ;
AcceptHitAndEndSearch ( ) ;
}
}
Binary file added tests/user_type/byte_address_buffer.spv
Binary file not shown.
Loading

0 comments on commit 42878ed

Please sign in to comment.