diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2021-01-04 13:58:50 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2021-01-04 21:12:43 +0300 |
commit | a1c784f0028a150454c5a7c6f0ff2608760056db (patch) | |
tree | f8207a12495d44de70ccda5e46c024f204701686 /spirv_hlsl.cpp | |
parent | 9a304fe9315a5f5eb5bb3509f95a5b69595f57df (diff) |
More robust handling of initialized output builtin variables.
Diffstat (limited to 'spirv_hlsl.cpp')
-rw-r--r-- | spirv_hlsl.cpp | 37 |
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, ";"); } }); |