diff options
Diffstat (limited to 'gfx/angle/src/compiler/translator/Compiler.cpp')
-rwxr-xr-x | gfx/angle/src/compiler/translator/Compiler.cpp | 504 |
1 files changed, 217 insertions, 287 deletions
diff --git a/gfx/angle/src/compiler/translator/Compiler.cpp b/gfx/angle/src/compiler/translator/Compiler.cpp index e085ed588..0257dd3a7 100755 --- a/gfx/angle/src/compiler/translator/Compiler.cpp +++ b/gfx/angle/src/compiler/translator/Compiler.cpp @@ -4,18 +4,11 @@ // found in the LICENSE file. // -#include "compiler/translator/Compiler.h" - -#include <sstream> - -#include "angle_gl.h" -#include "common/utilities.h" -#include "compiler/translator/AddAndTrueToLoopCondition.h" #include "compiler/translator/Cache.h" +#include "compiler/translator/Compiler.h" #include "compiler/translator/CallDAG.h" #include "compiler/translator/DeferGlobalInitializers.h" #include "compiler/translator/EmulateGLFragColorBroadcast.h" -#include "compiler/translator/EmulatePrecision.h" #include "compiler/translator/ForLoopUnroll.h" #include "compiler/translator/Initialize.h" #include "compiler/translator/InitializeParseContext.h" @@ -23,100 +16,41 @@ #include "compiler/translator/ParseContext.h" #include "compiler/translator/PruneEmptyDeclarations.h" #include "compiler/translator/RegenerateStructNames.h" -#include "compiler/translator/RemoveInvariantDeclaration.h" #include "compiler/translator/RemovePow.h" +#include "compiler/translator/RenameFunction.h" #include "compiler/translator/RewriteDoWhile.h" #include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h" #include "compiler/translator/UnfoldShortCircuitAST.h" -#include "compiler/translator/UseInterfaceBlockFields.h" #include "compiler/translator/ValidateLimitations.h" #include "compiler/translator/ValidateMaxParameters.h" #include "compiler/translator/ValidateOutputs.h" #include "compiler/translator/VariablePacker.h" +#include "compiler/translator/depgraph/DependencyGraph.h" +#include "compiler/translator/depgraph/DependencyGraphOutput.h" +#include "compiler/translator/timing/RestrictFragmentShaderTiming.h" +#include "compiler/translator/timing/RestrictVertexShaderTiming.h" #include "third_party/compiler/ArrayBoundsClamper.h" - -namespace sh -{ - -namespace -{ - -#if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) -void DumpFuzzerCase(char const *const *shaderStrings, - size_t numStrings, - uint32_t type, - uint32_t spec, - uint32_t output, - uint64_t options) -{ - static int fileIndex = 0; - - std::ostringstream o; - o << "corpus/" << fileIndex++ << ".sample"; - std::string s = o.str(); - - // Must match the input format of the fuzzer - FILE *f = fopen(s.c_str(), "w"); - fwrite(&type, sizeof(type), 1, f); - fwrite(&spec, sizeof(spec), 1, f); - fwrite(&output, sizeof(output), 1, f); - fwrite(&options, sizeof(options), 1, f); - - char zero[128 - 20] = {0}; - fwrite(&zero, 128 - 20, 1, f); - - for (size_t i = 0; i < numStrings; i++) - { - fwrite(shaderStrings[i], sizeof(char), strlen(shaderStrings[i]), f); - } - fwrite(&zero, 1, 1, f); - - fclose(f); -} -#endif // defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) -} // anonymous namespace +#include "angle_gl.h" +#include "common/utilities.h" bool IsWebGLBasedSpec(ShShaderSpec spec) { - return (spec == SH_WEBGL_SPEC || spec == SH_WEBGL2_SPEC || spec == SH_WEBGL3_SPEC); + return (spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC || spec == SH_WEBGL2_SPEC || + spec == SH_WEBGL3_SPEC); } bool IsGLSL130OrNewer(ShShaderOutput output) { - return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT || - output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT || - output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT || - output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT || - output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT); -} - -bool IsGLSL420OrNewer(ShShaderOutput output) -{ - return (output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT || - output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT); -} - -bool IsGLSL410OrOlder(ShShaderOutput output) -{ - return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT || - output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT || - output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT); -} - -bool RemoveInvariant(sh::GLenum shaderType, - int shaderVersion, - ShShaderOutput outputType, - ShCompileOptions compileOptions) -{ - if ((compileOptions & SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT) == 0 && - shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType)) - return true; - - if ((compileOptions & SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3) != 0 && - shaderVersion >= 300 && shaderType == GL_VERTEX_SHADER && IsGLSL410OrOlder(outputType)) - return true; - - return false; + return (output == SH_GLSL_130_OUTPUT || + output == SH_GLSL_140_OUTPUT || + output == SH_GLSL_150_CORE_OUTPUT || + output == SH_GLSL_330_CORE_OUTPUT || + output == SH_GLSL_400_CORE_OUTPUT || + output == SH_GLSL_410_CORE_OUTPUT || + output == SH_GLSL_420_CORE_OUTPUT || + output == SH_GLSL_430_CORE_OUTPUT || + output == SH_GLSL_440_CORE_OUTPUT || + output == SH_GLSL_450_CORE_OUTPUT); } size_t GetGlobalMaxTokenSize(ShShaderSpec spec) @@ -125,10 +59,11 @@ size_t GetGlobalMaxTokenSize(ShShaderSpec spec) // size undefined. ES3 defines a max size of 1024 characters. switch (spec) { - case SH_WEBGL_SPEC: - return 256; - default: - return 1024; + case SH_WEBGL_SPEC: + case SH_CSS_SHADERS_SPEC: + return 256; + default: + return 1024; } } @@ -174,18 +109,19 @@ int MapSpecToShaderVersion(ShShaderSpec spec) { switch (spec) { - case SH_GLES2_SPEC: - case SH_WEBGL_SPEC: - return 100; - case SH_GLES3_SPEC: - case SH_WEBGL2_SPEC: - return 300; - case SH_GLES3_1_SPEC: - case SH_WEBGL3_SPEC: - return 310; - default: - UNREACHABLE(); - return 0; + case SH_GLES2_SPEC: + case SH_WEBGL_SPEC: + case SH_CSS_SHADERS_SPEC: + return 100; + case SH_GLES3_SPEC: + case SH_WEBGL2_SPEC: + return 300; + case SH_GLES3_1_SPEC: + case SH_WEBGL3_SPEC: + return 310; + default: + UNREACHABLE(); + return 0; } } @@ -226,7 +162,7 @@ TCompiler::~TCompiler() { } -bool TCompiler::shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const +bool TCompiler::shouldRunLoopAndIndexingValidation(int compileOptions) const { // If compiling an ESSL 1.00 shader for WebGL, or if its been requested through the API, // validate loop and indexing as well (to verify that the shader only uses minimal functionality @@ -261,16 +197,15 @@ bool TCompiler::Init(const ShBuiltInResources& resources) return true; } -TIntermBlock *TCompiler::compileTreeForTesting(const char *const shaderStrings[], - size_t numStrings, - ShCompileOptions compileOptions) +TIntermNode *TCompiler::compileTreeForTesting(const char* const shaderStrings[], + size_t numStrings, int compileOptions) { return compileTreeImpl(shaderStrings, numStrings, compileOptions); } -TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], - size_t numStrings, - const ShCompileOptions compileOptions) +TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], + size_t numStrings, + const int compileOptions) { clearResults(); @@ -288,7 +223,8 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], ++firstSource; } - TParseContext parseContext(symbolTable, extensionBehavior, shaderType, shaderSpec, + TIntermediate intermediate(infoSink); + TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec, compileOptions, true, infoSink, getResources()); parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh); @@ -311,7 +247,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], success = false; } - TIntermBlock *root = nullptr; + TIntermNode *root = nullptr; if (success) { @@ -322,6 +258,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize(); root = parseContext.getTreeRoot(); + root = intermediate.postProcess(root); // Highp might have been auto-enabled based on shader version fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh(); @@ -358,17 +295,11 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], if (success && shouldRunLoopAndIndexingValidation(compileOptions)) success = validateLimitations(root); - // Fail compilation if precision emulation not supported. - if (success && getResources().WEBGL_debug_shader_precision && - getPragma().debugShaderPrecision) - { - if (!EmulatePrecision::SupportedInLanguage(outputType)) - { - infoSink.info.prefix(EPrefixError); - infoSink.info << "Precision emulation not supported for this output type."; - success = false; - } - } + if (success && (compileOptions & SH_TIMING_RESTRICTIONS)) + success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0); + + if (success && shaderSpec == SH_CSS_SHADERS_SPEC) + rewriteCSSShader(root); // Unroll for-loop markup needs to happen after validateLimitations pass. if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) @@ -410,16 +341,10 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], (outputType == SH_GLSL_COMPATIBILITY_OUTPUT))) initializeGLPosition(root); - if (success && RemoveInvariant(shaderType, shaderVersion, outputType, compileOptions)) - sh::RemoveInvariantDeclaration(root); - // This pass might emit short circuits so keep it before the short circuit unfolding if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS)) RewriteDoWhile(root, getTemporaryIndex()); - if (success && (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION)) - sh::AddAndTrueToLoopCondition(root); - if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) { UnfoldShortCircuitAST unfoldShortCircuit; @@ -435,10 +360,6 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], if (success && shouldCollectVariables(compileOptions)) { collectVariables(root); - if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS) - { - useAllMembersInUnusedStandardAndSharedBlocks(root); - } if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) { success = enforcePackingRestrictions(); @@ -456,8 +377,9 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS)) { - ScalarizeVecAndMatConstructorArgs(root, shaderType, fragmentPrecisionHigh, - &mTemporaryIndex); + ScalarizeVecAndMatConstructorArgs scalarizer( + shaderType, fragmentPrecisionHigh); + root->traverse(&scalarizer); } if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES)) @@ -486,18 +408,12 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], return NULL; } -bool TCompiler::compile(const char *const shaderStrings[], - size_t numStrings, - ShCompileOptions compileOptionsIn) +bool TCompiler::compile(const char *const shaderStrings[], size_t numStrings, int compileOptionsIn) { -#if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) - DumpFuzzerCase(shaderStrings, numStrings, shaderType, shaderSpec, outputType, compileOptionsIn); -#endif // defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) - if (numStrings == 0) return true; - ShCompileOptions compileOptions = compileOptionsIn; + int compileOptions = compileOptionsIn; // Apply key workarounds. if (shouldFlattenPragmaStdglInvariantAll()) @@ -506,19 +422,8 @@ bool TCompiler::compile(const char *const shaderStrings[], compileOptions |= SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL; } - ShCompileOptions unrollFlags = - SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX | SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX; - if ((compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION) != 0 && - (compileOptions & unrollFlags) != 0) - { - infoSink.info.prefix(EPrefixError); - infoSink.info - << "Unsupported compile flag combination: unroll & ADD_TRUE_TO_LOOP_CONDITION"; - return false; - } - TScopedPoolAllocator scopedAlloc(&allocator); - TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions); + TIntermNode *root = compileTreeImpl(shaderStrings, numStrings, compileOptions); if (root) { @@ -547,26 +452,32 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) symbolTable.push(); // ESSL3_1_BUILTINS TPublicType integer; - integer.initializeBasicType(EbtInt); + integer.type = EbtInt; + integer.primarySize = 1; + integer.secondarySize = 1; + integer.array = false; TPublicType floatingPoint; - floatingPoint.initializeBasicType(EbtFloat); + floatingPoint.type = EbtFloat; + floatingPoint.primarySize = 1; + floatingPoint.secondarySize = 1; + floatingPoint.array = false; - switch (shaderType) + switch(shaderType) { - case GL_FRAGMENT_SHADER: - symbolTable.setDefaultPrecision(integer, EbpMedium); - break; - case GL_VERTEX_SHADER: - symbolTable.setDefaultPrecision(integer, EbpHigh); - symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); - break; - case GL_COMPUTE_SHADER: - symbolTable.setDefaultPrecision(integer, EbpHigh); - symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); - break; - default: - assert(false && "Language not supported"); + case GL_FRAGMENT_SHADER: + symbolTable.setDefaultPrecision(integer, EbpMedium); + break; + case GL_VERTEX_SHADER: + symbolTable.setDefaultPrecision(integer, EbpHigh); + symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); + break; + case GL_COMPUTE_SHADER: + symbolTable.setDefaultPrecision(integer, EbpHigh); + symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); + break; + default: + assert(false && "Language not supported"); } // Set defaults for sampler types that have default precision, even those that are // only available if an extension exists. @@ -589,7 +500,10 @@ void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType) { ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd); TPublicType sampler; - sampler.initializeBasicType(samplerType); + sampler.primarySize = 1; + sampler.secondarySize = 1; + sampler.array = false; + sampler.type = samplerType; symbolTable.setDefaultPrecision(sampler, EbpLow); } @@ -599,60 +513,60 @@ void TCompiler::setResourceString() // clang-format off strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs - << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors - << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors - << ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits - << ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits - << ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits - << ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors - << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers - << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives - << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external - << ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3 - << ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external - << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle - << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers - << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh - << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity - << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth - << ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters - << ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended - << ":EXT_frag_depth:" << compileResources.EXT_frag_depth - << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod - << ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch - << ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch - << ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch - << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors - << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors - << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset - << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset - << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers - << ":NV_draw_buffers:" << compileResources.NV_draw_buffers - << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision - << ":MaxImageUnits:" << compileResources.MaxImageUnits - << ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms - << ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms - << ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms - << ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms - << ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources - << ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0] - << ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1] - << ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2] - << ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0] - << ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1] - << ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2] - << ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents - << ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits - << ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters - << ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers - << ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters - << ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters - << ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters - << ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings - << ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers - << ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers - << ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers - << ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize; + << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors + << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors + << ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits + << ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits + << ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits + << ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors + << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers + << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives + << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external + << ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3 + << ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external + << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle + << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers + << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh + << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity + << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth + << ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters + << ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended + << ":EXT_frag_depth:" << compileResources.EXT_frag_depth + << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod + << ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch + << ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch + << ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch + << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors + << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors + << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset + << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset + << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers + << ":NV_draw_buffers:" << compileResources.NV_draw_buffers + << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision + << ":MaxImageUnits:" << compileResources.MaxImageUnits + << ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms + << ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms + << ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms + << ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms + << ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources + << ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0] + << ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1] + << ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2] + << ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0] + << ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1] + << ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2] + << ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents + << ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits + << ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters + << ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers + << ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters + << ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters + << ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters + << ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings + << ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers + << ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers + << ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers + << ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize; // clang-format on builtInResourcesString = strstream.str(); @@ -687,16 +601,16 @@ bool TCompiler::initCallDag(TIntermNode *root) switch (mCallDag.init(root, &infoSink.info)) { - case CallDAG::INITDAG_SUCCESS: - return true; - case CallDAG::INITDAG_RECURSION: - infoSink.info.prefix(EPrefixError); - infoSink.info << "Function recursion detected"; - return false; - case CallDAG::INITDAG_UNDEFINED: - infoSink.info.prefix(EPrefixError); - infoSink.info << "Unimplemented function detected"; - return false; + case CallDAG::INITDAG_SUCCESS: + return true; + case CallDAG::INITDAG_RECURSION: + infoSink.info.prefix(EPrefixError); + infoSink.info << "Function recursion detected"; + return false; + case CallDAG::INITDAG_UNDEFINED: + infoSink.info.prefix(EPrefixError); + infoSink.info << "Unimplemented function detected"; + return false; } UNREACHABLE(); @@ -790,38 +704,30 @@ class TCompiler::UnusedPredicate { public: UnusedPredicate(const CallDAG *callDag, const std::vector<FunctionMetadata> *metadatas) - : mCallDag(callDag), mMetadatas(metadatas) + : mCallDag(callDag), + mMetadatas(metadatas) { } bool operator ()(TIntermNode *node) { const TIntermAggregate *asAggregate = node->getAsAggregate(); - const TIntermFunctionDefinition *asFunction = node->getAsFunctionDefinition(); - - const TFunctionSymbolInfo *functionInfo = nullptr; - if (asFunction) + if (asAggregate == nullptr) { - functionInfo = asFunction->getFunctionSymbolInfo(); - } - else if (asAggregate) - { - if (asAggregate->getOp() == EOpPrototype) - { - functionInfo = asAggregate->getFunctionSymbolInfo(); - } + return false; } - if (functionInfo == nullptr) + + if (!(asAggregate->getOp() == EOpFunction || asAggregate->getOp() == EOpPrototype)) { return false; } - size_t callDagIndex = mCallDag->findIndex(functionInfo); + size_t callDagIndex = mCallDag->findIndex(asAggregate); if (callDagIndex == CallDAG::InvalidIndex) { // This happens only for unimplemented prototypes which are thus unused - ASSERT(asAggregate && asAggregate->getOp() == EOpPrototype); + ASSERT(asAggregate->getOp() == EOpPrototype); return true; } @@ -834,10 +740,13 @@ class TCompiler::UnusedPredicate const std::vector<FunctionMetadata> *mMetadatas; }; -bool TCompiler::pruneUnusedFunctions(TIntermBlock *root) +bool TCompiler::pruneUnusedFunctions(TIntermNode *root) { + TIntermAggregate *rootNode = root->getAsAggregate(); + ASSERT(rootNode != nullptr); + UnusedPredicate isUnused(&mCallDag, &functionMetadata); - TIntermSequence *sequence = root->getSequence(); + TIntermSequence *sequence = rootNode->getSequence(); if (!sequence->empty()) { @@ -854,6 +763,12 @@ bool TCompiler::validateOutputs(TIntermNode* root) return (validateOutputs.validateAndCountErrors(infoSink.info) == 0); } +void TCompiler::rewriteCSSShader(TIntermNode* root) +{ + RenameFunction renamer("main(", "css_main("); + root->traverse(&renamer); +} + bool TCompiler::validateLimitations(TIntermNode* root) { ValidateLimitations validate(shaderType, &infoSink.info); @@ -861,9 +776,39 @@ bool TCompiler::validateLimitations(TIntermNode* root) return validate.numErrors() == 0; } +bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph) +{ + if (shaderSpec != SH_WEBGL_SPEC) + { + infoSink.info << "Timing restrictions must be enforced under the WebGL spec."; + return false; + } + + if (shaderType == GL_FRAGMENT_SHADER) + { + TDependencyGraph graph(root); + + // Output any errors first. + bool success = enforceFragmentShaderTimingRestrictions(graph); + + // Then, output the dependency graph. + if (outputGraph) + { + TDependencyGraphOutput output(infoSink.info); + output.outputAllSpanningTrees(graph); + } + + return success; + } + else + { + return enforceVertexShaderTimingRestrictions(root); + } +} + bool TCompiler::limitExpressionComplexity(TIntermNode* root) { - TMaxDepthTraverser traverser(maxExpressionComplexity + 1); + TMaxDepthTraverser traverser(maxExpressionComplexity+1); root->traverse(&traverser); if (traverser.getMaxDepth() > maxExpressionComplexity) @@ -881,13 +826,26 @@ bool TCompiler::limitExpressionComplexity(TIntermNode* root) return true; } +bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph) +{ + RestrictFragmentShaderTiming restrictor(infoSink.info); + restrictor.enforceRestrictions(graph); + return restrictor.numErrors() == 0; +} + +bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root) +{ + RestrictVertexShaderTiming restrictor(infoSink.info); + restrictor.enforceRestrictions(root); + return restrictor.numErrors() == 0; +} + void TCompiler::collectVariables(TIntermNode* root) { if (!variablesCollected) { sh::CollectVariables collect(&attributes, &outputVariables, &uniforms, &varyings, - &interfaceBlocks, hashFunction, symbolTable, - extensionBehavior); + &interfaceBlocks, hashFunction, symbolTable, extensionBehavior); root->traverse(&collect); // This is for enforcePackingRestriction(). @@ -896,16 +854,6 @@ void TCompiler::collectVariables(TIntermNode* root) } } -bool TCompiler::shouldCollectVariables(ShCompileOptions compileOptions) -{ - return (compileOptions & SH_VARIABLES) != 0; -} - -bool TCompiler::wereVariablesCollected() const -{ - return variablesCollected; -} - bool TCompiler::enforcePackingRestrictions() { VariablePacker packer; @@ -918,23 +866,7 @@ void TCompiler::initializeGLPosition(TIntermNode* root) sh::ShaderVariable var(GL_FLOAT_VEC4, 0); var.name = "gl_Position"; list.push_back(var); - InitializeVariables(root, list, symbolTable); -} - -void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root) -{ - sh::InterfaceBlockList list; - - for (auto block : interfaceBlocks) - { - if (!block.staticUse && - (block.layout == sh::BLOCKLAYOUT_STANDARD || block.layout == sh::BLOCKLAYOUT_SHARED)) - { - list.push_back(block); - } - } - - sh::UseInterfaceBlockFields(root, list, symbolTable); + InitializeVariables(root, list); } void TCompiler::initializeOutputVariables(TIntermNode *root) @@ -955,7 +887,7 @@ void TCompiler::initializeOutputVariables(TIntermNode *root) list.push_back(var); } } - InitializeVariables(root, list, symbolTable); + InitializeVariables(root, list); } const TExtensionBehavior& TCompiler::getExtensionBehavior() const @@ -988,7 +920,7 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const return builtInFunctionEmulator; } -void TCompiler::writePragma(ShCompileOptions compileOptions) +void TCompiler::writePragma(int compileOptions) { if (!(compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL)) { @@ -1011,5 +943,3 @@ bool TCompiler::isVaryingDefined(const char *varyingName) return false; } - -} // namespace sh |