4242
4343// clang-format off
4444enum {
45- SPIRV_STARTING_WORD_INDEX = 5 ,
46- SPIRV_WORD_SIZE = sizeof (uint32_t ),
47- SPIRV_BYTE_WIDTH = 8 ,
48- SPIRV_MINIMUM_FILE_SIZE = SPIRV_STARTING_WORD_INDEX * SPIRV_WORD_SIZE ,
49- SPIRV_DATA_ALIGNMENT = 4 * SPIRV_WORD_SIZE , // 16
50- SPIRV_ACCESS_CHAIN_INDEX_OFFSET = 4 ,
45+ SPIRV_STARTING_WORD_INDEX = 5 ,
46+ SPIRV_WORD_SIZE = sizeof (uint32_t ),
47+ SPIRV_BYTE_WIDTH = 8 ,
48+ SPIRV_MINIMUM_FILE_SIZE = SPIRV_STARTING_WORD_INDEX * SPIRV_WORD_SIZE ,
49+ SPIRV_DATA_ALIGNMENT = 4 * SPIRV_WORD_SIZE , // 16
50+ SPIRV_ACCESS_CHAIN_INDEX_OFFSET = 4 ,
51+ SPIRV_PHYSICAL_STORAGE_POINTER_SIZE = 8 , // Pointers are defined as 64-bit
5152};
5253
5354enum {
@@ -1986,6 +1987,13 @@ static SpvReflectResult ParseType(SpvReflectPrvParser* p_parser, SpvReflectPrvNo
19861987 p_type -> type_flags |= SPV_REFLECT_TYPE_FLAG_REF ;
19871988 IF_READU32_CAST (result , p_parser , p_node -> word_offset + 2 , SpvStorageClass , p_type -> storage_class );
19881989
1990+ SpvReflectPrvNode * p_next_node = FindNode (p_parser , p_node -> type_id );
1991+ if (IsNull (p_next_node )) {
1992+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE ;
1993+ SPV_REFLECT_ASSERT (false);
1994+ break ;
1995+ }
1996+
19891997 bool found_recursion = false;
19901998 if (p_type -> storage_class == SpvStorageClassPhysicalStorageBuffer ) {
19911999 // Need to make sure we haven't started an infinite recursive loop
@@ -1997,7 +2005,7 @@ static SpvReflectResult ParseType(SpvReflectPrvParser* p_parser, SpvReflectPrvNo
19972005 return SPV_REFLECT_RESULT_SUCCESS ;
19982006 }
19992007 }
2000- if (!found_recursion ) {
2008+ if (!found_recursion && p_next_node -> op == SpvOpTypeStruct ) {
20012009 p_parser -> physical_pointer_struct_count ++ ;
20022010 p_parser -> physical_pointer_check [p_parser -> physical_pointer_count ] = p_type ;
20032011 p_parser -> physical_pointer_count ++ ;
@@ -2007,12 +2015,7 @@ static SpvReflectResult ParseType(SpvReflectPrvParser* p_parser, SpvReflectPrvNo
20072015 }
20082016 }
20092017
2010- // Parse type
2011- SpvReflectPrvNode * p_next_node = FindNode (p_parser , p_node -> type_id );
2012- if (IsNull (p_next_node )) {
2013- result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE ;
2014- SPV_REFLECT_ASSERT (false);
2015- } else if (!found_recursion ) {
2018+ if (!found_recursion ) {
20162019 if (p_next_node -> op == SpvOpTypeStruct ) {
20172020 p_type -> struct_type_description = FindType (p_module , p_next_node -> result_id );
20182021 }
@@ -2188,7 +2191,8 @@ static SpvReflectResult ParseDescriptorBindings(SpvReflectPrvParser* p_parser, S
21882191 // from the pointer so that we can use it to deduce deescriptor types.
21892192 SpvStorageClass pointer_storage_class = SpvStorageClassMax ;
21902193 if (p_type -> op == SpvOpTypePointer ) {
2191- pointer_storage_class = p_type -> storage_class ;
2194+ assert (p_type -> storage_class != -1 && "Pointer types must have a valid storage class." );
2195+ pointer_storage_class = (SpvStorageClass )p_type -> storage_class ;
21922196 // Find the type's node
21932197 SpvReflectPrvNode * p_type_node = FindNode (p_parser , p_type -> id );
21942198 if (IsNull (p_type_node )) {
@@ -2544,15 +2548,19 @@ static SpvReflectResult ParseDescriptorBlockVariable(SpvReflectPrvParser* p_pars
25442548 }
25452549 }
25462550 if (!found_recursion ) {
2547- uint32_t struct_id = FindType (p_module , p_member_type -> id )-> struct_type_description -> id ;
2548- p_parser -> physical_pointer_structs [p_parser -> physical_pointer_struct_count ].struct_id = struct_id ;
2549- p_parser -> physical_pointer_structs [p_parser -> physical_pointer_struct_count ].p_var = p_member_var ;
2550- p_parser -> physical_pointer_struct_count ++ ;
2551-
2552- p_parser -> physical_pointer_check [p_parser -> physical_pointer_count ] = p_member_type ;
2553- p_parser -> physical_pointer_count ++ ;
2554- if (p_parser -> physical_pointer_count >= MAX_RECURSIVE_PHYSICAL_POINTER_CHECK ) {
2555- return SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED ;
2551+ SpvReflectTypeDescription * struct_type = FindType (p_module , p_member_type -> id );
2552+ // could be pointer directly to non-struct type here
2553+ if (struct_type -> struct_type_description ) {
2554+ uint32_t struct_id = struct_type -> struct_type_description -> id ;
2555+ p_parser -> physical_pointer_structs [p_parser -> physical_pointer_struct_count ].struct_id = struct_id ;
2556+ p_parser -> physical_pointer_structs [p_parser -> physical_pointer_struct_count ].p_var = p_member_var ;
2557+ p_parser -> physical_pointer_struct_count ++ ;
2558+
2559+ p_parser -> physical_pointer_check [p_parser -> physical_pointer_count ] = p_member_type ;
2560+ p_parser -> physical_pointer_count ++ ;
2561+ if (p_parser -> physical_pointer_count >= MAX_RECURSIVE_PHYSICAL_POINTER_CHECK ) {
2562+ return SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED ;
2563+ }
25562564 }
25572565 }
25582566
@@ -2723,7 +2731,13 @@ static SpvReflectResult ParseDescriptorBlockVariableSizes(SpvReflectPrvParser* p
27232731 if (IsNull (p_member_type )) {
27242732 return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE ;
27252733 }
2726- assert (p_member_type -> op == SpvOpTypeStruct );
2734+
2735+ // If we found a struct, we need to fall through and get the size of it or else we grab the size here
2736+ if (p_member_type -> op != SpvOpTypeStruct ) {
2737+ // If we hit this, we are seeing a POD pointer and the size is fixed
2738+ p_member_var -> size = SPIRV_PHYSICAL_STORAGE_POINTER_SIZE ;
2739+ break ;
2740+ }
27272741 FALLTHROUGH ;
27282742 }
27292743
@@ -2815,19 +2829,11 @@ static void MarkSelfAndAllMemberVarsAsUsed(SpvReflectBlockVariable* p_var) {
28152829 p_var -> flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED ;
28162830
28172831 SpvOp op_type = p_var -> type_description -> op ;
2818- switch (op_type ) {
2819- default :
2820- break ;
2821-
2822- case SpvOpTypeArray : {
2823- } break ;
2824-
2825- case SpvOpTypeStruct : {
2826- for (uint32_t i = 0 ; i < p_var -> member_count ; ++ i ) {
2827- SpvReflectBlockVariable * p_member_var = & p_var -> members [i ];
2828- MarkSelfAndAllMemberVarsAsUsed (p_member_var );
2829- }
2830- } break ;
2832+ if (op_type == SpvOpTypeStruct ) {
2833+ for (uint32_t i = 0 ; i < p_var -> member_count ; ++ i ) {
2834+ SpvReflectBlockVariable * p_member_var = & p_var -> members [i ];
2835+ MarkSelfAndAllMemberVarsAsUsed (p_member_var );
2836+ }
28312837 }
28322838}
28332839
@@ -2944,7 +2950,10 @@ static SpvReflectResult ParseDescriptorBlockVariableUsage(SpvReflectPrvParser* p
29442950 if (result != SPV_REFLECT_RESULT_SUCCESS ) {
29452951 return result ;
29462952 }
2947- } else if (!is_pointer_to_pointer ) {
2953+ } else if (is_pointer_to_pointer ) {
2954+ // Clear UNUSED flag, but only for the pointer
2955+ p_member_var -> flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED ;
2956+ } else {
29482957 // Clear UNUSED flag for remaining variables
29492958 MarkSelfAndAllMemberVarsAsUsed (p_member_var );
29502959 }
@@ -4015,7 +4024,7 @@ static SpvReflectResult ParsePushConstantBlocks(SpvReflectPrvParser* p_parser, S
40154024 }
40164025
40174026 p_push_constant -> name = p_node -> name ;
4018- result = ParseDescriptorBlockVariableSizes (p_parser , p_module , true, false, false , p_push_constant );
4027+ result = ParseDescriptorBlockVariableSizes (p_parser , p_module , true, false, true , p_push_constant );
40194028 if (result != SPV_REFLECT_RESULT_SUCCESS ) {
40204029 return result ;
40214030 }
0 commit comments