diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2021-06-03 15:13:18 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-03 15:13:18 +0300 |
commit | 2e1b5fb39ebc2ef4cb77005f8267e4f3a6241ba1 (patch) | |
tree | d61c562053e81a1a69bcd66cd61bd0f26931c69d /spirv_glsl.cpp | |
parent | fa42f1ce34317d55189e05bfdb01c612bb1aa9fe (diff) | |
parent | 449f68ef3b0bc7ed1d62aea63beee4f85967fb60 (diff) |
Merge pull request #1686 from KhronosGroup/fix-1684
GLSL: Support control flow hints
Diffstat (limited to 'spirv_glsl.cpp')
-rw-r--r-- | spirv_glsl.cpp | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 99f42638..bde261eb 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -823,6 +823,22 @@ void CompilerGLSL::emit_header() statement("#extension ", ext, " : enable"); statement("#endif"); } + else if (ext == "GL_EXT_control_flow_attributes") + { + // These are just hints so we can conditionally enable and fallback in the shader. + statement("#if defined(GL_EXT_control_flow_attributes)"); + statement("#extension GL_EXT_control_flow_attributes : require"); + statement("#define SPIRV_CROSS_FLATTEN [[flatten]]"); + statement("#define SPIRV_CROSS_BRANCH [[dont_flatten]]"); + statement("#define SPIRV_CROSS_UNROLL [[unroll]]"); + statement("#define SPIRV_CROSS_LOOP [[dont_unroll]]"); + statement("#else"); + statement("#define SPIRV_CROSS_FLATTEN"); + statement("#define SPIRV_CROSS_BRANCH"); + statement("#define SPIRV_CROSS_UNROLL"); + statement("#define SPIRV_CROSS_LOOP"); + statement("#endif"); + } else statement("#extension ", ext, " : require"); } @@ -14004,7 +14020,10 @@ void CompilerGLSL::branch(BlockID from, uint32_t cond, BlockID true_block, Block if (!true_block_needs_code && !false_block_needs_code) return; - emit_block_hints(get<SPIRBlock>(from)); + // We might have a loop merge here. Only consider selection flattening constructs. + // Loop hints are handled explicitly elsewhere. + if (from_block.hint == SPIRBlock::HintFlatten || from_block.hint == SPIRBlock::HintDontFlatten) + emit_block_hints(from_block); if (true_block_needs_code) { @@ -14510,6 +14529,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) // for (;;) { create-temporary; break; } consume-temporary; // so force-declare temporaries here. emit_hoisted_temporaries(block.potential_declare_temporary); + emit_block_hints(block); statement("for (;;)"); begin_scope(); @@ -15376,8 +15396,32 @@ void CompilerGLSL::convert_non_uniform_expression(string &expr, uint32_t ptr_id) expr.substr(end_array_index, string::npos)); } -void CompilerGLSL::emit_block_hints(const SPIRBlock &) +void CompilerGLSL::emit_block_hints(const SPIRBlock &block) { + if ((options.es && options.version < 310) || (!options.es && options.version < 140)) + return; + + switch (block.hint) + { + case SPIRBlock::HintFlatten: + require_extension_internal("GL_EXT_control_flow_attributes"); + statement("SPIRV_CROSS_FLATTEN"); + break; + case SPIRBlock::HintDontFlatten: + require_extension_internal("GL_EXT_control_flow_attributes"); + statement("SPIRV_CROSS_BRANCH"); + break; + case SPIRBlock::HintUnroll: + require_extension_internal("GL_EXT_control_flow_attributes"); + statement("SPIRV_CROSS_UNROLL"); + break; + case SPIRBlock::HintDontUnroll: + require_extension_internal("GL_EXT_control_flow_attributes"); + statement("SPIRV_CROSS_LOOP"); + break; + default: + break; + } } void CompilerGLSL::preserve_alias_on_reset(uint32_t id) |