Skip to content

Commit 26c9751

Browse files
Add Spec Constant API
1 parent 4aedb50 commit 26c9751

96 files changed

Lines changed: 8770 additions & 2 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

common/output_stream.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2174,6 +2174,15 @@ void SpvReflectToYaml::Write(std::ostream& os) {
21742174
os << t2 << "- *bv" << itor->second << " # " << SafeString(sm_.push_constant_blocks[i].name) << std::endl;
21752175
}
21762176

2177+
// uint32_t spec_constant_count;
2178+
os << t1 << "specialization_constant_count: " << sm_.spec_constant_count << ",\n";
2179+
// SpvReflectSpecializationConstant* spec_constants;
2180+
os << t1 << "specialization_constants:" << std::endl;
2181+
for (uint32_t i = 0; i < sm_.spec_constant_count; ++i) {
2182+
os << t3 << "spirv_id: " << sm_.spec_constants[i].spirv_id << std::endl;
2183+
os << t3 << "constant_id: " << sm_.spec_constants[i].constant_id << std::endl;
2184+
}
2185+
21772186
if (verbosity_ >= 2) {
21782187
// struct Internal {
21792188
os << t1 << "_internal:" << std::endl;

spirv_reflect.c

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
44594513
const SpvReflectDescriptorBinding* spvReflectGetDescriptorBinding(const SpvReflectShaderModule* p_module, uint32_t binding_number,
44604514
uint32_t set_number, SpvReflectResult* p_result) {
44614515
const SpvReflectDescriptorBinding* p_descriptor = NULL;

spirv_reflect.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,15 @@ typedef struct SpvReflectCapability {
520520
uint32_t word_offset;
521521
} SpvReflectCapability;
522522

523+
524+
/*! @struct SpvReflectSpecId
525+
526+
*/
527+
typedef struct SpvReflectSpecializationConstant {
528+
uint32_t spirv_id;
529+
uint32_t constant_id;
530+
} SpvReflectSpecializationConstant;
531+
523532
/*! @struct SpvReflectShaderModule
524533
525534
*/
@@ -549,6 +558,8 @@ typedef struct SpvReflectShaderModule {
549558
SpvReflectInterfaceVariable* interface_variables; // Uses value(s) from first entry point
550559
uint32_t push_constant_block_count; // Uses value(s) from first entry point
551560
SpvReflectBlockVariable* push_constant_blocks; // Uses value(s) from first entry point
561+
uint32_t spec_constant_count; // Uses value(s) from first entry point
562+
SpvReflectSpecializationConstant* spec_constants; // Uses value(s) from first entry point
552563

553564
struct Internal {
554565
SpvReflectModuleFlags module_flags;
@@ -960,6 +971,25 @@ SpvReflectResult spvReflectEnumerateEntryPointPushConstantBlocks(
960971
);
961972

962973

974+
/*! @fn spvReflectEnumerateSpecializationConstants
975+
@param p_module Pointer to an instance of SpvReflectShaderModule.
976+
@param p_count If pp_blocks is NULL, the module's specialization constant
977+
count will be stored here. If pp_blocks is not NULL, *p_count
978+
must contain the module's specialization constant count.
979+
@param pp_constants If NULL, the module's specialization constant count
980+
will be written to *p_count. If non-NULL, pp_blocks must
981+
point to an array with *p_count entries, where pointers to
982+
the module's specialization constant blocks will be written.
983+
The caller must not free the variables written to this array.
984+
@return If successful, returns SPV_REFLECT_RESULT_SUCCESS.
985+
Otherwise, the error code indicates the cause of the failure.
986+
*/
987+
SpvReflectResult spvReflectEnumerateSpecializationConstants(
988+
const SpvReflectShaderModule* p_module,
989+
uint32_t* p_count,
990+
SpvReflectSpecializationConstant** pp_constants
991+
);
992+
963993
/*! @fn spvReflectGetDescriptorBinding
964994
965995
@param p_module Pointer to an instance of SpvReflectShaderModule.
@@ -1550,6 +1580,7 @@ class ShaderModule {
15501580
SpvReflectResult EnumeratePushConstants(uint32_t* p_count, SpvReflectBlockVariable** pp_blocks) const {
15511581
return EnumeratePushConstantBlocks(p_count, pp_blocks);
15521582
}
1583+
SpvReflectResult EnumerateSpecializationConstants(uint32_t* p_count, SpvReflectSpecializationConstant** pp_constants) const;
15531584

15541585
const SpvReflectDescriptorBinding* GetDescriptorBinding(uint32_t binding_number, uint32_t set_number, SpvReflectResult* p_result = nullptr) const;
15551586
const SpvReflectDescriptorBinding* GetEntryPointDescriptorBinding(const char* entry_point, uint32_t binding_number, uint32_t set_number, SpvReflectResult* p_result = nullptr) const;
@@ -1997,6 +2028,24 @@ inline SpvReflectResult ShaderModule::EnumeratePushConstantBlocks(
19972028
return m_result;
19982029
}
19992030

2031+
/*! @fn EnumerateSpecializationConstants
2032+
@param p_count
2033+
@param pp_constants
2034+
@return
2035+
*/
2036+
inline SpvReflectResult ShaderModule::EnumerateSpecializationConstants(
2037+
uint32_t* p_count,
2038+
SpvReflectSpecializationConstant** pp_constants
2039+
) const
2040+
{
2041+
m_result = spvReflectEnumerateSpecializationConstants(
2042+
&m_module,
2043+
p_count,
2044+
pp_constants
2045+
);
2046+
return m_result;
2047+
}
2048+
20002049
/*! @fn EnumerateEntryPointPushConstantBlocks
20012050
20022051
@param entry_point

tests/16bit/vert_in_out_16.spv.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,4 +352,6 @@ module:
352352
- *iv11 # "_f"
353353
push_constant_count: 0,
354354
push_constants:
355+
specialization_constant_count: 0,
356+
specialization_constants:
355357
...

tests/access_chains/array_length_from_access_chain.spv.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,6 @@ module:
143143
output_variables:
144144
push_constant_count: 0,
145145
push_constants:
146+
specialization_constant_count: 0,
147+
specialization_constants:
146148
...

tests/cbuffer_unused/cbuffer_unused_001.spv.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3393,4 +3393,6 @@ module:
33933393
- *iv1 #
33943394
push_constant_count: 0,
33953395
push_constants:
3396+
specialization_constant_count: 0,
3397+
specialization_constants:
33963398
...

tests/entry_exec_mode/comp_local_size.spv.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,6 @@ module:
109109
output_variables:
110110
push_constant_count: 0,
111111
push_constants:
112+
specialization_constant_count: 0,
113+
specialization_constants:
112114
...

tests/entry_exec_mode/geom_inv_out_vert.spv.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,4 +390,6 @@ module:
390390
- *iv9 # ""
391391
push_constant_count: 0,
392392
push_constants:
393+
specialization_constant_count: 0,
394+
specialization_constants:
393395
...

tests/execution_mode/local_size_id.spv.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ module:
2222
output_variables:
2323
push_constant_count: 0,
2424
push_constants:
25+
specialization_constant_count: 0,
26+
specialization_constants:
2527
...

tests/execution_mode/local_size_id_spec.spv.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ module:
2222
output_variables:
2323
push_constant_count: 0,
2424
push_constants:
25+
specialization_constant_count: 0,
26+
specialization_constants:
2527
...

0 commit comments

Comments
 (0)