diff --git a/OGLCompilersDLL/InitializeDll.cpp b/OGLCompilersDLL/InitializeDll.cpp index 8804ae853..7a9955d56 100644 --- a/OGLCompilersDLL/InitializeDll.cpp +++ b/OGLCompilersDLL/InitializeDll.cpp @@ -89,7 +89,7 @@ bool InitThread() InitializeGlobalPools(); - if (!InitializeGlobalParseContext()) + if (!InitializeThreadParseContext()) return false; if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) { diff --git a/Test/precision.vert b/Test/precision.vert new file mode 100644 index 000000000..5d073488c --- /dev/null +++ b/Test/precision.vert @@ -0,0 +1,25 @@ +#version 300 es + +in vec4 pos; + +uniform sampler2D s2D; +uniform samplerCube sCube; +uniform isampler2DArray is2DAbad; // ERROR, no default precision +uniform sampler2DArrayShadow s2dASbad; // ERROR, no default precision + +precision highp sampler2D; +precision mediump sampler2DArrayShadow; + +uniform sampler2DArrayShadow s2dAS; +uniform isampler2DArray is2DAbad2; // ERROR, still no default precision + +uniform sampler2D s2Dhigh; + +void main() +{ + vec4 t = texture(s2D, vec2(0.1, 0.2)); + t += texture(s2Dhigh, vec2(0.1, 0.2)); + t += texture(s2dAS, vec4(0.5)); + + gl_Position = pos; +} diff --git a/glslang/Include/InitializeParseContext.h b/glslang/Include/InitializeParseContext.h index 4d369e8af..6fe095e7f 100644 --- a/glslang/Include/InitializeParseContext.h +++ b/glslang/Include/InitializeParseContext.h @@ -37,7 +37,7 @@ #include "osinclude.h" bool InitializeParseContextIndex(); -bool InitializeGlobalParseContext(); +bool InitializeThreadParseContext(); bool FreeParseContext(); bool FreeParseContextIndex(); diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index d6ac017ad..e6006c24d 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -2038,10 +2038,10 @@ bool InitializeParseContextIndex() return true; } -bool InitializeGlobalParseContext() +bool InitializeThreadParseContext() { if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "InitializeGlobalParseContext(): Parse Context index not initialized"); + assert(0 && "InitializeThreadParseContext(): Parse Context index not initialized"); return false; } @@ -2053,7 +2053,7 @@ bool InitializeGlobalParseContext() TThreadParseContext *lpThreadData = new TThreadParseContext(); if (lpThreadData == 0) { - assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context"); + assert(0 && "InitializeThreadParseContext(): Unable to create thread parse context"); return false; } @@ -2063,7 +2063,7 @@ bool InitializeGlobalParseContext() return true; } -TParseContextPointer& GetGlobalParseContext() +TParseContextPointer& ThreadLocalParseContext() { // // Minimal error checking for speed diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index aa7962d5b..990fd3fd2 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -185,8 +185,7 @@ int PaParseComment(int &lineno, TParseContext&); void ResetFlex(); typedef TParseContext* TParseContextPointer; -extern TParseContextPointer& GetGlobalParseContext(); -#define GlobalParseContext GetGlobalParseContext() +TParseContextPointer& ThreadLocalParseContext(); typedef struct TThreadParseContextRec { diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 20533d33d..6c84330c8 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -100,7 +100,7 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil TParseContext parseContext(*symbolTable, intermediate, true, version, profile, language, infoSink); - GlobalParseContext = &parseContext; + ThreadLocalParseContext() = &parseContext; assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel()); @@ -259,15 +259,14 @@ bool DeduceProfile(TInfoSink& infoSink, int version, EProfile& profile) }; // end anonymous namespace for local functions +// +// ShInitialize() should be called exactly once per process, not per thread. +// int ShInitialize() { if (! InitProcess()) return 0; - // TODO: Quality: Thread safety: - // This method should be called once per process. If it's called by multiple threads, then - // we need to have thread synchronization code around the initialization of per process - // global pool allocator if (! PerProcessGPA) { PerProcessGPA = new TPoolAllocator(true); } @@ -422,7 +421,7 @@ int ShCompile( else if (profile == EEsProfile && version >= 300 && versionNotFirst) parseContext.error(1, "statement must appear first in ESSL shader; before comments or newlines", "#version", ""); - GlobalParseContext = &parseContext; + ThreadLocalParseContext() = &parseContext; ResetFlex(); InitPreprocessor(); diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l index 0845f8ae0..1ca307daf 100644 --- a/glslang/MachineIndependent/glslang.l +++ b/glslang/MachineIndependent/glslang.l @@ -724,14 +724,14 @@ void yyerror(const char *s) if (pc.AfterEOF) { if (cpp->tokensBeforeEOF == 1) - GlobalParseContext->error(yylineno, "", "pre-mature EOF", s, ""); + ThreadLocalParseContext()->error(yylineno, "", "pre-mature EOF", s, ""); } else - GlobalParseContext->error(yylineno, "", yytext, s, ""); + ThreadLocalParseContext()->error(yylineno, "", yytext, s, ""); } void PaReservedWord() { - GlobalParseContext->error(yylineno, "Reserved word.", yytext, "", ""); + ThreadLocalParseContext()->error(yylineno, "Reserved word.", yytext, "", ""); } int PaIdentOrType(const char* yytext, TParseContext& parseContextLocal, YYSTYPE* pyylval) diff --git a/glslang/OSDependent/Linux/ossource.cpp b/glslang/OSDependent/Linux/ossource.cpp index 74a4107a3..879e83859 100644 --- a/glslang/OSDependent/Linux/ossource.cpp +++ b/glslang/OSDependent/Linux/ossource.cpp @@ -33,7 +33,7 @@ // // -// This file contains the Linux specific functions +// This file contains the Linux-specific functions // #include "osinclude.h" #include "InitializeDll.h" diff --git a/glslang/OSDependent/Windows/ossource.cpp b/glslang/OSDependent/Windows/ossource.cpp index 3c2cb85a0..697e690d0 100644 --- a/glslang/OSDependent/Windows/ossource.cpp +++ b/glslang/OSDependent/Windows/ossource.cpp @@ -34,7 +34,7 @@ #include "osinclude.h" // -// This file contains contains the window's specific functions +// This file contains contains the Window-OS-specific functions // #if !(defined(_WIN32) || defined(_WIN64)) diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index d20b5d73e..a6b057343 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -58,13 +58,17 @@ #ifdef __cplusplus extern "C" { #endif + // // Driver must call this first, once, before doing any other // compiler/linker operations. // -SH_IMPORT_EXPORT int ShInitialize(); +// (Call once per process, not once per thread.) // -// Driver should call this at shutdown. +SH_IMPORT_EXPORT int ShInitialize(); + +// +// Driver should call this at process shutdown. // SH_IMPORT_EXPORT int __fastcall ShFinalize();