(glslang) Syntax cleanups, other cleanups

This commit is contained in:
libretroadmin 2024-05-23 16:35:45 +02:00
parent a8fe9b74da
commit e480ebd29f
15 changed files with 1316 additions and 1183 deletions

View File

@ -191,9 +191,9 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
break; break;
case EbtUint8: case EbtUint8:
if (rightUnionArray[i] == 0) { if (rightUnionArray[i] == 0)
newConstArray[i].setU8Const(0xFF); newConstArray[i].setU8Const(0xFF);
} else else
newConstArray[i].setU8Const(leftUnionArray[i].getU8Const() / rightUnionArray[i].getU8Const()); newConstArray[i].setU8Const(leftUnionArray[i].getU8Const() / rightUnionArray[i].getU8Const());
break; break;
@ -207,9 +207,9 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
break; break;
case EbtUint16: case EbtUint16:
if (rightUnionArray[i] == 0) { if (rightUnionArray[i] == 0)
newConstArray[i].setU16Const(0xFFFF); newConstArray[i].setU16Const(0xFFFF);
} else else
newConstArray[i].setU16Const(leftUnionArray[i].getU16Const() / rightUnionArray[i].getU16Const()); newConstArray[i].setU16Const(leftUnionArray[i].getU16Const() / rightUnionArray[i].getU16Const());
break; break;

View File

@ -104,7 +104,8 @@ protected:
return true; // traverse all code return true; // traverse all code
TIntermConstantUnion* constant = node->getCondition()->getAsConstantUnion(); TIntermConstantUnion* constant = node->getCondition()->getAsConstantUnion();
if (constant) { if (constant)
{
// cull the path that is dead // cull the path that is dead
if (constant->getConstArray()[0].getBConst() == true && node->getTrueBlock()) if (constant->getConstArray()[0].getBConst() == true && node->getTrueBlock())
node->getTrueBlock()->traverse(this); node->getTrueBlock()->traverse(this);
@ -112,7 +113,7 @@ protected:
node->getFalseBlock()->traverse(this); node->getFalseBlock()->traverse(this);
return false; // don't traverse any more, we did it all above return false; // don't traverse any more, we did it all above
} else }
return true; // traverse the whole subtree return true; // traverse the whole subtree
} }

View File

