Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SPV_GOOGLE_user_type support #247

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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