@@ -125,6 +125,7 @@ typedef struct SpvReflectPrvDecorations {
125125 SpvReflectPrvStringDecoration semantic ;
126126 uint32_t array_stride ;
127127 uint32_t matrix_stride ;
128+ uint32_t spec_id ;
128129 SpvBuiltIn built_in ;
129130} SpvReflectPrvDecorations ;
130131
@@ -1354,7 +1355,8 @@ static SpvReflectResult ParseNames(SpvReflectPrvParser* p_parser) {
13541355 return SPV_REFLECT_RESULT_SUCCESS ;
13551356}
13561357
1357- static SpvReflectResult ParseDecorations (SpvReflectPrvParser * p_parser ) {
1358+ static SpvReflectResult ParseDecorations (SpvReflectPrvParser * p_parser , SpvReflectShaderModule * p_module ) {
1359+ uint32_t spec_constant_count = 0 ;
13581360 for (uint32_t i = 0 ; i < p_parser -> node_count ; ++ i ) {
13591361 SpvReflectPrvNode * p_node = & (p_parser -> nodes [i ]);
13601362
@@ -1403,6 +1405,7 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) {
14031405 case SpvDecorationDescriptorSet :
14041406 case SpvDecorationOffset :
14051407 case SpvDecorationInputAttachmentIndex :
1408+ case SpvDecorationSpecId :
14061409 case SpvDecorationWeightTextureQCOM :
14071410 case SpvDecorationBlockMatchTextureQCOM :
14081411 case SpvReflectDecorationHlslCounterBufferGOOGLE :
@@ -1539,6 +1542,10 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) {
15391542 p_target_decorations -> input_attachment_index .word_offset = word_offset ;
15401543 } break ;
15411544
1545+ case SpvDecorationSpecId : {
1546+ spec_constant_count ++ ;
1547+ } break ;
1548+
15421549 case SpvReflectDecorationHlslCounterBufferGOOGLE : {
15431550 uint32_t word_offset = p_node -> word_offset + member_offset + 3 ;
15441551 CHECKED_READU32 (p_parser , word_offset , p_target_decorations -> uav_counter_buffer .value );
@@ -1560,6 +1567,27 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) {
15601567 } break ;
15611568 }
15621569 }
1570+
1571+ if (spec_constant_count > 0 ) {
1572+ p_module -> spec_constants = (SpvReflectSpecializationConstant * )calloc (spec_constant_count , sizeof (* p_module -> spec_constants ));
1573+ if (IsNull (p_module -> spec_constants )) {
1574+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED ;
1575+ }
1576+ }
1577+ for (uint32_t i = 0 ; i < p_parser -> node_count ; ++ i ) {
1578+ SpvReflectPrvNode * p_node = & (p_parser -> nodes [i ]);
1579+ if (p_node -> op == SpvOpDecorate ) {
1580+ uint32_t decoration = (uint32_t )INVALID_VALUE ;
1581+ CHECKED_READU32 (p_parser , p_node -> word_offset + 2 , decoration );
1582+ if (decoration == SpvDecorationSpecId ) {
1583+ const uint32_t count = p_module -> spec_constant_count ;
1584+ CHECKED_READU32 (p_parser , p_node -> word_offset + 1 , p_module -> spec_constants [count ].constant_id );
1585+ CHECKED_READU32 (p_parser , p_node -> word_offset + 3 , p_module -> spec_constants [count ].spirv_id );
1586+ p_module -> spec_constant_count ++ ;
1587+ }
1588+ }
1589+ }
1590+
15631591 return SPV_REFLECT_RESULT_SUCCESS ;
15641592}
15651593
@@ -3862,7 +3890,7 @@ static SpvReflectResult CreateShaderModule(uint32_t flags, size_t size, const vo
38623890 SPV_REFLECT_ASSERT (result == SPV_REFLECT_RESULT_SUCCESS );
38633891 }
38643892 if (result == SPV_REFLECT_RESULT_SUCCESS ) {
3865- result = ParseDecorations (& parser );
3893+ result = ParseDecorations (& parser , p_module );
38663894 SPV_REFLECT_ASSERT (result == SPV_REFLECT_RESULT_SUCCESS );
38673895 }
38683896
@@ -4051,6 +4079,7 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module) {
40514079 }
40524080 SafeFree (p_module -> capabilities );
40534081 SafeFree (p_module -> entry_points );
4082+ SafeFree (p_module -> spec_constants );
40544083
40554084 // Push constants
40564085 for (size_t i = 0 ; i < p_module -> push_constant_block_count ; ++ i ) {
@@ -4456,6 +4485,31 @@ SpvReflectResult spvReflectEnumerateEntryPointPushConstantBlocks(const SpvReflec
44564485 return SPV_REFLECT_RESULT_SUCCESS ;
44574486}
44584487
4488+ SpvReflectResult spvReflectEnumerateSpecializationConstants (const SpvReflectShaderModule * p_module , uint32_t * p_count ,
4489+ SpvReflectSpecializationConstant * * pp_constants ) {
4490+ if (IsNull (p_module )) {
4491+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER ;
4492+ }
4493+ if (IsNull (p_count )) {
4494+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER ;
4495+ }
4496+
4497+ if (IsNotNull (pp_constants )) {
4498+ if (* p_count != p_module -> spec_constant_count ) {
4499+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH ;
4500+ }
4501+
4502+ for (uint32_t index = 0 ; index < * p_count ; ++ index ) {
4503+ SpvReflectSpecializationConstant * p_constant = (SpvReflectSpecializationConstant * )& p_module -> spec_constants [index ];
4504+ pp_constants [index ] = p_constant ;
4505+ }
4506+ } else {
4507+ * p_count = p_module -> spec_constant_count ;
4508+ }
4509+
4510+ return SPV_REFLECT_RESULT_SUCCESS ;
4511+ }
4512+
44594513const SpvReflectDescriptorBinding * spvReflectGetDescriptorBinding (const SpvReflectShaderModule * p_module , uint32_t binding_number ,
44604514 uint32_t set_number , SpvReflectResult * p_result ) {
44614515 const SpvReflectDescriptorBinding * p_descriptor = NULL ;
0 commit comments