diff --git a/thirdparty/spirv-reflect/patches/specialization-constants.patch b/thirdparty/spirv-reflect/patches/specialization-constants.patch index 297bbf3a2d..e69de29bb2 100644 --- a/thirdparty/spirv-reflect/patches/specialization-constants.patch +++ b/thirdparty/spirv-reflect/patches/specialization-constants.patch @@ -1,286 +0,0 @@ -diff --git a/thirdparty/spirv-reflect/spirv_reflect.c b/thirdparty/spirv-reflect/spirv_reflect.c -index 3b9d6bfecc..e97d1b0438 100644 ---- a/thirdparty/spirv-reflect/spirv_reflect.c -+++ b/thirdparty/spirv-reflect/spirv_reflect.c -@@ -122,6 +122,9 @@ typedef struct SpvReflectPrvDecorations { - SpvReflectPrvNumberDecoration component; - SpvReflectPrvNumberDecoration offset; - SpvReflectPrvNumberDecoration uav_counter_buffer; -+// -- GODOT begin -- -+ SpvReflectPrvNumberDecoration specialization_constant; -+// -- GODOT end -- - SpvReflectPrvStringDecoration semantic; - uint32_t array_stride; - uint32_t matrix_stride; -@@ -708,6 +711,9 @@ static SpvReflectResult ParseNodes(SpvReflectPrvParser* p_parser) { - p_parser->nodes[i].decorations.offset.value = (uint32_t)INVALID_VALUE; - p_parser->nodes[i].decorations.uav_counter_buffer.value = (uint32_t)INVALID_VALUE; - p_parser->nodes[i].decorations.built_in = (SpvBuiltIn)INVALID_VALUE; -+// -- GODOT begin -- -+ p_parser->nodes[i].decorations.specialization_constant.value = (SpvBuiltIn)INVALID_VALUE; -+// -- GODOT end -- - } - // Mark source file id node - p_parser->source_file_id = (uint32_t)INVALID_VALUE; -@@ -907,7 +913,13 @@ static SpvReflectResult ParseNodes(SpvReflectPrvParser* p_parser) { - - case SpvOpSpecConstantTrue: - case SpvOpSpecConstantFalse: -- case SpvOpSpecConstant: -+// -- GODOT begin -- -+ case SpvOpSpecConstant: { -+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id); -+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id); -+ p_node->is_type = true; -+ } break; -+// -- GODOT end -- - case SpvOpSpecConstantComposite: - case SpvOpSpecConstantOp: { - CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id); -@@ -1385,6 +1397,9 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) { - default: { - skip = true; - } break; -+// -- GODOT begin -- -+ case SpvDecorationSpecId: -+// -- GODOT end -- - case SpvDecorationRelaxedPrecision: - case SpvDecorationBlock: - case SpvDecorationBufferBlock: -@@ -1542,6 +1557,14 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser) { - p_target_decorations->input_attachment_index.word_offset = word_offset; - } break; - -+// -- GODOT begin -- -+ case SpvDecorationSpecId: { -+ uint32_t word_offset = p_node->word_offset + member_offset+ 3; -+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->specialization_constant.value); -+ p_target_decorations->specialization_constant.word_offset = word_offset; -+ } break; -+// -- GODOT end -- -+ - case SpvReflectDecorationHlslCounterBufferGOOGLE: { - uint32_t word_offset = p_node->word_offset + member_offset + 3; - CHECKED_READU32(p_parser, word_offset, p_target_decorations->uav_counter_buffer.value); -@@ -1851,6 +1874,13 @@ static SpvReflectResult ParseType(SpvReflectPrvParser* p_parser, SpvReflectPrvNo - case SpvOpTypeAccelerationStructureKHR: { - p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE; - } break; -+ -+// -- GODOT begin -- -+ case SpvOpSpecConstantTrue: -+ case SpvOpSpecConstantFalse: -+ case SpvOpSpecConstant: { -+ } break; -+// -- GODOT end -- - } - - if (result == SPV_REFLECT_RESULT_SUCCESS) { -@@ -3522,6 +3552,68 @@ static SpvReflectResult ParseExecutionModes(SpvReflectPrvParser* p_parser, SpvRe - return SPV_REFLECT_RESULT_SUCCESS; - } - -+// -- GODOT begin -- -+static SpvReflectResult ParseSpecializationConstants(SpvReflectPrvParser* p_parser, SpvReflectShaderModule* p_module) { -+ p_module->specialization_constant_count = 0; -+ p_module->specialization_constants = NULL; -+ for (size_t i = 0; i < p_parser->node_count; ++i) { -+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]); -+ if (p_node->op == SpvOpSpecConstantTrue || p_node->op == SpvOpSpecConstantFalse || p_node->op == SpvOpSpecConstant) { -+ p_module->specialization_constant_count++; -+ } -+ } -+ -+ if (p_module->specialization_constant_count == 0) { -+ return SPV_REFLECT_RESULT_SUCCESS; -+ } -+ -+ p_module->specialization_constants = (SpvReflectSpecializationConstant*)calloc(p_module->specialization_constant_count, sizeof(SpvReflectSpecializationConstant)); -+ -+ uint32_t index = 0; -+ -+ for (size_t i = 0; i < p_parser->node_count; ++i) { -+ SpvReflectPrvNode* p_node = &(p_parser->nodes[i]); -+ switch(p_node->op) { -+ default: continue; -+ case SpvOpSpecConstantTrue: { -+ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL; -+ p_module->specialization_constants[index].default_value.int_bool_value = 1; -+ } break; -+ case SpvOpSpecConstantFalse: { -+ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL; -+ p_module->specialization_constants[index].default_value.int_bool_value = 0; -+ } break; -+ case SpvOpSpecConstant: { -+ SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS; -+ uint32_t element_type_id = (uint32_t)INVALID_VALUE; -+ uint32_t default_value = 0; -+ IF_READU32(result, p_parser, p_node->word_offset + 1, element_type_id); -+ IF_READU32(result, p_parser, p_node->word_offset + 3, default_value); -+ -+ SpvReflectPrvNode* p_next_node = FindNode(p_parser, element_type_id); -+ -+ if (p_next_node->op == SpvOpTypeInt) { -+ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_INT; -+ } else if (p_next_node->op == SpvOpTypeFloat) { -+ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT; -+ } else { -+ return SPV_REFLECT_RESULT_ERROR_PARSE_FAILED; -+ } -+ -+ p_module->specialization_constants[index].default_value.int_bool_value = default_value; //bits are the same for int and float -+ } break; -+ } -+ -+ p_module->specialization_constants[index].name = p_node->name; -+ p_module->specialization_constants[index].constant_id = p_node->decorations.specialization_constant.value; -+ p_module->specialization_constants[index].spirv_id = p_node->result_id; -+ index++; -+ } -+ -+ return SPV_REFLECT_RESULT_SUCCESS; -+} -+// -- GODOT end -- -+ - static SpvReflectResult ParsePushConstantBlocks(SpvReflectPrvParser* p_parser, SpvReflectShaderModule* p_module) { - for (size_t i = 0; i < p_parser->node_count; ++i) { - SpvReflectPrvNode* p_node = &(p_parser->nodes[i]); -@@ -3908,6 +4000,12 @@ static SpvReflectResult CreateShaderModule(uint32_t flags, size_t size, const vo - result = ParsePushConstantBlocks(&parser, p_module); - SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); - } -+// -- GODOT begin -- -+ if (result == SPV_REFLECT_RESULT_SUCCESS) { -+ result = ParseSpecializationConstants(&parser, p_module); -+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); -+ } -+// -- GODOT end -- - if (result == SPV_REFLECT_RESULT_SUCCESS) { - result = ParseEntryPoints(&parser, p_module); - SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); -@@ -4056,6 +4154,9 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module) { - } - SafeFree(p_module->capabilities); - SafeFree(p_module->entry_points); -+// -- GODOT begin -- -+ SafeFree(p_module->specialization_constants); -+// -- GODOT end -- - - // Push constants - for (size_t i = 0; i < p_module->push_constant_block_count; ++i) { -@@ -4283,6 +4384,36 @@ SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables(const SpvReflec - return SPV_REFLECT_RESULT_SUCCESS; - } - -+// -- GODOT begin -- -+SpvReflectResult spvReflectEnumerateSpecializationConstants( -+ const SpvReflectShaderModule* p_module, -+ uint32_t* p_count, -+ SpvReflectSpecializationConstant** pp_constants -+) { -+ if (IsNull(p_module)) { -+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER; -+ } -+ if (IsNull(p_count)) { -+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER; -+ } -+ -+ if (IsNotNull(pp_constants)) { -+ if (*p_count != p_module->specialization_constant_count) { -+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH; -+ } -+ -+ for (uint32_t index = 0; index < *p_count; ++index) { -+ SpvReflectSpecializationConstant *p_const = &p_module->specialization_constants[index]; -+ pp_constants[index] = p_const; -+ } -+ } else { -+ *p_count = p_module->specialization_constant_count; -+ } -+ -+ return SPV_REFLECT_RESULT_SUCCESS; -+} -+// -- GODOT end -- -+ - SpvReflectResult spvReflectEnumerateInputVariables(const SpvReflectShaderModule* p_module, uint32_t* p_count, - SpvReflectInterfaceVariable** pp_variables) { - if (IsNull(p_module)) { -diff --git a/thirdparty/spirv-reflect/spirv_reflect.h b/thirdparty/spirv-reflect/spirv_reflect.h -index 08550e8f02..24446f1c1b 100644 ---- a/thirdparty/spirv-reflect/spirv_reflect.h -+++ b/thirdparty/spirv-reflect/spirv_reflect.h -@@ -374,6 +374,30 @@ typedef struct SpvReflectTypeDescription { - struct SpvReflectTypeDescription* members; - } SpvReflectTypeDescription; - -+// -- GODOT begin -- -+/*! @enum SpvReflectSpecializationConstantType -+ -+*/ -+typedef enum SpvReflectSpecializationConstantType { -+ SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL = 0, -+ SPV_REFLECT_SPECIALIZATION_CONSTANT_INT = 1, -+ SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT = 2, -+} SpvReflectSpecializationConstantType; -+ -+/*! @struct SpvReflectSpecializationConstant -+ -+*/ -+typedef struct SpvReflectSpecializationConstant { -+ const char* name; -+ uint32_t spirv_id; -+ uint32_t constant_id; -+ SpvReflectSpecializationConstantType constant_type; -+ union { -+ float float_value; -+ uint32_t int_bool_value; -+ } default_value; -+} SpvReflectSpecializationConstant; -+// -- GODOT end -- - - /*! @struct SpvReflectInterfaceVariable - @brief The OpVariable that is either an Input or Output to the module -@@ -549,6 +573,10 @@ typedef struct SpvReflectShaderModule { - SpvReflectInterfaceVariable* interface_variables; // Uses value(s) from first entry point - uint32_t push_constant_block_count; // Uses value(s) from first entry point - SpvReflectBlockVariable* push_constant_blocks; // Uses value(s) from first entry point -+// -- GODOT begin -- -+ uint32_t specialization_constant_count; -+ SpvReflectSpecializationConstant* specialization_constants; -+// -- GODOT end -- - - struct Internal { - SpvReflectModuleFlags module_flags; -@@ -821,6 +849,32 @@ SpvReflectResult spvReflectEnumerateInputVariables( - SpvReflectInterfaceVariable** pp_variables - ); - -+// -- GOODT begin -- -+/*! @fn spvReflectEnumerateSpecializationConstants -+ @brief If the module contains multiple entry points, this will only get -+ the specialization constants for the first one. -+ @param p_module Pointer to an instance of SpvReflectShaderModule. -+ @param p_count If pp_constants is NULL, the module's specialization constant -+ count will be stored here. -+ If pp_variables is not NULL, *p_count must contain -+ the module's specialization constant count. -+ @param pp_variables If NULL, the module's specialization constant count will be -+ written to *p_count. -+ If non-NULL, pp_constants must point to an array with -+ *p_count entries, where pointers to the module's -+ specialization constants will be written. The caller must not -+ free the specialization constants written to this array. -+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS. -+ Otherwise, the error code indicates the cause of the -+ failure. -+*/ -+SpvReflectResult spvReflectEnumerateSpecializationConstants( -+ const SpvReflectShaderModule* p_module, -+ uint32_t* p_count, -+ SpvReflectSpecializationConstant** pp_constants -+); -+// -- GODOT end -- -+ - /*! @fn spvReflectEnumerateEntryPointInputVariables - @brief Enumerate the input variables for a given entry point. - @param entry_point The name of the entry point to get the input variables for. diff --git a/thirdparty/spirv-reflect/spirv_reflect.c b/thirdparty/spirv-reflect/spirv_reflect.c index b4f6bc17c2..c96dd85439 100644 --- a/thirdparty/spirv-reflect/spirv_reflect.c +++ b/thirdparty/spirv-reflect/spirv_reflect.c @@ -1571,6 +1571,10 @@ static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser, SpvRefle } break; case SpvDecorationSpecId: { +// -- GODOT begin -- + uint32_t word_offset = p_node->word_offset + member_offset+ 3; + CHECKED_READU32(p_parser, word_offset, p_target_decorations->spec_id); +// -- GODOT end -- spec_constant_count++; } break; @@ -1692,21 +1696,45 @@ 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 (p_node->op == SpvOpDecorate) { - uint32_t decoration = (uint32_t)INVALID_VALUE; - CHECKED_READU32(p_parser, p_node->word_offset + 2, decoration); - if (decoration == SpvDecorationSpecId) { - const uint32_t count = p_module->spec_constant_count; - CHECKED_READU32(p_parser, p_node->word_offset + 1, p_module->spec_constants[count].spirv_id); - CHECKED_READU32(p_parser, p_node->word_offset + 3, p_module->spec_constants[count].constant_id); - // If being used for a OpSpecConstantComposite (ex. LocalSizeId), there won't be a name - SpvReflectPrvNode* target_node = FindNode(p_parser, p_module->spec_constants[count].spirv_id); - if (IsNotNull(target_node)) { - p_module->spec_constants[count].name = target_node->name; +// -- GODOT begin -- + const uint32_t count = p_module->spec_constant_count; + switch(p_node->op) { + default: continue; + case SpvOpSpecConstantTrue: { + p_module->spec_constants[count].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL; + p_module->spec_constants[count].default_value.int_bool_value = 1; + } break; + case SpvOpSpecConstantFalse: { + p_module->spec_constants[count].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL; + p_module->spec_constants[count].default_value.int_bool_value = 0; + } break; + case SpvOpSpecConstant: { + SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS; + uint32_t element_type_id = (uint32_t)INVALID_VALUE; + uint32_t default_value = 0; + CHECKED_READU32(p_parser, p_node->word_offset + 1, element_type_id); + CHECKED_READU32(p_parser, p_node->word_offset + 3, default_value); + + SpvReflectPrvNode* p_next_node = FindNode(p_parser, element_type_id); + + if (p_next_node->op == SpvOpTypeInt) { + p_module->spec_constants[count].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_INT; + } else if (p_next_node->op == SpvOpTypeFloat) { + p_module->spec_constants[count].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT; + } else { + return SPV_REFLECT_RESULT_ERROR_PARSE_FAILED; } - p_module->spec_constant_count++; - } + + p_module->spec_constants[count].default_value.int_bool_value = default_value; //bits are the same for int and float + } break; } + + p_module->spec_constants[count].name = p_node->name; + p_module->spec_constants[count].constant_id = p_node->decorations.spec_id; + p_module->spec_constants[count].spirv_id = p_node->result_id; + + p_module->spec_constant_count++; +// -- GODOT end -- } return SPV_REFLECT_RESULT_SUCCESS; diff --git a/thirdparty/spirv-reflect/spirv_reflect.h b/thirdparty/spirv-reflect/spirv_reflect.h index 9a42f14eed..4ea0319c5e 100644 --- a/thirdparty/spirv-reflect/spirv_reflect.h +++ b/thirdparty/spirv-reflect/spirv_reflect.h @@ -568,6 +568,17 @@ typedef struct SpvReflectCapability { } SpvReflectCapability; +// -- GODOT begin -- +/*! @enum SpvReflectSpecializationConstantType + +*/ +typedef enum SpvReflectSpecializationConstantType { + SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL = 0, + SPV_REFLECT_SPECIALIZATION_CONSTANT_INT = 1, + SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT = 2, +} SpvReflectSpecializationConstantType; +// -- GODOT end -- + /*! @struct SpvReflectSpecId */ @@ -575,6 +586,13 @@ typedef struct SpvReflectSpecializationConstant { uint32_t spirv_id; uint32_t constant_id; const char* name; +// -- GODOT begin -- + SpvReflectSpecializationConstantType constant_type; + union { + float float_value; + uint32_t int_bool_value; + } default_value; +// -- GODOT end -- } SpvReflectSpecializationConstant; /*! @struct SpvReflectShaderModule