Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Cross.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2021-01-04 13:58:50 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2021-01-04 21:12:43 +0300
commita1c784f0028a150454c5a7c6f0ff2608760056db (patch)
treef8207a12495d44de70ccda5e46c024f204701686 /spirv_hlsl.cpp
parent9a304fe9315a5f5eb5bb3509f95a5b69595f57df (diff)
More robust handling of initialized output builtin variables.
Diffstat (limited to 'spirv_hlsl.cpp')
-rw-r--r--spirv_hlsl.cpp37
1 files changed, 34 insertions, 3 deletions
diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp
index a375183c..24eae998 100644
--- a/spirv_hlsl.cpp
+++ b/spirv_hlsl.cpp
@@ -1023,12 +1023,43 @@ void CompilerHLSL::emit_builtin_variables()
bool need_base_vertex_info = false;
+ std::unordered_map<uint32_t, ID> builtin_to_initializer;
+ ir.for_each_typed_id<SPIRVariable>([&](uint32_t, SPIRVariable &var) {
+ if (!is_builtin_variable(var) || var.storage != StorageClassOutput || !var.initializer)
+ return;
+
+ auto *c = this->maybe_get<SPIRConstant>(var.initializer);
+ if (!c)
+ return;
+
+ auto &type = this->get<SPIRType>(var.basetype);
+ if (type.basetype == SPIRType::Struct)
+ {
+ uint32_t member_count = uint32_t(type.member_types.size());
+ for (uint32_t i = 0; i < member_count; i++)
+ {
+ if (has_member_decoration(type.self, i, DecorationBuiltIn))
+ {
+ builtin_to_initializer[get_member_decoration(type.self, i, DecorationBuiltIn)] =
+ c->subconstants[i];
+ }
+ }
+ }
+ else if (has_decoration(var.self, DecorationBuiltIn))
+ builtin_to_initializer[get_decoration(var.self, DecorationBuiltIn)] = var.initializer;
+ });
+
// Emit global variables for the interface variables which are statically used by the shader.
builtins.for_each_bit([&](uint32_t i) {
const char *type = nullptr;
auto builtin = static_cast<BuiltIn>(i);
uint32_t array_size = 0;
+ string init_expr;
+ auto init_itr = builtin_to_initializer.find(builtin);
+ if (init_itr != builtin_to_initializer.end())
+ init_expr = join(" = ", to_expression(init_itr->second));
+
switch (builtin)
{
case BuiltInFragCoord:
@@ -1121,16 +1152,16 @@ void CompilerHLSL::emit_builtin_variables()
if (type)
{
if (array_size)
- statement("static ", type, " ", builtin_to_glsl(builtin, storage), "[", array_size, "];");
+ statement("static ", type, " ", builtin_to_glsl(builtin, storage), "[", array_size, "]", init_expr, ";");
else
- statement("static ", type, " ", builtin_to_glsl(builtin, storage), ";");
+ statement("static ", type, " ", builtin_to_glsl(builtin, storage), init_expr, ";");
}
// SampleMask can be both in and out with sample builtin, in this case we have already
// declared the input variable and we need to add the output one now.
if (builtin == BuiltInSampleMask && storage == StorageClassInput && this->active_output_builtins.get(i))
{
- statement("static ", type, " ", this->builtin_to_glsl(builtin, StorageClassOutput), ";");
+ statement("static ", type, " ", this->builtin_to_glsl(builtin, StorageClassOutput), init_expr, ";");
}
});