Skip to content

Commit be73aee

Browse files
Add Spec Constant API (#242)
1 parent 4fd8c09 commit be73aee

File tree

99 files changed

+8929
-4
lines changed

Some content is hidden

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

99 files changed

+8929
-4
lines changed

common/output_stream.cpp

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

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

spirv_reflect.c

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,8 @@ static SpvReflectResult ParseNames(SpvReflectPrvParser* p_parser) {
13521352
return SPV_REFLECT_RESULT_SUCCESS;
13531353
}
13541354

1355-
static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) {
1355+
static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser, SpvReflectShaderModule* p_module) {
1356+
uint32_t spec_constant_count = 0;
13561357
for (uint32_t i = 0; i < p_parser->node_count; ++i) {
13571358
SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
13581359

@@ -1538,8 +1539,7 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) {
15381539
} break;
15391540

15401541
case SpvDecorationSpecId: {
1541-
uint32_t word_offset = p_node->word_offset + member_offset + 3;
1542-
CHECKED_READU32(p_parser, word_offset, p_target_decorations->spec_id);
1542+
spec_constant_count++;
15431543
} break;
15441544

15451545
case SpvDecorationHlslCounterBufferGOOGLE: {
@@ -1563,6 +1563,27 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) {
15631563
} break;
15641564
}
15651565
}
1566+
1567+
if (spec_constant_count > 0) {
1568+
p_module->spec_constants = (SpvReflectSpecializationConstant*)calloc(spec_constant_count, sizeof(*p_module->spec_constants));
1569+
if (IsNull(p_module->spec_constants)) {
1570+
return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
1571+
}
1572+
}
1573+
for (uint32_t i = 0; i < p_parser->node_count; ++i) {
1574+
SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
1575+
if (p_node->op == SpvOpDecorate) {
1576+
uint32_t decoration = (uint32_t)INVALID_VALUE;
1577+
CHECKED_READU32(p_parser, p_node->word_offset + 2, decoration);
1578+
if (decoration == SpvDecorationSpecId) {
1579+
const uint32_t count = p_module->spec_constant_count;
1580+
CHECKED_READU32(p_parser, p_node->word_offset + 1, p_module->spec_constants[count].constant_id);
1581+
CHECKED_READU32(p_parser, p_node->word_offset + 3, p_module->spec_constants[count].spirv_id);
1582+
p_module->spec_constant_count++;
1583+
}
1584+
}
1585+
}
1586+
15661587
return SPV_REFLECT_RESULT_SUCCESS;
15671588
}
15681589

@@ -3861,7 +3882,7 @@ static SpvReflectResult CreateShaderModule(uint32_t flags, size_t size, const vo
38613882
SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
38623883
}
38633884
if (result == SPV_REFLECT_RESULT_SUCCESS) {
3864-
result = ParseDecorations(&parser);
3885+
result = ParseDecorations(&parser, p_module);
38653886
SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
38663887
}
38673888

@@ -4050,6 +4071,7 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module) {
40504071
}
40514072
SafeFree(p_module->capabilities);
40524073
SafeFree(p_module->entry_points);
4074+
SafeFree(p_module->spec_constants);
40534075

40544076
// Push constants
40554077
for (size_t i = 0; i < p_module->push_constant_block_count; ++i) {
@@ -4455,6 +4477,31 @@ SpvReflectResult spvReflectEnumerateEntryPointPushConstantBlocks(const SpvReflec
44554477
return SPV_REFLECT_RESULT_SUCCESS;
44564478
}
44574479

4480+
SpvReflectResult spvReflectEnumerateSpecializationConstants(const SpvReflectShaderModule* p_module, uint32_t* p_count,
4481+
SpvReflectSpecializationConstant** pp_constants) {
4482+
if (IsNull(p_module)) {
4483+
return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
4484+
}
4485+
if (IsNull(p_count)) {
4486+
return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
4487+
}
4488+
4489+
if (IsNotNull(pp_constants)) {
4490+
if (*p_count != p_module->spec_constant_count) {
4491+
return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
4492+
}
4493+
4494+
for (uint32_t index = 0; index < *p_count; ++index) {
4495+
SpvReflectSpecializationConstant* p_constant = (SpvReflectSpecializationConstant*)&p_module->spec_constants[index];
4496+
pp_constants[index] = p_constant;
4497+
}
4498+
} else {
4499+
*p_count = p_module->spec_constant_count;
4500+
}
4501+
4502+
return SPV_REFLECT_RESULT_SUCCESS;
4503+
}
4504+
44584505
const SpvReflectDescriptorBinding* spvReflectGetDescriptorBinding(const SpvReflectShaderModule* p_module, uint32_t binding_number,
44594506
uint32_t set_number, SpvReflectResult* p_result) {
44604507
const SpvReflectDescriptorBinding* p_descriptor = NULL;

spirv_reflect.h

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

522+
523+
/*! @struct SpvReflectSpecId
524+
525+
*/
526+
typedef struct SpvReflectSpecializationConstant {
527+
uint32_t spirv_id;
528+
uint32_t constant_id;
529+
} SpvReflectSpecializationConstant;
530+
522531
/*! @struct SpvReflectShaderModule
523532
524533
*/
@@ -548,6 +557,8 @@ typedef struct SpvReflectShaderModule {
548557
SpvReflectInterfaceVariable* interface_variables; // Uses value(s) from first entry point
549558
uint32_t push_constant_block_count; // Uses value(s) from first entry point
550559
SpvReflectBlockVariable* push_constant_blocks; // Uses value(s) from first entry point
560+
uint32_t spec_constant_count; // Uses value(s) from first entry point
561+
SpvReflectSpecializationConstant* spec_constants; // Uses value(s) from first entry point
551562

552563
struct Internal {
553564
SpvReflectModuleFlags module_flags;
@@ -959,6 +970,25 @@ SpvReflectResult spvReflectEnumerateEntryPointPushConstantBlocks(
959970
);
960971

961972

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

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

2030+
/*! @fn EnumerateSpecializationConstants
2031+
@param p_count
2032+
@param pp_constants
2033+
@return
2034+
*/
2035+
inline SpvReflectResult ShaderModule::EnumerateSpecializationConstants(
2036+
uint32_t* p_count,
2037+
SpvReflectSpecializationConstant** pp_constants
2038+
) const
2039+
{
2040+
m_result = spvReflectEnumerateSpecializationConstants(
2041+
&m_module,
2042+
p_count,
2043+
pp_constants
2044+
);
2045+
return m_result;
2046+
}
2047+
19992048
/*! @fn EnumerateEntryPointPushConstantBlocks
20002049
20012050
@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)