@ -81,22 +81,26 @@ bool TInputScanner::consumeComment()
get(); // consume the '/' get(); // consume the '/'
int c = peek(); int c = peek();
if (c == '/') { if (c == '/')
{
// a '//' style comment // a '//' style comment
get(); // consume the second '/' get(); // consume the second '/'
c = get(); c = get();
for (;;) { for (;;)
{
while (c != EndOfInput && c != '\\' && c != '\r' && c != '\n') while (c != EndOfInput && c != '\\' && c != '\r' && c != '\n')
c = get(); c = get();
if (c == EndOfInput || c == '\r' || c == '\n') { if (c == EndOfInput || c == '\r' || c == '\n')
{
while (c == '\r' || c == '\n') while (c == '\r' || c == '\n')
c = get(); c = get();
// we reached the end of the comment // we reached the end of the comment
break; break;
} else { }
else
{
// it's a '\', so we need to keep going, after skipping what's escaped // it's a '\', so we need to keep going, after skipping what's escaped
// read the skipped character // read the skipped character
@ -107,26 +111,30 @@ bool TInputScanner::consumeComment()
get(); get();
c = get(); c = get();
} }
}; }
// put back the last non-comment character // put back the last non-comment character
if (c != EndOfInput) if (c != EndOfInput)
unget(); unget();
} else if (c == '*') { }
else if (c == '*')
{
// a '/*' style comment // a '/*' style comment
get(); // consume the '*' get(); // consume the '*'
c = get(); c = get();
for (;;) { for (;;)
{
while (c != EndOfInput && c != '*') while (c != EndOfInput && c != '*')
c = get(); c = get();
if (c == '*') { if (c == '*')
{
c = get(); c = get();
if (c == '/') if (c == '/')
break; // end of comment break; // end of comment
// not end of comment // not end of comment
} else // end of input } else // end of input
break; break;
}; }
} }
else else
{ {
@ -141,7 +149,8 @@ bool TInputScanner::consumeComment()
// skip whitespace, then skip a comment, rinse, repeat // skip whitespace, then skip a comment, rinse, repeat
void TInputScanner::consumeWhitespaceComment(bool& foundNonSpaceTab) void TInputScanner::consumeWhitespaceComment(bool& foundNonSpaceTab)
{ {
for (;;) { for (;;)
{
consumeWhiteSpace(foundNonSpaceTab); consumeWhiteSpace(foundNonSpaceTab);
// if not starting a comment now, then done // if not starting a comment now, then done
@ -153,7 +162,7 @@ void TInputScanner::consumeWhitespaceComment(bool& foundNonSpaceTab)
foundNonSpaceTab = true; foundNonSpaceTab = true;
if (!consumeComment()) if (!consumeComment())
return; return;
}; }
} }
// Returns true if there was non-white space (e.g., a comment, newline) before the #version // Returns true if there was non-white space (e.g., a comment, newline) before the #version
@ -311,11 +320,10 @@ namespace glslang {
void TScanContext::fillInKeywordMap() void TScanContext::fillInKeywordMap()
{ {
if (KeywordMap != NULL) {
// this is really an error, as this should called only once per process // this is really an error, as this should called only once per process
// but, the only risk is if two threads called simultaneously // but, the only risk is if two threads called simultaneously
if (KeywordMap)
return; return;
}
KeywordMap = new std::unordered_map<const char*, int, str_hash, str_eq>; KeywordMap = new std::unordered_map<const char*, int, str_hash, str_eq>;
(*KeywordMap)["const"] = CONST; (*KeywordMap)["const"] = CONST;
@ -828,13 +836,13 @@ int TScanContext::tokenizeIdentifier()
return reservedWord(); return reservedWord();
auto it = KeywordMap->find(tokenText); auto it = KeywordMap->find(tokenText);
if (it == KeywordMap->end()) {
// Should have an identifier of some sort // Should have an identifier of some sort
if (it == KeywordMap->end())
return identifierOrType(); return identifierOrType();
}
keyword = it->second; keyword = it->second;
switch (keyword) { switch (keyword)
{
case CONST: case CONST:
case UNIFORM: case UNIFORM:
case IN: case IN:
@ -857,15 +865,17 @@ int TScanContext::tokenizeIdentifier()
return keyword; return keyword;
case NONUNIFORM: case NONUNIFORM:
if (_parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier)) if (_parseContext.extensionTurnedOn(
E_GL_EXT_nonuniform_qualifier))
return keyword; return keyword;
else
return identifierOrType(); return identifierOrType();
case SWITCH: case SWITCH:
case DEFAULT: case DEFAULT:
if ((_parseContext.profile == EEsProfile && _parseContext.version < 300) || if (( _parseContext.profile == EEsProfile
(_parseContext.profile != EEsProfile && _parseContext.version < 130)) && _parseContext.version < 300)
|| (_parseContext.profile != EEsProfile
&& _parseContext.version < 130))
reservedWord(); reservedWord();
return keyword; return keyword;
@ -899,19 +909,24 @@ int TScanContext::tokenizeIdentifier()
case ATTRIBUTE: case ATTRIBUTE:
case VARYING: case VARYING:
if (_parseContext.profile == EEsProfile && _parseContext.version >= 300) if (_parseContext.profile == EEsProfile
&& _parseContext.version >= 300)
reservedWord(); reservedWord();
return keyword; return keyword;
case BUFFER: case BUFFER:
if ((_parseContext.profile == EEsProfile && _parseContext.version < 310) || if ((_parseContext.profile == EEsProfile
(_parseContext.profile != EEsProfile && _parseContext.version < 430)) && _parseContext.version < 310)
|| (_parseContext.profile != EEsProfile
&& _parseContext.version < 430))
return identifierOrType(); return identifierOrType();
return keyword; return keyword;
case ATOMIC_UINT: case ATOMIC_UINT:
if ((_parseContext.profile == EEsProfile && _parseContext.version >= 310) || if ((_parseContext.profile == EEsProfile
_parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters)) && _parseContext.version >= 310)
|| _parseContext.extensionTurnedOn(
E_GL_ARB_shader_atomic_counters))
return keyword; return keyword;
return es30ReservedFromGLSL(420); return es30ReservedFromGLSL(420);
@ -919,15 +934,20 @@ int TScanContext::tokenizeIdentifier()
case RESTRICT: case RESTRICT:
case READONLY: case READONLY:
case WRITEONLY: case WRITEONLY:
if (_parseContext.profile == EEsProfile && _parseContext.version >= 310) if (_parseContext.profile == EEsProfile
&& _parseContext.version >= 310)
return keyword; return keyword;
return es30ReservedFromGLSL(_parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store) ? 130 : 420); return es30ReservedFromGLSL(_parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store) ? 130 : 420);
case VOLATILE: case VOLATILE:
if (_parseContext.profile == EEsProfile && _parseContext.version >= 310) if (_parseContext.profile == EEsProfile
&& _parseContext.version >= 310)
return keyword; return keyword;
if (! _parseContext.symbolTable.atBuiltInLevel() && (_parseContext.profile == EEsProfile || if ( !_parseContext.symbolTable.atBuiltInLevel()
(_parseContext.version < 420 && ! _parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) && (_parseContext.profile == EEsProfile
|| (_parseContext.version < 420
&& !_parseContext.extensionTurnedOn(
E_GL_ARB_shader_image_load_store))))
reservedWord(); reservedWord();
return keyword; return keyword;
@ -936,15 +956,20 @@ int TScanContext::tokenizeIdentifier()
const int numLayoutExts = 2; const int numLayoutExts = 2;
const char* layoutExts[numLayoutExts] = { E_GL_ARB_shading_language_420pack, const char* layoutExts[numLayoutExts] = { E_GL_ARB_shading_language_420pack,
E_GL_ARB_explicit_attrib_location }; E_GL_ARB_explicit_attrib_location };
if ((_parseContext.profile == EEsProfile && _parseContext.version < 300) || if ( ( _parseContext.profile == EEsProfile
(_parseContext.profile != EEsProfile && _parseContext.version < 140 && && _parseContext.version < 300)
! _parseContext.extensionsTurnedOn(numLayoutExts, layoutExts))) || ( _parseContext.profile != EEsProfile
&& _parseContext.version < 140
&& ! _parseContext.extensionsTurnedOn(
numLayoutExts, layoutExts)))
return identifierOrType(); return identifierOrType();
return keyword; return keyword;
} }
case SHARED: case SHARED:
if ((_parseContext.profile == EEsProfile && _parseContext.version < 300) || if ((_parseContext.profile == EEsProfile
(_parseContext.profile != EEsProfile && _parseContext.version < 140)) && _parseContext.version < 300)
|| (_parseContext.profile != EEsProfile
&& _parseContext.version < 140))
return identifierOrType(); return identifierOrType();
return keyword; return keyword;
@ -959,8 +984,10 @@ int TScanContext::tokenizeIdentifier()
return es30ReservedFromGLSL(400); return es30ReservedFromGLSL(400);
case SAMPLE: case SAMPLE:
if ((_parseContext.profile == EEsProfile && _parseContext.version >= 320) || if ((_parseContext.profile == EEsProfile
_parseContext.extensionsTurnedOn(1, &E_GL_OES_shader_multisample_interpolation)) && _parseContext.version >= 320)
|| _parseContext.extensionsTurnedOn(1,
&E_GL_OES_shader_multisample_interpolation))
return keyword; return keyword;
return es30ReservedFromGLSL(400); return es30ReservedFromGLSL(400);
@ -972,7 +999,6 @@ int TScanContext::tokenizeIdentifier()
case LOW_PRECISION: case LOW_PRECISION:
case PRECISION: case PRECISION:
return precisionKeyword(); return precisionKeyword();
case MAT2X2: case MAT2X2:
case MAT2X3: case MAT2X3:
case MAT2X4: case MAT2X4:
@ -983,7 +1009,6 @@ int TScanContext::tokenizeIdentifier()
case MAT4X3: case MAT4X3:
case MAT4X4: case MAT4X4:
return matNxM(); return matNxM();
case DMAT2: case DMAT2:
case DMAT3: case DMAT3:
case DMAT4: case DMAT4:
@ -997,7 +1022,6 @@ int TScanContext::tokenizeIdentifier()
case DMAT4X3: case DMAT4X3:
case DMAT4X4: case DMAT4X4:
return dMat(); return dMat();
case IMAGE1D: case IMAGE1D:
case IIMAGE1D: case IIMAGE1D:
case UIMAGE1D: case UIMAGE1D:
@ -1009,13 +1033,14 @@ int TScanContext::tokenizeIdentifier()
case UIMAGE2DRECT: case UIMAGE2DRECT:
afterType = true; afterType = true;
return firstGenerationImage(false); return firstGenerationImage(false);
case IMAGEBUFFER: case IMAGEBUFFER:
case IIMAGEBUFFER: case IIMAGEBUFFER:
case UIMAGEBUFFER: case UIMAGEBUFFER:
afterType = true; afterType = true;
if ((_parseContext.profile == EEsProfile && _parseContext.version >= 320) || if ((_parseContext.profile == EEsProfile
_parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) && _parseContext.version >= 320)
|| _parseContext.extensionsTurnedOn(
Num_AEP_texture_buffer, AEP_texture_buffer))
return keyword; return keyword;
return firstGenerationImage(false); return firstGenerationImage(false);
@ -1038,8 +1063,11 @@ int TScanContext::tokenizeIdentifier()
case IIMAGECUBEARRAY: case IIMAGECUBEARRAY:
case UIMAGECUBEARRAY: case UIMAGECUBEARRAY:
afterType = true; afterType = true;
if ((_parseContext.profile == EEsProfile && _parseContext.version >= 320) || if ((_parseContext.profile == EEsProfile
_parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array)) && _parseContext.version >= 320)
|| _parseContext.extensionsTurnedOn(
Num_AEP_texture_cube_map_array,
AEP_texture_cube_map_array))
return keyword; return keyword;
return secondGenerationImage(); return secondGenerationImage();
@ -1057,7 +1085,8 @@ int TScanContext::tokenizeIdentifier()
case DVEC3: case DVEC3:
case DVEC4: case DVEC4:
afterType = true; afterType = true;
if (_parseContext.profile == EEsProfile || _parseContext.version < 400) if (_parseContext.profile == EEsProfile
|| _parseContext.version < 400)
reservedWord(); reservedWord();
return keyword; return keyword;
@ -1210,10 +1239,16 @@ int TScanContext::tokenizeIdentifier()
case ISAMPLERCUBEARRAY: case ISAMPLERCUBEARRAY:
case USAMPLERCUBEARRAY: case USAMPLERCUBEARRAY:
afterType = true; afterType = true;
if ((_parseContext.profile == EEsProfile && _parseContext.version >= 320) || if ((_parseContext.profile == EEsProfile
_parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array)) && _parseContext.version >= 320)
|| _parseContext.extensionsTurnedOn(
Num_AEP_texture_cube_map_array,
AEP_texture_cube_map_array))
return keyword; return keyword;
if (_parseContext.profile == EEsProfile || (_parseContext.version < 400 && ! _parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array))) if ( _parseContext.profile == EEsProfile
|| ( _parseContext.version < 400
&& ! _parseContext.extensionTurnedOn(
E_GL_ARB_texture_cube_map_array)))
reservedWord(); reservedWord();
return keyword; return keyword;
@ -1250,16 +1285,20 @@ int TScanContext::tokenizeIdentifier()
case SAMPLERBUFFER: case SAMPLERBUFFER:
afterType = true; afterType = true;
if ((_parseContext.profile == EEsProfile && _parseContext.version >= 320) || if ((_parseContext.profile == EEsProfile
_parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) && _parseContext.version >= 320)
|| _parseContext.extensionsTurnedOn(
Num_AEP_texture_buffer, AEP_texture_buffer))
return keyword; return keyword;
return es30ReservedFromGLSL(130); return es30ReservedFromGLSL(130);
case ISAMPLERBUFFER: case ISAMPLERBUFFER:
case USAMPLERBUFFER: case USAMPLERBUFFER:
afterType = true; afterType = true;
if ((_parseContext.profile == EEsProfile && _parseContext.version >= 320) || if ((_parseContext.profile == EEsProfile
_parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) && _parseContext.version >= 320)
|| _parseContext.extensionsTurnedOn(
Num_AEP_texture_buffer, AEP_texture_buffer))
return keyword; return keyword;
return es30ReservedFromGLSL(140); return es30ReservedFromGLSL(140);
@ -1267,7 +1306,8 @@ int TScanContext::tokenizeIdentifier()
case ISAMPLER2DMS: case ISAMPLER2DMS:
case USAMPLER2DMS: case USAMPLER2DMS:
afterType = true; afterType = true;
if (_parseContext.profile == EEsProfile && _parseContext.version >= 310) if (_parseContext.profile == EEsProfile
&& _parseContext.version >= 310)
return keyword; return keyword;
return es30ReservedFromGLSL(150); return es30ReservedFromGLSL(150);
@ -1275,8 +1315,10 @@ int TScanContext::tokenizeIdentifier()
case ISAMPLER2DMSARRAY: case ISAMPLER2DMSARRAY:
case USAMPLER2DMSARRAY: case USAMPLER2DMSARRAY:
afterType = true; afterType = true;
if ((_parseContext.profile == EEsProfile && _parseContext.version >= 320) || if ((_parseContext.profile == EEsProfile
_parseContext.extensionsTurnedOn(1, &E_GL_OES_texture_storage_multisample_2d_array)) && _parseContext.version >= 320)
|| _parseContext.extensionsTurnedOn(1,
&E_GL_OES_texture_storage_multisample_2d_array))
return keyword; return keyword;
return es30ReservedFromGLSL(150); return es30ReservedFromGLSL(150);
@ -1289,16 +1331,22 @@ int TScanContext::tokenizeIdentifier()
case SAMPLER3D: case SAMPLER3D:
afterType = true; afterType = true;
if (_parseContext.profile == EEsProfile && _parseContext.version < 300) { if (_parseContext.profile == EEsProfile
if (!_parseContext.extensionTurnedOn(E_GL_OES_texture_3D)) && _parseContext.version < 300)
{
if (!_parseContext.extensionTurnedOn(
E_GL_OES_texture_3D))
reservedWord(); reservedWord();
} }
return keyword; return keyword;
case SAMPLER2DSHADOW: case SAMPLER2DSHADOW:
afterType = true; afterType = true;
if (_parseContext.profile == EEsProfile && _parseContext.version < 300) { if (_parseContext.profile == EEsProfile
if (!_parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers)) && _parseContext.version < 300)
{
if (!_parseContext.extensionTurnedOn(
E_GL_EXT_shadow_samplers))
reservedWord(); reservedWord();
} }
return keyword; return keyword;
@ -1308,7 +1356,11 @@ int TScanContext::tokenizeIdentifier()
afterType = true; afterType = true;
if (_parseContext.profile == EEsProfile) if (_parseContext.profile == EEsProfile)
reservedWord(); reservedWord();
else if (_parseContext.version < 140 && ! _parseContext.symbolTable.atBuiltInLevel() && ! _parseContext.extensionTurnedOn(E_GL_ARB_texture_rectangle)) { else if (_parseContext.version < 140
&& ! _parseContext.symbolTable.atBuiltInLevel()
&& ! _parseContext.extensionTurnedOn(
E_GL_ARB_texture_rectangle))
{
if (_parseContext.relaxedErrors()) if (_parseContext.relaxedErrors())
_parseContext.requireExtensions(loc, 1, &E_GL_ARB_texture_rectangle, "texture-rectangle sampler keyword"); _parseContext.requireExtensions(loc, 1, &E_GL_ARB_texture_rectangle, "texture-rectangle sampler keyword");
else else
@ -1318,18 +1370,23 @@ int TScanContext::tokenizeIdentifier()
case SAMPLER1DARRAY: case SAMPLER1DARRAY:
afterType = true; afterType = true;
if (_parseContext.profile == EEsProfile && _parseContext.version == 300) if (_parseContext.profile == EEsProfile
&& _parseContext.version == 300)
reservedWord(); reservedWord();
else if ((_parseContext.profile == EEsProfile && _parseContext.version < 300) || else if ( (_parseContext.profile == EEsProfile
(_parseContext.profile != EEsProfile && _parseContext.version < 130)) && _parseContext.version < 300)
|| (_parseContext.profile != EEsProfile
&& _parseContext.version < 130))
return identifierOrType(); return identifierOrType();
return keyword; return keyword;
case SAMPLEREXTERNALOES: case SAMPLEREXTERNALOES:
afterType = true; afterType = true;
if (_parseContext.symbolTable.atBuiltInLevel() || if ( _parseContext.symbolTable.atBuiltInLevel()
_parseContext.extensionTurnedOn(E_GL_OES_EGL_image_external) || || _parseContext.extensionTurnedOn(
_parseContext.extensionTurnedOn(E_GL_OES_EGL_image_external_essl3)) E_GL_OES_EGL_image_external)
|| _parseContext.extensionTurnedOn(
E_GL_OES_EGL_image_external_essl3))
return keyword; return keyword;
return identifierOrType(); return identifierOrType();
@ -1370,7 +1427,6 @@ int TScanContext::tokenizeIdentifier()
case SAMPLERSHADOW: case SAMPLERSHADOW:
if (_parseContext.spvVersion.vulkan > 0) if (_parseContext.spvVersion.vulkan > 0)
return keyword; return keyword;
else
return identifierOrType(); return identifierOrType();
case SUBPASSINPUT: case SUBPASSINPUT:
@ -1381,7 +1437,6 @@ int TScanContext::tokenizeIdentifier()
case USUBPASSINPUTMS: case USUBPASSINPUTMS:
if (_parseContext.spvVersion.vulkan > 0) if (_parseContext.spvVersion.vulkan > 0)
return keyword; return keyword;
else
return identifierOrType(); return identifierOrType();
#ifdef AMD_EXTENSIONS #ifdef AMD_EXTENSIONS
@ -1431,39 +1486,49 @@ int TScanContext::tokenizeIdentifier()
case F16SUBPASSINPUT: case F16SUBPASSINPUT:
case F16SUBPASSINPUTMS: case F16SUBPASSINPUTMS:
afterType = true; afterType = true;
if (_parseContext.symbolTable.atBuiltInLevel() || if ( _parseContext.symbolTable.atBuiltInLevel()
(_parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch) && || (_parseContext.extensionTurnedOn(
_parseContext.profile != EEsProfile && _parseContext.version >= 450)) E_GL_AMD_gpu_shader_half_float_fetch)
&& _parseContext.profile != EEsProfile
&& _parseContext.version >= 450))
return keyword; return keyword;
return identifierOrType(); return identifierOrType();
#endif #endif
case NOPERSPECTIVE: case NOPERSPECTIVE:
#ifdef NV_EXTENSIONS #ifdef NV_EXTENSIONS
if (_parseContext.profile == EEsProfile && _parseContext.version >= 300 && if (_parseContext.profile == EEsProfile
_parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation)) && _parseContext.version >= 300
&& _parseContext.extensionTurnedOn(
E_GL_NV_shader_noperspective_interpolation))
return keyword; return keyword;
#endif #endif
return es30ReservedFromGLSL(130); return es30ReservedFromGLSL(130);
case SMOOTH: case SMOOTH:
if ((_parseContext.profile == EEsProfile && _parseContext.version < 300) || if ( (_parseContext.profile == EEsProfile
(_parseContext.profile != EEsProfile && _parseContext.version < 130)) && _parseContext.version < 300)
|| (_parseContext.profile != EEsProfile
&& _parseContext.version < 130))
return identifierOrType(); return identifierOrType();
return keyword; return keyword;
#ifdef AMD_EXTENSIONS #ifdef AMD_EXTENSIONS
case __EXPLICITINTERPAMD: case __EXPLICITINTERPAMD:
if (_parseContext.profile != EEsProfile && _parseContext.version >= 450 && if ( _parseContext.profile != EEsProfile
_parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter)) && _parseContext.version >= 450
&& _parseContext.extensionTurnedOn(
E_GL_AMD_shader_explicit_vertex_parameter))
return keyword; return keyword;
return identifierOrType(); return identifierOrType();
#endif #endif
case FLAT: case FLAT:
if (_parseContext.profile == EEsProfile && _parseContext.version < 300) if ( _parseContext.profile == EEsProfile
&& _parseContext.version < 300)
reservedWord(); reservedWord();
else if (_parseContext.profile != EEsProfile && _parseContext.version < 130) else if (_parseContext.profile != EEsProfile
&& _parseContext.version < 130)
return identifierOrType(); return identifierOrType();
return keyword; return keyword;
@ -1473,31 +1538,42 @@ int TScanContext::tokenizeIdentifier()
return keyword; return keyword;
case PRECISE: case PRECISE:
if ((_parseContext.profile == EEsProfile && if ( (_parseContext.profile == EEsProfile
(_parseContext.version >= 320 || _parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) || && (_parseContext.version >= 320
(_parseContext.profile != EEsProfile && _parseContext.version >= 400)) || _parseContext.extensionsTurnedOn(
Num_AEP_gpu_shader5, AEP_gpu_shader5)))
|| (_parseContext.profile != EEsProfile
&& _parseContext.version >= 400))
return keyword; return keyword;
if (_parseContext.profile == EEsProfile && _parseContext.version == 310) { if ( _parseContext.profile == EEsProfile
&& _parseContext.version == 310)
{
reservedWord(); reservedWord();
return keyword; return keyword;
} }
return identifierOrType(); return identifierOrType();
case INVARIANT: case INVARIANT:
if (_parseContext.profile != EEsProfile && _parseContext.version < 120) if ( _parseContext.profile != EEsProfile
&& _parseContext.version < 120)
return identifierOrType(); return identifierOrType();
return keyword; return keyword;
case PACKED: case PACKED:
if ((_parseContext.profile == EEsProfile && _parseContext.version < 300) || if ( (_parseContext.profile == EEsProfile
(_parseContext.profile != EEsProfile && _parseContext.version < 330)) && _parseContext.version < 300)
|| (_parseContext.profile != EEsProfile
&& _parseContext.version < 330))
return reservedWord(); return reservedWord();
return identifierOrType(); return identifierOrType();
case RESOURCE: case RESOURCE:
{ {
bool reserved = (_parseContext.profile == EEsProfile && _parseContext.version >= 300) || bool reserved =
(_parseContext.profile != EEsProfile && _parseContext.version >= 420); (_parseContext.profile == EEsProfile
&& _parseContext.version >= 300)
|| (_parseContext.profile != EEsProfile
&& _parseContext.version >= 420);
return identifierOrReserved(reserved); return identifierOrReserved(reserved);
} }
case SUPERP: case SUPERP:
@ -1508,27 +1584,32 @@ int TScanContext::tokenizeIdentifier()
default: default:
_parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc); _parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
return 0; break;
} }
return 0;
} }
int TScanContext::identifierOrType() int TScanContext::identifierOrType()
{ {
parserToken->sType.lex.string = NewPoolTString(tokenText); parserToken->sType.lex.string = NewPoolTString(tokenText);
if (field) if (!field)
return IDENTIFIER; {
parserToken->sType.lex.symbol = _parseContext.symbolTable.find(*parserToken->sType.lex.string); parserToken->sType.lex.symbol = _parseContext.symbolTable.find(*parserToken->sType.lex.string);
if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != NULL) { if ((afterType == false
if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) { && afterStruct == false)
if (variable->isUserType()) { && parserToken->sType.lex.symbol)
{
if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable())
{
if (variable->isUserType())
{
afterType = true; afterType = true;
return TYPE_NAME; return TYPE_NAME;
} }
} }
} }
}
return IDENTIFIER; return IDENTIFIER;
} }
@ -1545,9 +1626,9 @@ int TScanContext::reservedWord()
int TScanContext::identifierOrReserved(bool reserved) int TScanContext::identifierOrReserved(bool reserved)
{ {
if (reserved) { if (reserved)
{
reservedWord(); reservedWord();
return 0; return 0;
} }
@ -1564,13 +1645,20 @@ int TScanContext::es30ReservedFromGLSL(int version)
if (_parseContext.symbolTable.atBuiltInLevel()) if (_parseContext.symbolTable.atBuiltInLevel())
return keyword; return keyword;
if ((_parseContext.profile == EEsProfile && _parseContext.version < 300) || if ( (_parseContext.profile == EEsProfile
(_parseContext.profile != EEsProfile && _parseContext.version < version)) { && _parseContext.version < 300)
|| (_parseContext.profile != EEsProfile
&& _parseContext.version < version))
{
if (_parseContext.forwardCompatible) if (_parseContext.forwardCompatible)
_parseContext.warn(loc, "future reserved word in ES 300 and keyword in GLSL", tokenText, ""); _parseContext.warn(loc,
"future reserved word in ES 300 and keyword in GLSL",
tokenText, "");
return identifierOrType(); return identifierOrType();
} else if (_parseContext.profile == EEsProfile && _parseContext.version >= 300) }
else if (_parseContext.profile == EEsProfile
&& _parseContext.version >= 300)
reservedWord(); reservedWord();
return keyword; return keyword;
@ -1580,8 +1668,11 @@ int TScanContext::es30ReservedFromGLSL(int version)
// showed up, both in an es version and a non-ES version. // showed up, both in an es version and a non-ES version.
int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion) int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion)
{ {
if ((_parseContext.profile == EEsProfile && _parseContext.version < esVersion) || if ( ( _parseContext.profile == EEsProfile
(_parseContext.profile != EEsProfile && _parseContext.version < nonEsVersion)) { && _parseContext.version < esVersion)
|| (_parseContext.profile != EEsProfile
&& _parseContext.version < nonEsVersion))
{
if (_parseContext.forwardCompatible) if (_parseContext.forwardCompatible)
_parseContext.warn(loc, "using future keyword", tokenText, ""); _parseContext.warn(loc, "using future keyword", tokenText, "");
@ -1619,13 +1710,15 @@ int TScanContext::dMat()
{ {
afterType = true; afterType = true;
if (_parseContext.profile == EEsProfile && _parseContext.version >= 300) { if ( _parseContext.profile == EEsProfile
&& _parseContext.version >= 300)
{
reservedWord(); reservedWord();
return keyword; return keyword;
} }
if (_parseContext.profile != EEsProfile && _parseContext.version >= 400) if ( _parseContext.profile != EEsProfile
&& _parseContext.version >= 400)
return keyword; return keyword;
if (_parseContext.forwardCompatible) if (_parseContext.forwardCompatible)
@ -1636,16 +1729,19 @@ int TScanContext::dMat()
int TScanContext::firstGenerationImage(bool inEs310) int TScanContext::firstGenerationImage(bool inEs310)
{ {
if (_parseContext.symbolTable.atBuiltInLevel() || if ( _parseContext.symbolTable.atBuiltInLevel()
(_parseContext.profile != EEsProfile && (_parseContext.version >= 420 || || (_parseContext.profile != EEsProfile
_parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) || && (_parseContext.version >= 420
(inEs310 && _parseContext.profile == EEsProfile && _parseContext.version >= 310)) || _parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))
|| (inEs310 && _parseContext.profile == EEsProfile && _parseContext.version >= 310))
return keyword; return keyword;
if ((_parseContext.profile == EEsProfile && _parseContext.version >= 300) || if ( (_parseContext.profile == EEsProfile
(_parseContext.profile != EEsProfile && _parseContext.version >= 130)) { && _parseContext.version >= 300)
|| (_parseContext.profile != EEsProfile
&& _parseContext.version >= 130))
{
reservedWord(); reservedWord();
return keyword; return keyword;
} }
@ -1657,14 +1753,18 @@ int TScanContext::firstGenerationImage(bool inEs310)
int TScanContext::secondGenerationImage() int TScanContext::secondGenerationImage()
{ {
if (_parseContext.profile == EEsProfile && _parseContext.version >= 310) { if ( _parseContext.profile == EEsProfile
&& _parseContext.version >= 310)
{
reservedWord(); reservedWord();
return keyword; return keyword;
} }
if (_parseContext.symbolTable.atBuiltInLevel() || if ( _parseContext.symbolTable.atBuiltInLevel()
(_parseContext.profile != EEsProfile && || (_parseContext.profile != EEsProfile
(_parseContext.version >= 420 || _parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) && (_parseContext.version >= 420
|| _parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))
)
return keyword; return keyword;
if (_parseContext.forwardCompatible) if (_parseContext.forwardCompatible)

View File

@ -107,13 +107,13 @@ public:
// N.B. Sources can have a length of 0. // N.B. Sources can have a length of 0.
int sourceToRead = currentSource; int sourceToRead = currentSource;
size_t charToRead = currentChar; size_t charToRead = currentChar;
while(charToRead >= lengths[sourceToRead]) { while(charToRead >= lengths[sourceToRead])
{
charToRead = 0; charToRead = 0;
sourceToRead += 1; sourceToRead += 1;
if (sourceToRead >= numSources) { if (sourceToRead >= numSources)
return EndOfInput; return EndOfInput;
} }
}
// Here, we care about making negative valued characters positive // Here, we care about making negative valued characters positive
return sources[sourceToRead][charToRead]; return sources[sourceToRead][charToRead];
@ -130,15 +130,16 @@ public:
--currentChar; --currentChar;
--loc[currentSource].column; --loc[currentSource].column;
--logicalSourceLoc.column; --logicalSourceLoc.column;
if (loc[currentSource].column < 0) { if (loc[currentSource].column < 0)
{
// We've moved back past a new line. Find the // We've moved back past a new line. Find the
// previous newline (or start of the file) to compute // previous newline (or start of the file) to compute
// the column count on the now current line. // the column count on the now current line.
size_t chIndex = currentChar; size_t chIndex = currentChar;
while (chIndex > 0) { while (chIndex > 0)
if (sources[currentSource][chIndex] == '\n') { {
if (sources[currentSource][chIndex] == '\n')
break; break;
}
--chIndex; --chIndex;
} }
logicalSourceLoc.column = (int)(currentChar - chIndex); logicalSourceLoc.column = (int)(currentChar - chIndex);
@ -148,10 +149,10 @@ public:
do { do {
--currentSource; --currentSource;
} while (currentSource > 0 && lengths[currentSource] == 0); } while (currentSource > 0 && lengths[currentSource] == 0);
if (lengths[currentSource] == 0) { if (lengths[currentSource] == 0)
// set to 0 if we've backed up to the start of an empty string // set to 0 if we've backed up to the start of an empty string
currentChar = 0; currentChar = 0;
} else else
currentChar = lengths[currentSource] - 1; currentChar = lengths[currentSource] - 1;
} }
if (peek() == '\n') { if (peek() == '\n') {
@ -207,12 +208,10 @@ public:
const TSourceLoc& getSourceLoc() const const TSourceLoc& getSourceLoc() const
{ {
if (singleLogical) { if (singleLogical)
return logicalSourceLoc; return logicalSourceLoc;
} else {
return loc[std::max(0, std::min(currentSource, numSources - finale - 1))]; return loc[std::max(0, std::min(currentSource, numSources - finale - 1))];
} }
}
// Returns the index (starting from 0) of the most recent valid source string we are reading from. // Returns the index (starting from 0) of the most recent valid source string we are reading from.
int getLastValidSourceIndex() const { return std::min(currentSource, numSources - 1); } int getLastValidSourceIndex() const { return std::min(currentSource, numSources - 1); }

View File

@ -65,20 +65,23 @@ namespace { // anonymous namespace for file-local functions and symbols
// Total number of successful initializers of glslang: a refcount // Total number of successful initializers of glslang: a refcount
// Shared global; access should be protected by a global mutex/critical section. // Shared global; access should be protected by a global mutex/critical section.
int NumberOfClients = 0; static int NumberOfClients = 0;
using namespace glslang; using namespace glslang;
// Create a language specific version of parseables. // Create a language specific version of parseables.
TBuiltInParseables* CreateBuiltInParseables(TInfoSink& infoSink, EShSource source) TBuiltInParseables* CreateBuiltInParseables(
TInfoSink& infoSink, EShSource source)
{ {
switch (source) { switch (source)
case EShSourceGlsl: return new TBuiltIns(); // GLSL builtIns {
case EShSourceGlsl:
return new TBuiltIns(); // GLSL builtIns
default: default:
infoSink.info.message(EPrefixInternalError, "Unable to determine source language"); infoSink.info.message(EPrefixInternalError, "Unable to determine source language");
return NULL; break;
} }
return NULL;
} }
// Create a language specific version of a parse context. // Create a language specific version of a parse context.
@ -1233,7 +1236,7 @@ void ShDestruct(ShHandle handle)
// //
// Cleanup symbol tables // Cleanup symbol tables
// //
int __fastcall ShFinalize() int __fastcall ShFinalize(void)
{ {
glslang::GetGlobalLock(); glslang::GetGlobalLock();
--NumberOfClients; --NumberOfClients;
@ -1316,15 +1319,15 @@ int ShCompile(
TIntermediate intermediate(compiler->getLanguage()); TIntermediate intermediate(compiler->getLanguage());
TShader::ForbidIncluder includer; TShader::ForbidIncluder includer;
bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, NULL, bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, NULL, "", optLevel, resources, defaultVersion, ENoProfile, false,
"", optLevel, resources, defaultVersion, ENoProfile, false,
forwardCompatible, messages, intermediate, includer); forwardCompatible, messages, intermediate, includer);
//
// Call the machine dependent compiler // Call the machine dependent compiler
// if ( success
if (success && intermediate.getTreeRoot() && optLevel != EShOptNoGeneration) && intermediate.getTreeRoot()
success = compiler->compile(intermediate.getTreeRoot(), intermediate.getVersion(), intermediate.getProfile()); && optLevel != EShOptNoGeneration)
success = compiler->compile(intermediate.getTreeRoot(),
intermediate.getVersion(), intermediate.getProfile());
intermediate.removeTree(); intermediate.removeTree();
@ -1351,13 +1354,13 @@ int ShLinkExt(
THandleList cObjects; THandleList cObjects;
for (int i = 0; i < numHandles; ++i) { for (int i = 0; i < numHandles; ++i)
{
if (compHandles[i] == 0) if (compHandles[i] == 0)
return 0; return 0;
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(compHandles[i]); TShHandleBase* base = reinterpret_cast<TShHandleBase*>(compHandles[i]);
if (base->getAsLinker()) { if (base->getAsLinker())
cObjects.push_back(base->getAsLinker()); cObjects.push_back(base->getAsLinker());
}
if (base->getAsCompiler()) if (base->getAsCompiler())
cObjects.push_back(base->getAsCompiler()); cObjects.push_back(base->getAsCompiler());
@ -1375,33 +1378,28 @@ int ShLinkExt(
linker->infoSink.info.erase(); linker->infoSink.info.erase();
for (int i = 0; i < numHandles; ++i) { for (int i = 0; i < numHandles; ++i)
if (cObjects[i]->getAsCompiler()) { {
if (! cObjects[i]->getAsCompiler()->linkable()) { if (cObjects[i]->getAsCompiler())
{
if (! cObjects[i]->getAsCompiler()->linkable())
{
linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code."); linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code.");
return 0; return 0;
} }
} }
} }
bool ret = linker->link(cObjects); return linker->link(cObjects) ? 1 : 0;
return ret ? 1 : 0;
} }
// //
// ShSetEncrpytionMethod is a place-holder for specifying // ShSetEncrpytionMethod is a place-holder for specifying
// how source code is encrypted. // how source code is encrypted.
// //
void ShSetEncryptionMethod(ShHandle handle) void ShSetEncryptionMethod(ShHandle handle) { }
{
if (handle == 0)
return;
}
//
// Return any compiler/linker/uniformmap log of messages for the application. // Return any compiler/linker/uniformmap log of messages for the application.
//
const char* ShGetInfoLog(const ShHandle handle) const char* ShGetInfoLog(const ShHandle handle)
{ {
if (handle == 0) if (handle == 0)
@ -1536,30 +1534,19 @@ namespace glslang {
#define QUOTE(s) #s #define QUOTE(s) #s
#define STR(n) QUOTE(n) #define STR(n) QUOTE(n)
const char* GetEsslVersionString() const char* GetEsslVersionString(void)
{ {
return "OpenGL ES GLSL 3.20 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL); return "OpenGL ES GLSL 3.20 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL);
} }
const char* GetGlslVersionString() const char* GetGlslVersionString(void)
{ {
return "4.60 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL); return "4.60 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL);
} }
int GetKhronosToolId() int GetKhronosToolId(void) { return 8; }
{ bool InitializeProcess(void) { return ShInitialize() != 0; }
return 8; void FinalizeProcess(void) { ShFinalize(); }
}
bool InitializeProcess()
{
return ShInitialize() != 0;
}
void FinalizeProcess()
{
ShFinalize();
}
class TDeferredCompiler : public TCompiler { class TDeferredCompiler : public TCompiler {
public: public:
@ -1598,7 +1585,8 @@ void TShader::setStrings(const char* const* s, int n)
lengths = NULL; lengths = NULL;
} }
void TShader::setStringsWithLengths(const char* const* s, const int* l, int n) void TShader::setStringsWithLengths(
const char* const* s, const int* l, int n)
{ {
strings = s; strings = s;
numStrings = n; numStrings = n;
@ -1671,7 +1659,9 @@ void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode
// //
// Returns true for success. // Returns true for success.
// //
bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, bool TShader::parse(const TBuiltInResource* builtInResources,
int defaultVersion, EProfile defaultProfile,
bool forceDefaultVersionAndProfile,
bool forwardCompatible, EShMessages messages, Includer& includer) bool forwardCompatible, EShMessages messages, Includer& includer)
{ {
if (! InitThread()) if (! InitThread())
@ -1704,18 +1694,20 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
if (! preamble) if (! preamble)
preamble = ""; preamble = "";
return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble, return PreprocessDeferred(
compiler, strings, numStrings, lengths, stringNames, preamble,
EShOptNone, builtInResources, defaultVersion, EShOptNone, builtInResources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile, defaultProfile, forceDefaultVersionAndProfile,
forwardCompatible, message, includer, *intermediate, output_string); forwardCompatible, message, includer,
*intermediate, output_string);
} }
const char* TShader::getInfoLog() const char* TShader::getInfoLog(void)
{ {
return infoSink->info.c_str(); return infoSink->info.c_str();
} }
const char* TShader::getInfoDebugLog() const char* TShader::getInfoDebugLog(void)
{ {
return infoSink->debug.c_str(); return infoSink->debug.c_str();
} }
@ -1724,7 +1716,8 @@ TProgram::TProgram() : reflection(0), ioMapper(NULL), linked(false)
{ {
pool = new TPoolAllocator; pool = new TPoolAllocator;
infoSink = new TInfoSink; infoSink = new TInfoSink;
for (int s = 0; s < EShLangCount; ++s) { for (int s = 0; s < EShLangCount; ++s)
{
intermediate[s] = 0; intermediate[s] = 0;
newedIntermediate[s] = false; newedIntermediate[s] = false;
} }
@ -1788,28 +1781,32 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
numNonEsShaders++; numNonEsShaders++;
} }
if (numEsShaders > 0 && numNonEsShaders > 0) { if (numEsShaders > 0 && numNonEsShaders > 0)
{
infoSink->info.message(EPrefixError, "Cannot mix ES profile with non-ES profile shaders"); infoSink->info.message(EPrefixError, "Cannot mix ES profile with non-ES profile shaders");
return false; return false;
} else if (numEsShaders > 1) { }
if (numEsShaders > 1)
{
infoSink->info.message(EPrefixError, "Cannot attach multiple ES shaders of the same type to a single program"); infoSink->info.message(EPrefixError, "Cannot attach multiple ES shaders of the same type to a single program");
return false; return false;
} }
//
// Be efficient for the common single compilation unit per stage case, // Be efficient for the common single compilation unit per stage case,
// reusing it's TIntermediate instead of merging into a new one. // reusing it's TIntermediate instead of merging into a new one.
//
TIntermediate *firstIntermediate = stages[stage].front()->intermediate; TIntermediate *firstIntermediate = stages[stage].front()->intermediate;
if (stages[stage].size() == 1) if (stages[stage].size() == 1)
intermediate[stage] = firstIntermediate; intermediate[stage] = firstIntermediate;
else { else
{
intermediate[stage] = new TIntermediate(stage, intermediate[stage] = new TIntermediate(stage,
firstIntermediate->getVersion(), firstIntermediate->getVersion(),
firstIntermediate->getProfile()); firstIntermediate->getProfile());
// The new TIntermediate must use the same origin as the original TIntermediates. // The new TIntermediate must use the same
// origin as the original TIntermediates.
// Otherwise linking will fail due to different coordinate systems. // Otherwise linking will fail due to different coordinate systems.
if (firstIntermediate->getOriginUpperLeft()) if (firstIntermediate->getOriginUpperLeft())
intermediate[stage]->setOriginUpperLeft(); intermediate[stage]->setOriginUpperLeft();
@ -1856,8 +1853,10 @@ bool TProgram::buildReflection(void)
reflection = new TReflection; reflection = new TReflection;
for (int s = 0; s < EShLangCount; ++s) { for (int s = 0; s < EShLangCount; ++s)
if (intermediate[s]) { {
if (intermediate[s])
{
if (! reflection->addStage((EShLanguage)s, *intermediate[s])) if (! reflection->addStage((EShLanguage)s, *intermediate[s]))
return false; return false;
} }
@ -1895,8 +1894,10 @@ bool TProgram::mapIO(TIoMapResolver* resolver)
ioMapper = new TIoMapper; ioMapper = new TIoMapper;
for (int s = 0; s < EShLangCount; ++s) { for (int s = 0; s < EShLangCount; ++s)
if (intermediate[s]) { {
if (intermediate[s])
{
if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, resolver)) if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, resolver))
return false; return false;
} }

View File

@ -173,9 +173,8 @@ void TType::buildMangledName(TString& mangledName) const
void TVariable::dump(TInfoSink& infoSink) const void TVariable::dump(TInfoSink& infoSink) const
{ {
infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " << type.getBasicTypeString(); infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " << type.getBasicTypeString();
if (type.isArray()) { if (type.isArray())
infoSink.debug << "[0]"; infoSink.debug << "[0]";
}
infoSink.debug << "\n"; infoSink.debug << "\n";
} }
@ -299,15 +298,13 @@ TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf)
TVariable* TVariable::clone() const TVariable* TVariable::clone() const
{ {
TVariable *variable = new TVariable(*this); return new TVariable(*this);
return variable;
} }
TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf) TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
{ {
for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) { for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
TParameter param; TParameter param = {};
parameters.push_back(param); parameters.push_back(param);
parameters.back().copyParam(copyOf.parameters[i]); parameters.back().copyParam(copyOf.parameters[i]);
} }

View File

@ -129,10 +129,8 @@ protected:
int numExtensions; int numExtensions;
const char** extensions; // an array of pointers to existing constant char strings const char** extensions; // an array of pointers to existing constant char strings
//
// N.B.: Non-const functions that will be generally used should assert on this, // N.B.: Non-const functions that will be generally used should assert on this,
// to avoid overwriting shared symbol-table information. // to avoid overwriting shared symbol-table information.
//
bool writable; bool writable;
}; };
@ -400,7 +398,6 @@ public:
// Only supporting amend of anonymous blocks so far. // Only supporting amend of anonymous blocks so far.
if (IsAnonymous(symbol.getName())) if (IsAnonymous(symbol.getName()))
return insertAnonymousMembers(symbol, firstNewMember); return insertAnonymousMembers(symbol, firstNewMember);
else
return false; return false;
} }
@ -421,7 +418,6 @@ public:
tLevel::const_iterator it = level.find(name); tLevel::const_iterator it = level.find(name);
if (it == level.end()) if (it == level.end())
return 0; return 0;
else
return (*it).second; return (*it).second;
} }
@ -533,12 +529,8 @@ protected:
class TSymbolTable { class TSymbolTable {
public: public:
TSymbolTable() : uniqueId(0), noBuiltInRedeclarations(false), separateNameSpaces(false), adoptedLevels(0)
{
//
// This symbol table cannot be used until push() is called. // This symbol table cannot be used until push() is called.
// TSymbolTable() : uniqueId(0), noBuiltInRedeclarations(false), separateNameSpaces(false), adoptedLevels(0) { }
}
~TSymbolTable() ~TSymbolTable()
{ {
// this can be called explicitly; safest to code it so it can be called multiple times // this can be called explicitly; safest to code it so it can be called multiple times
@ -677,11 +669,9 @@ public:
table[globalLevel]->insert(*copy, separateNameSpaces); table[globalLevel]->insert(*copy, separateNameSpaces);
if (shared->getAsVariable()) if (shared->getAsVariable())
return copy; return copy;
else {
// return the copy of the anonymous member // return the copy of the anonymous member
return table[globalLevel]->find(shared->getName()); return table[globalLevel]->find(shared->getName());
} }
}
// Normal find of a symbol, that can optionally say whether the symbol was found // Normal find of a symbol, that can optionally say whether the symbol was found
// at a built-in level or the current top-scope level. // at a built-in level or the current top-scope level.

View File

@ -253,27 +253,26 @@ struct TResolverUniformAdaptor
ent.newBinding = -1; ent.newBinding = -1;
ent.newSet = -1; ent.newSet = -1;
ent.newIndex = -1; ent.newIndex = -1;
const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
ent.live);
if (isValid) { if (isValid)
ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), {
ent.live); ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
ent.newSet = resolver.resolveSet(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live); ent.newSet = resolver.resolveSet(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
ent.newLocation = resolver.resolveUniformLocation(stage, ent.symbol->getName().c_str(), ent.newLocation = resolver.resolveUniformLocation(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
ent.symbol->getType(), ent.live);
if (ent.newBinding != -1) { if (ent.newBinding != -1) {
if (ent.newBinding >= int(TQualifier::layoutBindingEnd)) { if (ent.newBinding >= int(TQualifier::layoutBindingEnd)) {
TString err = "mapped binding out of range: " + ent.symbol->getName(); TString err = "mapped binding out of range: "
+ ent.symbol->getName();
infoSink.info.message(EPrefixInternalError, err.c_str()); infoSink.info.message(EPrefixInternalError, err.c_str());
error = true; error = true;
} }
} }
if (ent.newSet != -1) { if (ent.newSet != -1) {
if (ent.newSet >= int(TQualifier::layoutSetEnd)) { if (ent.newSet >= int(TQualifier::layoutSetEnd)) {
TString err = "mapped set out of range: " + ent.symbol->getName(); TString err = "mapped set out of range: "
+ ent.symbol->getName();
infoSink.info.message(EPrefixInternalError, err.c_str()); infoSink.info.message(EPrefixInternalError, err.c_str());
error = true; error = true;
} }
@ -330,7 +329,9 @@ struct TResolverInOutAdaptor
ent.symbol->getName().c_str(), ent.symbol->getName().c_str(),
ent.symbol->getType(), ent.symbol->getType(),
ent.live); ent.live);
} else { }
else
{
TString errorMsg = "Invalid shader In/Out variable semantic: "; TString errorMsg = "Invalid shader In/Out variable semantic: ";
errorMsg += ent.symbol->getType().getQualifier().semanticName; errorMsg += ent.symbol->getType().getQualifier().semanticName;
infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
@ -359,37 +360,33 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
{ } { }
int getBaseBinding(TResourceType res, unsigned int set) const { int getBaseBinding(TResourceType res, unsigned int set) const {
return selectBaseBinding(intermediate.getShiftBinding(res), // Return descriptor set specific base if
intermediate.getShiftBindingForSet(res, set)); // there is one, and the generic base otherwise.
int base = intermediate.getShiftBinding(res);
int descriptorSetBase = intermediate.getShiftBindingForSet(res, set);
return descriptorSetBase != -1 ? descriptorSetBase : base;
} }
const std::vector<std::string>& getResourceSetBinding() const { return intermediate.getResourceSetBinding(); } const std::vector<std::string>& getResourceSetBinding() const { return intermediate.getResourceSetBinding(); }
bool doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }
bool doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); }
typedef std::vector<int> TSlotSet; typedef std::vector<int> TSlotSet;
typedef std::unordered_map<int, TSlotSet> TSlotSetMap; typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
TSlotSetMap slots; TSlotSetMap slots;
TSlotSet::iterator findSlot(int set, int slot)
{
return std::lower_bound(slots[set].begin(), slots[set].end(), slot);
}
bool checkEmpty(int set, int slot) bool checkEmpty(int set, int slot)
{ {
TSlotSet::iterator at = findSlot(set, slot); TSlotSet::iterator at = std::lower_bound(slots[set].begin(), slots[set].end(), slot);
return !(at != slots[set].end() && *at == slot); return !(at != slots[set].end() && *at == slot);
} }
int reserveSlot(int set, int slot, int size = 1) int reserveSlot(int set, int slot, int size = 1)
{ {
TSlotSet::iterator at = findSlot(set, slot); TSlotSet::iterator at = std::lower_bound(slots[set].begin(), slots[set].end(), slot);
// tolerate aliasing, by not double-recording aliases // tolerate aliasing, by not double-recording aliases
// (policy about appropriateness of the alias is higher up) // (policy about appropriateness of the alias is higher up)
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++)
{
if (at == slots[set].end() || *at != slot + i) if (at == slots[set].end() || *at != slot + i)
at = slots[set].insert(at, slot + i); at = slots[set].insert(at, slot + i);
++at; ++at;
@ -400,12 +397,13 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
int getFreeSlot(int set, int base, int size = 1) int getFreeSlot(int set, int base, int size = 1)
{ {
TSlotSet::iterator at = findSlot(set, base); TSlotSet::iterator at = std::lower_bound(slots[set].begin(), slots[set].end(), base);
if (at == slots[set].end()) if (at == slots[set].end())
return reserveSlot(set, base, size); return reserveSlot(set, base, size);
// look for a big enough gap // look for a big enough gap
for (; at != slots[set].end(); ++at) { for (; at != slots[set].end(); ++at)
{
if (*at - base >= size) if (*at - base >= size)
break; break;
base = *at + 1; base = *at + 1;
@ -417,7 +415,7 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
virtual int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override = 0; virtual int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override = 0;
int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override int resolveSet(EShLanguage stage, const char* name, const glslang::TType& type, bool is_live) override
{ {
if (type.getQualifier().hasSet()) if (type.getQualifier().hasSet())
return type.getQualifier().layoutSet; return type.getQualifier().layoutSet;
@ -428,21 +426,24 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
return 0; return 0;
} }
int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override int resolveUniformLocation(EShLanguage stage, const char* name, const glslang::TType& type, bool is_live) override
{ {
// kick out of not doing this // kick out of not doing this
if (!doAutoLocationMapping()) if (!intermediate.getAutoMapLocations())
return -1; return -1;
// no locations added if already present, a built-in variable, a block, or an opaque // no locations added if already present,
if (type.getQualifier().hasLocation() || type.isBuiltIn() || // a built-in variable, a block, or an opaque
type.getBasicType() == EbtBlock || if ( type.getQualifier().hasLocation()
type.getBasicType() == EbtAtomicUint || || type.isBuiltIn()
(type.containsOpaque() && intermediate.getSpv().openGl == 0)) || type.getBasicType() == EbtBlock
|| type.getBasicType() == EbtAtomicUint
|| (type.containsOpaque() && intermediate.getSpv().openGl == 0))
return -1; return -1;
// no locations on blocks of built-in variables // no locations on blocks of built-in variables
if (type.isStruct()) { if (type.isStruct())
{
if (type.getStruct()->size() < 1) if (type.getStruct()->size() < 1)
return -1; return -1;
if ((*type.getStruct())[0].type->isBuiltIn()) if ((*type.getStruct())[0].type->isBuiltIn())
@ -455,14 +456,16 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
return location; return location;
} }
bool validateInOut(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) override
{ {
return true; return true;
} }
int resolveInOutLocation(EShLanguage stage, const char* /*name*/, const TType& type, bool /*is_live*/) override
int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) override
{ {
// kick out of not doing this // kick out of not doing this
if (!doAutoLocationMapping()) if (!intermediate.getAutoMapLocations())
return -1; return -1;
// no locations added if already present, or a built-in variable // no locations added if already present, or a built-in variable
@ -470,7 +473,8 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
return -1; return -1;
// no locations on blocks of built-in variables // no locations on blocks of built-in variables
if (type.isStruct()) { if (type.isStruct())
{
if (type.getStruct()->size() < 1) if (type.getStruct()->size() < 1)
return -1; return -1;
if ((*type.getStruct())[0].type->isBuiltIn()) if ((*type.getStruct())[0].type->isBuiltIn())
@ -486,27 +490,30 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
int typeLocationSize; int typeLocationSize;
// Dont take into account the outer-most array if the stages // Dont take into account the outer-most array if the stages
// interface is automatically an array. // interface is automatically an array.
if (type.getQualifier().isArrayedIo(stage)) { if (type.getQualifier().isArrayedIo(stage))
{
TType elementType(type, 0); TType elementType(type, 0);
typeLocationSize = TIntermediate::computeTypeLocationSize(elementType, stage); typeLocationSize = TIntermediate::computeTypeLocationSize(elementType, stage);
} else {
typeLocationSize = TIntermediate::computeTypeLocationSize(type, stage);
} }
else
typeLocationSize = TIntermediate::computeTypeLocationSize(type, stage);
nextLocation += typeLocationSize; nextLocation += typeLocationSize;
return location; return location;
} }
int resolveInOutComponent(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
{ int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) override
return -1;
}
int resolveInOutIndex(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
{ {
return -1; return -1;
} }
void notifyBinding(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {} int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) override
void notifyInOut(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {} {
return -1;
}
void notifyBinding(EShLanguage, const char* name, const TType&, bool is_live) override {}
void notifyInOut(EShLanguage, const char* name, const TType&, bool is_live) override {}
void endNotifications(EShLanguage) override {} void endNotifications(EShLanguage) override {}
void beginNotifications(EShLanguage) override {} void beginNotifications(EShLanguage) override {}
void beginResolve(EShLanguage) override {} void beginResolve(EShLanguage) override {}
@ -518,30 +525,10 @@ protected:
int nextInputLocation; int nextInputLocation;
int nextOutputLocation; int nextOutputLocation;
// Return descriptor set specific base if there is one, and the generic base otherwise.
int selectBaseBinding(int base, int descriptorSetBase) const {
return descriptorSetBase != -1 ? descriptorSetBase : base;
}
static int getLayoutSet(const glslang::TType& type) {
if (type.getQualifier().hasSet())
return type.getQualifier().layoutSet;
else
return 0;
}
static bool isSamplerType(const glslang::TType& type) {
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler();
}
static bool isTextureType(const glslang::TType& type) { static bool isTextureType(const glslang::TType& type) {
return (type.getBasicType() == glslang::EbtSampler && return (type.getBasicType() == glslang::EbtSampler &&
(type.getSampler().isTexture() || type.getSampler().isSubpass())); (type.getSampler().isTexture() || type.getSampler().isSubpass()));
} }
static bool isUboType(const glslang::TType& type) {
return type.getQualifier().storage == EvqUniform;
}
}; };
/* /*
@ -558,63 +545,57 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
{ {
TDefaultIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { } TDefaultIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { }
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override bool validateBinding(EShLanguage stage, const char* name, const glslang::TType& type, bool is_live) override
{ {
return true; return true;
} }
int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override int resolveBinding(EShLanguage stage, const char* name, const glslang::TType& type, bool is_live) override
{ {
const int set = getLayoutSet(type); const int set = (type.getQualifier().hasSet()) ? type.getQualifier().layoutSet : 0;
// On OpenGL arrays of opaque types take a seperate binding for each element // On OpenGL arrays of opaque types take a seperate binding for each element
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1; int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
if (type.getQualifier().hasBinding()) { if (type.getQualifier().hasBinding())
if (isImageType(type)) {
if (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage())
return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding, numBindings); return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding, numBindings);
if (isTextureType(type)) if (isTextureType(type))
return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding, numBindings); return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding, numBindings);
if (isSsboType(type)) if (type.getQualifier().storage == EvqBuffer)
return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding, numBindings); return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding, numBindings);
if (isSamplerType(type)) if (type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler())
return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding, numBindings); return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding, numBindings);
if (isUboType(type)) if (type.getQualifier().storage == EvqUniform)
return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding, numBindings); return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding, numBindings);
} else if (is_live && doAutoBindingMapping()) { }
else if (is_live && intermediate.getAutoMapBindings())
{
// find free slot, the caller did make sure it passes all vars with binding // find free slot, the caller did make sure it passes all vars with binding
// first and now all are passed that do not have a binding and needs one // first and now all are passed that do not have a binding and needs one
if (isImageType(type)) if (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage())
return getFreeSlot(set, getBaseBinding(EResImage, set), numBindings); return getFreeSlot(set, getBaseBinding(EResImage, set), numBindings);
if (isTextureType(type)) if (isTextureType(type))
return getFreeSlot(set, getBaseBinding(EResTexture, set), numBindings); return getFreeSlot(set, getBaseBinding(EResTexture, set), numBindings);
if (isSsboType(type)) if (type.getQualifier().storage == EvqBuffer)
return getFreeSlot(set, getBaseBinding(EResSsbo, set), numBindings); return getFreeSlot(set, getBaseBinding(EResSsbo, set), numBindings);
if (isSamplerType(type)) if (type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler())
return getFreeSlot(set, getBaseBinding(EResSampler, set), numBindings); return getFreeSlot(set, getBaseBinding(EResSampler, set), numBindings);
if (isUboType(type)) if (type.getQualifier().storage == EvqUniform)
return getFreeSlot(set, getBaseBinding(EResUbo, set), numBindings); return getFreeSlot(set, getBaseBinding(EResUbo, set), numBindings);
} }
return -1; return -1;
} }
protected:
static bool isImageType(const glslang::TType& type) {
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage();
}
static bool isSsboType(const glslang::TType& type) {
return type.getQualifier().storage == EvqBuffer;
}
}; };
/******************************************************************************** /********************************************************************************
@ -671,34 +652,37 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
{ {
const int set = getLayoutSet(type); const int set = (type.getQualifier().hasSet()) ? type.getQualifier().layoutSet : 0;
if (type.getQualifier().hasBinding()) { if (type.getQualifier().hasBinding())
{
if (isUavType(type)) if (isUavType(type))
return reserveSlot(set, getBaseBinding(EResUav, set) + type.getQualifier().layoutBinding); return reserveSlot(set, getBaseBinding(EResUav, set) + type.getQualifier().layoutBinding);
if (isSrvType(type)) if (isTextureType(type) || type.getQualifier().storage == EvqBuffer)
return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding); return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding);
if (isSamplerType(type)) if (type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler())
return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding); return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding);
if (isUboType(type)) if (type.getQualifier().storage == EvqUniform)
return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding); return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding);
} else if (is_live && doAutoBindingMapping()) { }
else if (is_live && intermediate.getAutoMapBindings())
{
// find free slot, the caller did make sure it passes all vars with binding // find free slot, the caller did make sure it passes all vars with binding
// first and now all are passed that do not have a binding and needs one // first and now all are passed that do not have a binding and needs one
if (isUavType(type)) if (isUavType(type))
return getFreeSlot(set, getBaseBinding(EResUav, set)); return getFreeSlot(set, getBaseBinding(EResUav, set));
if (isSrvType(type)) if (isTextureType(type) || type.getQualifier().storage == EvqBuffer)
return getFreeSlot(set, getBaseBinding(EResTexture, set)); return getFreeSlot(set, getBaseBinding(EResTexture, set));
if (isSamplerType(type)) if (type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler())
return getFreeSlot(set, getBaseBinding(EResSampler, set)); return getFreeSlot(set, getBaseBinding(EResSampler, set));
if (isUboType(type)) if (type.getQualifier().storage == EvqUniform)
return getFreeSlot(set, getBaseBinding(EResUbo, set)); return getFreeSlot(set, getBaseBinding(EResUbo, set));
} }
@ -706,18 +690,13 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
} }
protected: protected:
// Return true if this is a SRV (shader resource view) type:
static bool isSrvType(const glslang::TType& type) {
return isTextureType(type) || type.getQualifier().storage == EvqBuffer;
}
// Return true if this is a UAV (unordered access view) type: // Return true if this is a UAV (unordered access view) type:
static bool isUavType(const glslang::TType& type) { static bool isUavType(const glslang::TType& type) {
if (type.getQualifier().readonly) if (type.getQualifier().readonly)
return false; return false;
return ( type.getBasicType() == glslang::EbtSampler
return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) || && type.getSampler().isImage())
(type.getQualifier().storage == EvqBuffer); || (type.getQualifier().storage == EvqBuffer);
} }
}; };
@ -728,14 +707,16 @@ protected:
// Returns false if the input is too malformed to do this. // Returns false if the input is too malformed to do this.
bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSink &infoSink, TIoMapResolver *resolver) bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSink &infoSink, TIoMapResolver *resolver)
{ {
bool somethingToDo = !intermediate.getResourceSetBinding().empty() || bool somethingToDo =
intermediate.getAutoMapBindings() || !intermediate.getResourceSetBinding().empty()
intermediate.getAutoMapLocations(); || intermediate.getAutoMapBindings()
|| intermediate.getAutoMapLocations();
for (int res = 0; res < EResCount; ++res) { for (int res = 0; res < EResCount; ++res)
somethingToDo = somethingToDo || {
(intermediate.getShiftBinding(TResourceType(res)) != 0) || somethingToDo = somethingToDo
intermediate.hasShiftBindingForSet(TResourceType(res)); || (intermediate.getShiftBinding(TResourceType(res)) != 0)
|| intermediate.hasShiftBindingForSet(TResourceType(res));
} }
if (!somethingToDo && resolver == NULL) if (!somethingToDo && resolver == NULL)

View File

@ -267,7 +267,7 @@ public:
shiftBinding[res] = shift; shiftBinding[res] = shift;
const char* name = getResourceName(res); const char* name = getResourceName(res);
if (name != NULL) if (name)
processes.addIfNonZero(name, shift); processes.addIfNonZero(name, shift);
} }

View File

@ -104,10 +104,9 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
_parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", ""); _parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", "");
return token; return token;
} }
if (ppToken->loc.string >= 0) {
// We are in user code; check for reserved name use: // We are in user code; check for reserved name use:
if (ppToken->loc.string >= 0)
_parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#define"); _parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#define");
}
// save the macro name // save the macro name
const int defAtom = atomStrings.getAddAtom(ppToken->name); const int defAtom = atomStrings.getAddAtom(ppToken->name);
@ -120,18 +119,22 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
token = scanToken(ppToken); token = scanToken(ppToken);
if (mac.args.size() == 0 && token == ')') if (mac.args.size() == 0 && token == ')')
break; break;
if (token != PpAtomIdentifier) { if (token != PpAtomIdentifier)
{
_parseContext.ppError(ppToken->loc, "bad argument", "#define", ""); _parseContext.ppError(ppToken->loc, "bad argument", "#define", "");
return token; return token;
} }
mac.emptyArgs = 0; mac.emptyArgs = 0;
const int argAtom = atomStrings.getAddAtom(ppToken->name); const int argAtom = atomStrings.getAddAtom(ppToken->name);
// check for duplication of parameter name // check for duplication of parameter name
bool duplicate = false; bool duplicate = false;
for (size_t a = 0; a < mac.args.size(); ++a) { for (size_t a = 0; a < mac.args.size(); ++a)
if (mac.args[a] == argAtom) { {
if (mac.args[a] == argAtom)
{
_parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", ""); _parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", "");
duplicate = true; duplicate = true;
break; break;
@ -141,7 +144,9 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
mac.args.push_back(argAtom); mac.args.push_back(argAtom);
token = scanToken(ppToken); token = scanToken(ppToken);
} while (token == ','); } while (token == ',');
if (token != ')') {
if (token != ')')
{
_parseContext.ppError(ppToken->loc, "missing parenthesis", "#define", ""); _parseContext.ppError(ppToken->loc, "missing parenthesis", "#define", "");
return token; return token;
@ -152,7 +157,8 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
// record the definition of the macro // record the definition of the macro
TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors
while (token != '\n' && token != EndOfInput) { while (token != '\n' && token != EndOfInput)
{
mac.body.putToken(token, ppToken); mac.body.putToken(token, ppToken);
token = scanToken(ppToken); token = scanToken(ppToken);
if (token != '\n' && ppToken->space) if (token != '\n' && ppToken->space)
@ -161,14 +167,17 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
// check for duplicate definition // check for duplicate definition
MacroSymbol* existing = lookupMacroDef(defAtom); MacroSymbol* existing = lookupMacroDef(defAtom);
if (existing != NULL) { if (existing != NULL)
if (! existing->undef) { {
if (! existing->undef)
{
// Already defined -- need to make sure they are identical: // Already defined -- need to make sure they are identical:
// "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, // "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
// ordering, spelling, and white-space separation, where all white-space separations are considered identical." // ordering, spelling, and white-space separation, where all white-space separations are considered identical."
if (existing->args.size() != mac.args.size() || existing->emptyArgs != mac.emptyArgs) if (existing->args.size() != mac.args.size() || existing->emptyArgs != mac.emptyArgs)
_parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom)); _parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
else { else
{
if (existing->args != mac.args) if (existing->args != mac.args)
_parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom)); _parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom));
existing->body.reset(); existing->body.reset();
@ -180,7 +189,8 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
TPpToken newPpToken; TPpToken newPpToken;
oldToken = existing->body.getToken(_parseContext, &oldPpToken); oldToken = existing->body.getToken(_parseContext, &oldPpToken);
newToken = mac.body.getToken(_parseContext, &newPpToken); newToken = mac.body.getToken(_parseContext, &newPpToken);
if (oldToken != newToken || oldPpToken != newPpToken) { if (oldToken != newToken || oldPpToken != newPpToken)
{
_parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom)); _parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom));
break; break;
} }
@ -198,7 +208,8 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
int TPpContext::CPPundef(TPpToken* ppToken) int TPpContext::CPPundef(TPpToken* ppToken)
{ {
int token = scanToken(ppToken); int token = scanToken(ppToken);
if (token != PpAtomIdentifier) { if (token != PpAtomIdentifier)
{
_parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", ""); _parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", "");
return token; return token;
@ -207,7 +218,7 @@ int TPpContext::CPPundef(TPpToken* ppToken)
_parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#undef"); _parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#undef");
MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name)); MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
if (macro != NULL) if (macro)
macro->undef = 1; macro->undef = 1;
token = scanToken(ppToken); token = scanToken(ppToken);
if (token != '\n') if (token != '\n')
@ -226,8 +237,10 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
int depth = 0; int depth = 0;
int token = scanToken(ppToken); int token = scanToken(ppToken);
while (token != EndOfInput) { while (token != EndOfInput)
if (token != '#') { {
if (token != '#')
{
while (token != '\n' && token != EndOfInput) while (token != '\n' && token != EndOfInput)
token = scanToken(ppToken); token = scanToken(ppToken);
@ -242,20 +255,25 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
continue; continue;
int nextAtom = atomStrings.getAtom(ppToken->name); int nextAtom = atomStrings.getAtom(ppToken->name);
if (nextAtom == PpAtomIf || nextAtom == PpAtomIfdef || nextAtom == PpAtomIfndef) { if (nextAtom == PpAtomIf || nextAtom == PpAtomIfdef || nextAtom == PpAtomIfndef)
{
depth++; depth++;
if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) { if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting)
{
_parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if/#ifdef/#ifndef", ""); _parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if/#ifdef/#ifndef", "");
return EndOfInput; return EndOfInput;
} else { }
ifdepth++; ifdepth++;
elsetracker++; elsetracker++;
} }
} else if (nextAtom == PpAtomEndif) { else if (nextAtom == PpAtomEndif)
{
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken)); token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
elseSeen[elsetracker] = false; elseSeen[elsetracker] = false;
--elsetracker; --elsetracker;
if (depth == 0) { if (depth == 0)
{
// found the #endif we are looking for // found the #endif we are looking for
if (ifdepth > 0) if (ifdepth > 0)
--ifdepth; --ifdepth;
@ -263,18 +281,24 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
} }
--depth; --depth;
--ifdepth; --ifdepth;
} else if (matchelse && depth == 0) { }
if (nextAtom == PpAtomElse) { else if (matchelse && depth == 0)
{
if (nextAtom == PpAtomElse)
{
elseSeen[elsetracker] = true; elseSeen[elsetracker] = true;
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken)); token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
// found the #else we are looking for // found the #else we are looking for
break; break;
} else if (nextAtom == PpAtomElif) { }
else if (nextAtom == PpAtomElif)
{
if (elseSeen[elsetracker]) if (elseSeen[elsetracker])
_parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", ""); _parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
/* we decrement ifdepth here, because CPPif will increment /* we decrement ifdepth here, because CPPif will increment
* it and we really want to leave it alone */ * it and we really want to leave it alone */
if (ifdepth > 0) { if (ifdepth > 0)
{
--ifdepth; --ifdepth;
elseSeen[elsetracker] = false; elseSeen[elsetracker] = false;
--elsetracker; --elsetracker;
@ -282,13 +306,17 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
return CPPif(ppToken); return CPPif(ppToken);
} }
} else if (nextAtom == PpAtomElse) { }
else if (nextAtom == PpAtomElse)
{
if (elseSeen[elsetracker]) if (elseSeen[elsetracker])
_parseContext.ppError(ppToken->loc, "#else after #else", "#else", ""); _parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
else else
elseSeen[elsetracker] = true; elseSeen[elsetracker] = true;
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken)); token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
} else if (nextAtom == PpAtomElif) { }
else if (nextAtom == PpAtomElif)
{
if (elseSeen[elsetracker]) if (elseSeen[elsetracker])
_parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", ""); _parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
} }
@ -300,9 +328,9 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
// Call when there should be no more tokens left on a line. // Call when there should be no more tokens left on a line.
int TPpContext::extraTokenCheck(int contextAtom, TPpToken* ppToken, int token) int TPpContext::extraTokenCheck(int contextAtom, TPpToken* ppToken, int token)
{ {
if (token != '\n' && token != EndOfInput) { if (token != '\n' && token != EndOfInput)
{
static const char* message = "unexpected tokens following directive"; static const char* message = "unexpected tokens following directive";
const char* label; const char* label;
if (contextAtom == PpAtomElse) if (contextAtom == PpAtomElse)
label = "#else"; label = "#else";
@ -565,20 +593,24 @@ int TPpContext::CPPif(TPpToken* ppToken)
int TPpContext::CPPifdef(int defined, TPpToken* ppToken) int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
{ {
int token = scanToken(ppToken); int token = scanToken(ppToken);
if (ifdepth > maxIfNesting || elsetracker > maxIfNesting) { if (ifdepth > maxIfNesting || elsetracker > maxIfNesting)
{
_parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", ""); _parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
return EndOfInput; return EndOfInput;
} else {
elsetracker++;
ifdepth++;
} }
if (token != PpAtomIdentifier) { elsetracker++;
ifdepth++;
if (token != PpAtomIdentifier)
{
if (defined) if (defined)
_parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifdef", ""); _parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifdef", "");
else else
_parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", ""); _parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", "");
} else { }
else
{
MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name)); MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
token = scanToken(ppToken); token = scanToken(ppToken);
if (token != '\n') { if (token != '\n') {
@ -732,18 +764,18 @@ int TPpContext::CPPerror(TPpToken* ppToken)
std::string message; std::string message;
TSourceLoc loc = ppToken->loc; TSourceLoc loc = ppToken->loc;
while (token != '\n' && token != EndOfInput) { while (token != '\n' && token != EndOfInput)
{
if (token == PpAtomConstInt16 || token == PpAtomConstUint16 || if (token == PpAtomConstInt16 || token == PpAtomConstUint16 ||
token == PpAtomConstInt || token == PpAtomConstUint || token == PpAtomConstInt || token == PpAtomConstUint ||
token == PpAtomConstInt64 || token == PpAtomConstUint64 || token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
token == PpAtomConstFloat16 || token == PpAtomConstFloat16 ||
token == PpAtomConstFloat || token == PpAtomConstDouble) { token == PpAtomConstFloat || token == PpAtomConstDouble)
message.append(ppToken->name); message.append(ppToken->name);
} else if (token == PpAtomIdentifier || token == PpAtomConstString) { else if (token == PpAtomIdentifier || token == PpAtomConstString)
message.append(ppToken->name); message.append(ppToken->name);
} else { else
message.append(atomStrings.getString(token)); message.append(atomStrings.getString(token));
}
message.append(" "); message.append(" ");
token = scanToken(ppToken); token = scanToken(ppToken);
} }
@ -807,7 +839,8 @@ int TPpContext::CPPversion(TPpToken* ppToken)
} }
versionSeen = true; versionSeen = true;
if (token == '\n') { if (token == '\n')
{
_parseContext.ppError(ppToken->loc, "must be followed by version number", "#version", ""); _parseContext.ppError(ppToken->loc, "must be followed by version number", "#version", "");
return token; return token;
@ -821,10 +854,13 @@ int TPpContext::CPPversion(TPpToken* ppToken)
int line = ppToken->loc.line; int line = ppToken->loc.line;
token = scanToken(ppToken); token = scanToken(ppToken);
if (token == '\n') { if (token == '\n')
{
_parseContext.notifyVersion(line, versionNumber, NULL); _parseContext.notifyVersion(line, versionNumber, NULL);
return token; return token;
} else { }
else
{
int profileAtom = atomStrings.getAtom(ppToken->name); int profileAtom = atomStrings.getAtom(ppToken->name);
if (profileAtom != PpAtomCore && if (profileAtom != PpAtomCore &&
profileAtom != PpAtomCompatibility && profileAtom != PpAtomCompatibility &&
@ -835,7 +871,6 @@ int TPpContext::CPPversion(TPpToken* ppToken)
if (token == '\n') if (token == '\n')
return token; return token;
else
_parseContext.ppError(ppToken->loc, "bad tokens following profile -- expected newline", "#version", ""); _parseContext.ppError(ppToken->loc, "bad tokens following profile -- expected newline", "#version", "");
} }
@ -860,13 +895,15 @@ int TPpContext::CPPextension(TPpToken* ppToken)
strcpy(extensionName, ppToken->name); strcpy(extensionName, ppToken->name);
token = scanToken(ppToken); token = scanToken(ppToken);
if (token != ':') { if (token != ':')
{
_parseContext.ppError(ppToken->loc, "':' missing after extension name", "#extension", ""); _parseContext.ppError(ppToken->loc, "':' missing after extension name", "#extension", "");
return token; return token;
} }
token = scanToken(ppToken); token = scanToken(ppToken);
if (token != PpAtomIdentifier) { if (token != PpAtomIdentifier)
{
_parseContext.ppError(ppToken->loc, "behavior for extension not specified", "#extension", ""); _parseContext.ppError(ppToken->loc, "behavior for extension not specified", "#extension", "");
return token; return token;
} }
@ -877,7 +914,7 @@ int TPpContext::CPPextension(TPpToken* ppToken)
token = scanToken(ppToken); token = scanToken(ppToken);
if (token == '\n') if (token == '\n')
return token; return token;
else
_parseContext.ppError(ppToken->loc, "extra tokens -- expected newline", "#extension",""); _parseContext.ppError(ppToken->loc, "extra tokens -- expected newline", "#extension","");
return token; return token;
@ -980,16 +1017,19 @@ int TPpContext::scanHeaderName(TPpToken* ppToken, char delimit)
int len = 0; int len = 0;
ppToken->name[0] = '\0'; ppToken->name[0] = '\0';
do { for (;;)
{
int ch = inputStack.back()->getch(); int ch = inputStack.back()->getch();
// done yet? // done yet?
if (ch == delimit) { if (ch == delimit)
{
ppToken->name[len] = '\0'; ppToken->name[len] = '\0';
if (tooLong) if (tooLong)
_parseContext.ppError(ppToken->loc, "header name too long", "", ""); _parseContext.ppError(ppToken->loc, "header name too long", "", "");
return PpAtomConstString; return PpAtomConstString;
} else if (ch == EndOfInput) }
else if (ch == EndOfInput)
return EndOfInput; return EndOfInput;
// found a character to expand the name with // found a character to expand the name with
@ -997,7 +1037,7 @@ int TPpContext::scanHeaderName(TPpToken* ppToken, char delimit)
ppToken->name[len++] = (char)ch; ppToken->name[len++] = (char)ch;
else else
tooLong = true; tooLong = true;
} while (true); }
} }
// Macro-expand a macro argument 'arg' to create 'expandedArg'. // Macro-expand a macro argument 'arg' to create 'expandedArg'.
@ -1010,7 +1050,8 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken*
pushInput(new tMarkerInput(this)); pushInput(new tMarkerInput(this));
pushTokenStreamInput(arg); pushTokenStreamInput(arg);
int token; int token;
while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) { while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput)
{
token = tokenPaste(token, *ppToken); token = tokenPaste(token, *ppToken);
if (token == tMarkerInput::marker || token == EndOfInput) if (token == tMarkerInput::marker || token == EndOfInput)
break; break;
@ -1019,14 +1060,14 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken*
expandedArg->putToken(token, ppToken); expandedArg->putToken(token, ppToken);
} }
if (token == EndOfInput) { if (token == EndOfInput)
{
// MacroExpand ate the marker, so had bad input, recover // MacroExpand ate the marker, so had bad input, recover
delete expandedArg; delete expandedArg;
expandedArg = NULL; expandedArg = NULL;
} else {
// remove the marker
popInput();
} }
else // remove the marker
popInput();
return expandedArg; return expandedArg;
} }
@ -1056,13 +1097,15 @@ int TPpContext::tMacroInput::scan(TPpToken* ppToken)
// corresponding argument's preprocessing token sequence." // corresponding argument's preprocessing token sequence."
bool pasting = false; bool pasting = false;
if (postpaste) { if (postpaste)
{
// don't expand next token // don't expand next token
pasting = true; pasting = true;
postpaste = false; postpaste = false;
} }
if (prepaste) { if (prepaste)
{
// already know we should be on a ##, verify // already know we should be on a ##, verify
prepaste = false; prepaste = false;
postpaste = true; postpaste = true;

View File

@ -164,7 +164,8 @@ TStringAtomMap::TStringAtomMap()
char t[2]; char t[2];
t[1] = '\0'; t[1] = '\0';
while (*s) { while (*s)
{
t[0] = *s; t[0] = *s;
addAtomFixed(t, s[0]); addAtomFixed(t, s[0]);
s++; s++;

View File

@ -334,7 +334,6 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
return PpAtomConstDouble; return PpAtomConstDouble;
else if (isFloat16) else if (isFloat16)
return PpAtomConstFloat16; return PpAtomConstFloat16;
else
return PpAtomConstFloat; return PpAtomConstFloat;
} }
@ -349,10 +348,9 @@ int TPpContext::characterLiteral(TPpToken* ppToken)
ppToken->name[0] = 0; ppToken->name[0] = 0;
ppToken->ival = 0; ppToken->ival = 0;
if (_parseContext.intermediate.getSource() != EShSourceHlsl) {
// illegal, except in macro definition, for which case we report the character // illegal, except in macro definition, for which case we report the character
if (_parseContext.intermediate.getSource() != EShSourceHlsl)
return '\''; return '\'';
}
int ch = getChar(); int ch = getChar();
switch (ch) { switch (ch) {
@ -446,7 +444,8 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ppToken->i64val = 0; ppToken->i64val = 0;
ppToken->space = false; ppToken->space = false;
ch = getch(); ch = getch();
for (;;) { for (;;)
{
while (ch == ' ' || ch == '\t') { while (ch == ' ' || ch == '\t') {
ppToken->space = true; ppToken->space = true;
ch = getch(); ch = getch();
@ -850,49 +849,37 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
} }
case '*': case '*':
ch = getch(); ch = getch();
if (ch == '=') { if (ch == '=')
return PPAtomMulAssign; return PPAtomMulAssign;
} else {
ungetch(); ungetch();
return '*'; return '*';
}
case '%': case '%':
ch = getch(); ch = getch();
if (ch == '=') { if (ch == '=')
return PPAtomModAssign; return PPAtomModAssign;
} else {
ungetch(); ungetch();
return '%'; return '%';
}
case '^': case '^':
ch = getch(); ch = getch();
if (ch == '^') { if (ch == '^')
return PpAtomXor; return PpAtomXor;
} else {
if (ch == '=') if (ch == '=')
return PpAtomXorAssign; return PpAtomXorAssign;
else{
ungetch(); ungetch();
return '^'; return '^';
}
}
case '=': case '=':
ch = getch(); ch = getch();
if (ch == '=') { if (ch == '=')
return PpAtomEQ; return PpAtomEQ;
} else {
ungetch(); ungetch();
return '='; return '=';
}
case '!': case '!':
ch = getch(); ch = getch();
if (ch == '=') { if (ch == '=')
return PpAtomNE; return PpAtomNE;
} else {
ungetch(); ungetch();
return '!'; return '!';
}
case '|': case '|':
ch = getch(); ch = getch();
if (ch == '|') { if (ch == '|') {
@ -1043,14 +1030,18 @@ int TPpContext::tokenize(TPpToken& ppToken)
return EndOfInput; return EndOfInput;
} }
if (token == '#') { if (token == '#') {
if (previous_token == '\n') { if (previous_token == '\n')
{
token = readCPPline(&ppToken); token = readCPPline(&ppToken);
if (token == EndOfInput) { if (token == EndOfInput)
{
missingEndifCheck(); missingEndifCheck();
return EndOfInput; return EndOfInput;
} }
continue; continue;
} else { }
else
{
_parseContext.ppError(ppToken.loc, "preprocessor directive cannot be preceded by another token", "#", ""); _parseContext.ppError(ppToken.loc, "preprocessor directive cannot be preceded by another token", "#", "");
return EndOfInput; return EndOfInput;
} }
@ -1105,7 +1096,8 @@ int TPpContext::tokenize(TPpToken& ppToken)
int TPpContext::tokenPaste(int token, TPpToken& ppToken) int TPpContext::tokenPaste(int token, TPpToken& ppToken)
{ {
// starting with ## is illegal, skip to next token // starting with ## is illegal, skip to next token
if (token == PpAtomPaste) { if (token == PpAtomPaste)
{
_parseContext.ppError(ppToken.loc, "unexpected location", "##", ""); _parseContext.ppError(ppToken.loc, "unexpected location", "##", "");
return scanToken(&ppToken); return scanToken(&ppToken);
} }
@ -1113,14 +1105,16 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
int resultToken = token; // "foo" pasted with "35" is an identifier, not a number int resultToken = token; // "foo" pasted with "35" is an identifier, not a number
// ## can be chained, process all in the chain at once // ## can be chained, process all in the chain at once
while (peekPasting()) { while (peekPasting())
{
TPpToken pastedPpToken; TPpToken pastedPpToken;
// next token has to be ## // next token has to be ##
token = scanToken(&pastedPpToken); token = scanToken(&pastedPpToken);
// This covers end of macro expansion // This covers end of macro expansion
if (endOfReplacementList()) { if (endOfReplacementList())
{
_parseContext.ppError(ppToken.loc, "unexpected location; end of replacement list", "##", ""); _parseContext.ppError(ppToken.loc, "unexpected location; end of replacement list", "##", "");
break; break;
} }
@ -1135,7 +1129,8 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
} }
// get the token text // get the token text
switch (resultToken) { switch (resultToken)
{
case PpAtomIdentifier: case PpAtomIdentifier:
// already have the correct text in token.names // already have the correct text in token.names
break; break;
@ -1173,7 +1168,8 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
strncat(ppToken.name, pastedPpToken.name, MaxTokenLength - strlen(ppToken.name)); strncat(ppToken.name, pastedPpToken.name, MaxTokenLength - strlen(ppToken.name));
// correct the kind of token we are making, if needed (identifiers stay identifiers) // correct the kind of token we are making, if needed (identifiers stay identifiers)
if (resultToken != PpAtomIdentifier) { if (resultToken != PpAtomIdentifier)
{
int newToken = atomStrings.getAtom(ppToken.name); int newToken = atomStrings.getAtom(ppToken.name);
if (newToken > 0) if (newToken > 0)
resultToken = newToken; resultToken = newToken;

View File

@ -105,7 +105,8 @@ namespace {
// be saved (restored)? // be saved (restored)?
bool SaveName(int atom) bool SaveName(int atom)
{ {
switch (atom) { switch (atom)
{
case PpAtomIdentifier: case PpAtomIdentifier:
case PpAtomConstString: case PpAtomConstString:
case PpAtomConstInt: case PpAtomConstInt:
@ -121,15 +122,17 @@ namespace {
case PpAtomConstFloat16: case PpAtomConstFloat16:
return true; return true;
default: default:
return false; break;
} }
return false;
} }
// When recording (and playing back) should the numeric value // When recording (and playing back) should the numeric value
// be saved (restored)? // be saved (restored)?
bool SaveValue(int atom) bool SaveValue(int atom)
{ {
switch (atom) { switch (atom)
{
case PpAtomConstInt: case PpAtomConstInt:
case PpAtomConstUint: case PpAtomConstUint:
case PpAtomConstInt64: case PpAtomConstInt64:
@ -143,8 +146,9 @@ namespace {
case PpAtomConstFloat16: case PpAtomConstFloat16:
return true; return true;
default: default:
return false; break;
} }
return false;
} }
} }
@ -178,7 +182,8 @@ void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken)
putSubtoken(static_cast<char>(atom)); putSubtoken(static_cast<char>(atom));
// save the backing name string // save the backing name string
if (SaveName(atom)) { if (SaveName(atom))
{
const char* s = ppToken->name; const char* s = ppToken->name;
while (*s) while (*s)
putSubtoken(*s++); putSubtoken(*s++);
@ -186,7 +191,8 @@ void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken)
} }
// save the numeric value // save the numeric value
if (SaveValue(atom)) { if (SaveValue(atom))
{
const char* n = reinterpret_cast<const char*>(&ppToken->i64val); const char* n = reinterpret_cast<const char*>(&ppToken->i64val);
for (size_t i = 0; i < sizeof(ppToken->i64val); ++i) for (size_t i = 0; i < sizeof(ppToken->i64val); ++i)
putSubtoken(*n++); putSubtoken(*n++);
@ -207,15 +213,20 @@ int TPpContext::TokenStream::getToken(TParseContextBase& _parseContext, TPpToken
ppToken->loc = _parseContext.getCurrentLoc(); ppToken->loc = _parseContext.getCurrentLoc();
// get the backing name string // get the backing name string
if (SaveName(atom)) { if (SaveName(atom))
{
int ch = getSubtoken(); int ch = getSubtoken();
int len = 0; int len = 0;
while (ch != 0 && ch != EndOfInput) { while (ch != 0 && ch != EndOfInput)
if (len < MaxTokenLength) { {
if (len < MaxTokenLength)
{
ppToken->name[len] = (char)ch; ppToken->name[len] = (char)ch;
len++; len++;
ch = getSubtoken(); ch = getSubtoken();
} else { }
else
{
_parseContext.error(ppToken->loc, "token too long", "", ""); _parseContext.error(ppToken->loc, "token too long", "", "");
break; break;
} }
@ -224,13 +235,17 @@ int TPpContext::TokenStream::getToken(TParseContextBase& _parseContext, TPpToken
} }
// Check for ##, unless the current # is the last character // Check for ##, unless the current # is the last character
if (atom == '#') { if (atom == '#')
if (current < data.size()) { {
if (getSubtoken() == '#') { if (current < data.size())
{
if (getSubtoken() == '#')
{
_parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); _parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
_parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); _parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
atom = PpAtomPaste; atom = PpAtomPaste;
} else }
else
ungetSubtoken(); ungetSubtoken();
} }
} }
@ -273,15 +288,17 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
// Are we at the last non-whitespace token? // Are we at the last non-whitespace token?
savePos = current; savePos = current;
bool moreTokens = false; bool moreTokens = false;
do { for (;;)
{
subtoken = getSubtoken(); subtoken = getSubtoken();
if (subtoken == EndOfInput) if (subtoken == EndOfInput)
break; break;
if (subtoken != ' ') { if (subtoken != ' ')
{
moreTokens = true; moreTokens = true;
break; break;
} }
} while (true); }
current = savePos; current = savePos;
return !moreTokens; return !moreTokens;

View File

@ -93,8 +93,9 @@ bool isDereferenceOperation(glslang::TOperator op)
case glslang::EOpMatrixSwizzle: case glslang::EOpMatrixSwizzle:
return true; return true;
default: default:
return false; break;
} }
return false;
} }
// Returns true if the opcode leads to an assignment operation. // Returns true if the opcode leads to an assignment operation.
@ -123,8 +124,9 @@ bool isAssignOperation(glslang::TOperator op)
case glslang::EOpPreDecrement: case glslang::EOpPreDecrement:
return true; return true;
default: default:
return false; break;
} }
return false;
} }
// A helper function to get the unsigned int from a given constant union node. // A helper function to get the unsigned int from a given constant union node.
@ -180,8 +182,9 @@ bool isArithmeticOperation(glslang::TOperator op)
case glslang::EOpPreDecrement: case glslang::EOpPreDecrement:
return true; return true;
default: default:
return false; break;
} }
return false;
} }
// A helper class to help manage the populating_initial_no_contraction_ flag. // A helper class to help manage the populating_initial_no_contraction_ flag.
@ -232,7 +235,8 @@ ObjectAccessChain getSubAccessChainAfterPrefix(const ObjectAccessChain& chain,
// //
class TSymbolDefinitionCollectingTraverser : public glslang::TIntermTraverser { class TSymbolDefinitionCollectingTraverser : public glslang::TIntermTraverser {
public: public:
TSymbolDefinitionCollectingTraverser(NodeMapping* symbol_definition_mapping, TSymbolDefinitionCollectingTraverser(
NodeMapping* symbol_definition_mapping,
AccessChainMapping* accesschain_mapping, AccessChainMapping* accesschain_mapping,
ObjectAccesschainSet* precise_objects, ObjectAccesschainSet* precise_objects,
ReturnBranchNodeSet* precise_return_nodes); ReturnBranchNodeSet* precise_return_nodes);
@ -312,9 +316,11 @@ bool TSymbolDefinitionCollectingTraverser::visitAggregate(glslang::TVisit,
bool TSymbolDefinitionCollectingTraverser::visitBranch(glslang::TVisit, bool TSymbolDefinitionCollectingTraverser::visitBranch(glslang::TVisit,
glslang::TIntermBranch* node) glslang::TIntermBranch* node)
{ {
if (node->getFlowOp() == glslang::EOpReturn && node->getExpression() && if ( node->getFlowOp() == glslang::EOpReturn
current_function_definition_node_ && && node->getExpression()
current_function_definition_node_->getType().getQualifier().noContraction) { && current_function_definition_node_
&& current_function_definition_node_->getType().getQualifier().noContraction)
{
// This node is a return node with an expression, and its function has a // This node is a return node with an expression, and its function has a
// precise return value. We need to find the involved objects in its // precise return value. We need to find the involved objects in its
// expression and add them to the set of initial precise objects. // expression and add them to the set of initial precise objects.
@ -325,17 +331,20 @@ bool TSymbolDefinitionCollectingTraverser::visitBranch(glslang::TVisit,
} }
// Visits a unary node. This might be an implicit assignment like i++, i--. etc. // Visits a unary node. This might be an implicit assignment like i++, i--. etc.
bool TSymbolDefinitionCollectingTraverser::visitUnary(glslang::TVisit /* visit */, bool TSymbolDefinitionCollectingTraverser::visitUnary(
glslang::TVisit visit,
glslang::TIntermUnary* node) glslang::TIntermUnary* node)
{ {
current_object_.clear(); current_object_.clear();
node->getOperand()->traverse(this); node->getOperand()->traverse(this);
if (isAssignOperation(node->getOp())) { if (isAssignOperation(node->getOp()))
{
// We should always be able to get an access chain of the operand node. // We should always be able to get an access chain of the operand node.
// If the operand node object is 'precise', we collect its access chain // If the operand node object is 'precise', we collect its access chain
// for the initial set of 'precise' objects. // for the initial set of 'precise' objects.
if (isPreciseObjectNode(node->getOperand())) { if (isPreciseObjectNode(node->getOperand()))
{
// The operand node is an 'precise' object node, add its // The operand node is an 'precise' object node, add its
// access chain to the set of 'precise' objects. This is to collect // access chain to the set of 'precise' objects. This is to collect
// the initial set of 'precise' objects. // the initial set of 'precise' objects.
@ -354,7 +363,7 @@ bool TSymbolDefinitionCollectingTraverser::visitUnary(glslang::TVisit /* visit *
// Visits a binary node and updates the mapping from symbol IDs to the definition // Visits a binary node and updates the mapping from symbol IDs to the definition
// nodes. Also collects the access chains for the initial precise objects. // nodes. Also collects the access chains for the initial precise objects.
bool TSymbolDefinitionCollectingTraverser::visitBinary(glslang::TVisit /* visit */, bool TSymbolDefinitionCollectingTraverser::visitBinary(glslang::TVisit visit,
glslang::TIntermBinary* node) glslang::TIntermBinary* node)
{ {
// Traverses the left node to build the access chain info for the object. // Traverses the left node to build the access chain info for the object.
@ -414,9 +423,8 @@ bool TSymbolDefinitionCollectingTraverser::visitBinary(glslang::TVisit /* visit
std::tuple<NodeMapping, AccessChainMapping, ObjectAccesschainSet, ReturnBranchNodeSet> std::tuple<NodeMapping, AccessChainMapping, ObjectAccesschainSet, ReturnBranchNodeSet>
getSymbolToDefinitionMappingAndPreciseSymbolIDs(const glslang::TIntermediate& intermediate) getSymbolToDefinitionMappingAndPreciseSymbolIDs(const glslang::TIntermediate& intermediate)
{ {
auto result_tuple = std::make_tuple(NodeMapping(), AccessChainMapping(), ObjectAccesschainSet(), auto result_tuple = std::make_tuple(NodeMapping(), AccessChainMapping(),
ReturnBranchNodeSet()); ObjectAccesschainSet(), ReturnBranchNodeSet());
TIntermNode* root = intermediate.getTreeRoot(); TIntermNode* root = intermediate.getTreeRoot();
if (root == 0) if (root == 0)
return result_tuple; return result_tuple;
@ -427,8 +435,7 @@ getSymbolToDefinitionMappingAndPreciseSymbolIDs(const glslang::TIntermediate& in
ReturnBranchNodeSet& precise_return_nodes = std::get<3>(result_tuple); ReturnBranchNodeSet& precise_return_nodes = std::get<3>(result_tuple);
// Traverses the AST and populate the results. // Traverses the AST and populate the results.
TSymbolDefinitionCollectingTraverser collector(&symbol_definition_mapping, &accesschain_mapping, TSymbolDefinitionCollectingTraverser collector(&symbol_definition_mapping, &accesschain_mapping, &precise_objects, &precise_return_nodes);
&precise_objects, &precise_return_nodes);
root->traverse(&collector); root->traverse(&collector);
return result_tuple; return result_tuple;

View File

@ -389,24 +389,24 @@ public:
switch ((int)sampler.dim) { switch ((int)sampler.dim) {
case Esd1D: case Esd1D:
switch ((int)sampler.shadow) { switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_SAMPLER_1D_ARRAY : GL_SAMPLER_1D; case 0: return sampler.arrayed ? GL_SAMPLER_1D_ARRAY : GL_SAMPLER_1D;
case true: return sampler.arrayed ? GL_SAMPLER_1D_ARRAY_SHADOW : GL_SAMPLER_1D_SHADOW; case 1: return sampler.arrayed ? GL_SAMPLER_1D_ARRAY_SHADOW : GL_SAMPLER_1D_SHADOW;
} }
case Esd2D: case Esd2D:
switch ((int)sampler.ms) { switch ((int)sampler.ms) {
case false: case 0:
switch ((int)sampler.shadow) { switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_SAMPLER_2D_ARRAY : GL_SAMPLER_2D; case 0: return sampler.arrayed ? GL_SAMPLER_2D_ARRAY : GL_SAMPLER_2D;
case true: return sampler.arrayed ? GL_SAMPLER_2D_ARRAY_SHADOW : GL_SAMPLER_2D_SHADOW; case 1: return sampler.arrayed ? GL_SAMPLER_2D_ARRAY_SHADOW : GL_SAMPLER_2D_SHADOW;
} }
case true: return sampler.arrayed ? GL_SAMPLER_2D_MULTISAMPLE_ARRAY : GL_SAMPLER_2D_MULTISAMPLE; case 1: return sampler.arrayed ? GL_SAMPLER_2D_MULTISAMPLE_ARRAY : GL_SAMPLER_2D_MULTISAMPLE;
} }
case Esd3D: case Esd3D:
return GL_SAMPLER_3D; return GL_SAMPLER_3D;
case EsdCube: case EsdCube:
switch ((int)sampler.shadow) { switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY : GL_SAMPLER_CUBE; case 0: return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY : GL_SAMPLER_CUBE;
case true: return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW : GL_SAMPLER_CUBE_SHADOW; case 1: return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW : GL_SAMPLER_CUBE_SHADOW;
} }
case EsdRect: case EsdRect:
return sampler.shadow ? GL_SAMPLER_2D_RECT_SHADOW : GL_SAMPLER_2D_RECT; return sampler.shadow ? GL_SAMPLER_2D_RECT_SHADOW : GL_SAMPLER_2D_RECT;
@ -418,24 +418,24 @@ public:
switch ((int)sampler.dim) { switch ((int)sampler.dim) {
case Esd1D: case Esd1D:
switch ((int)sampler.shadow) { switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_AMD : GL_FLOAT16_SAMPLER_1D_AMD; case 0: return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_AMD : GL_FLOAT16_SAMPLER_1D_AMD;
case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_1D_SHADOW_AMD; case 1: return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_1D_SHADOW_AMD;
} }
case Esd2D: case Esd2D:
switch ((int)sampler.ms) { switch ((int)sampler.ms) {
case false: case 0:
switch ((int)sampler.shadow) { switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_AMD; case 0: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_AMD;
case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_SHADOW_AMD; case 1: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_SHADOW_AMD;
} }
case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD; case 1: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD;
} }
case Esd3D: case Esd3D:
return GL_FLOAT16_SAMPLER_3D_AMD; return GL_FLOAT16_SAMPLER_3D_AMD;
case EsdCube: case EsdCube:
switch ((int)sampler.shadow) { switch ((int)sampler.shadow) {
case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD : GL_FLOAT16_SAMPLER_CUBE_AMD; case 0: return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD : GL_FLOAT16_SAMPLER_CUBE_AMD;
case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD; case 1: return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD;
} }
case EsdRect: case EsdRect:
return sampler.shadow ? GL_FLOAT16_SAMPLER_2D_RECT_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_RECT_AMD; return sampler.shadow ? GL_FLOAT16_SAMPLER_2D_RECT_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_RECT_AMD;
@ -449,8 +449,8 @@ public:
return sampler.arrayed ? GL_INT_SAMPLER_1D_ARRAY : GL_INT_SAMPLER_1D; return sampler.arrayed ? GL_INT_SAMPLER_1D_ARRAY : GL_INT_SAMPLER_1D;
case Esd2D: case Esd2D:
switch ((int)sampler.ms) { switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_INT_SAMPLER_2D_ARRAY : GL_INT_SAMPLER_2D; case 0: return sampler.arrayed ? GL_INT_SAMPLER_2D_ARRAY : GL_INT_SAMPLER_2D;
case true: return sampler.arrayed ? GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY case 1: return sampler.arrayed ? GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
: GL_INT_SAMPLER_2D_MULTISAMPLE; : GL_INT_SAMPLER_2D_MULTISAMPLE;
} }
case Esd3D: case Esd3D:
@ -468,8 +468,8 @@ public:
return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_1D_ARRAY : GL_UNSIGNED_INT_SAMPLER_1D; return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_1D_ARRAY : GL_UNSIGNED_INT_SAMPLER_1D;
case Esd2D: case Esd2D:
switch ((int)sampler.ms) { switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_ARRAY : GL_UNSIGNED_INT_SAMPLER_2D; case 0: return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_ARRAY : GL_UNSIGNED_INT_SAMPLER_2D;
case true: return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY case 1: return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
: GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE; : GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
} }
case Esd3D: case Esd3D:
@ -493,8 +493,8 @@ public:
return sampler.arrayed ? GL_IMAGE_1D_ARRAY : GL_IMAGE_1D; return sampler.arrayed ? GL_IMAGE_1D_ARRAY : GL_IMAGE_1D;
case Esd2D: case Esd2D:
switch ((int)sampler.ms) { switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_IMAGE_2D_ARRAY : GL_IMAGE_2D; case 0: return sampler.arrayed ? GL_IMAGE_2D_ARRAY : GL_IMAGE_2D;
case true: return sampler.arrayed ? GL_IMAGE_2D_MULTISAMPLE_ARRAY : GL_IMAGE_2D_MULTISAMPLE; case 1: return sampler.arrayed ? GL_IMAGE_2D_MULTISAMPLE_ARRAY : GL_IMAGE_2D_MULTISAMPLE;
} }
case Esd3D: case Esd3D:
return GL_IMAGE_3D; return GL_IMAGE_3D;
@ -512,8 +512,8 @@ public:
return sampler.arrayed ? GL_FLOAT16_IMAGE_1D_ARRAY_AMD : GL_FLOAT16_IMAGE_1D_AMD; return sampler.arrayed ? GL_FLOAT16_IMAGE_1D_ARRAY_AMD : GL_FLOAT16_IMAGE_1D_AMD;
case Esd2D: case Esd2D:
switch ((int)sampler.ms) { switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_AMD; case 0: return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_AMD;
case true: return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD; case 1: return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD;
} }
case Esd3D: case Esd3D:
return GL_FLOAT16_IMAGE_3D_AMD; return GL_FLOAT16_IMAGE_3D_AMD;
@ -531,8 +531,8 @@ public:
return sampler.arrayed ? GL_INT_IMAGE_1D_ARRAY : GL_INT_IMAGE_1D; return sampler.arrayed ? GL_INT_IMAGE_1D_ARRAY : GL_INT_IMAGE_1D;
case Esd2D: case Esd2D:
switch ((int)sampler.ms) { switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_INT_IMAGE_2D_ARRAY : GL_INT_IMAGE_2D; case 0: return sampler.arrayed ? GL_INT_IMAGE_2D_ARRAY : GL_INT_IMAGE_2D;
case true: return sampler.arrayed ? GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY : GL_INT_IMAGE_2D_MULTISAMPLE; case 1: return sampler.arrayed ? GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY : GL_INT_IMAGE_2D_MULTISAMPLE;
} }
case Esd3D: case Esd3D:
return GL_INT_IMAGE_3D; return GL_INT_IMAGE_3D;
@ -549,8 +549,8 @@ public:
return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_1D_ARRAY : GL_UNSIGNED_INT_IMAGE_1D; return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_1D_ARRAY : GL_UNSIGNED_INT_IMAGE_1D;
case Esd2D: case Esd2D:
switch ((int)sampler.ms) { switch ((int)sampler.ms) {
case false: return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_ARRAY : GL_UNSIGNED_INT_IMAGE_2D; case 0: return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_ARRAY : GL_UNSIGNED_INT_IMAGE_2D;
case true: return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY case 1: return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY
: GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE; : GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE;
} }
case Esd3D: case Esd3D: