Merge branch 'master' into textureQueryLOD

This commit is contained in:
Greg Fischer 2021-11-22 10:39:03 -07:00 committed by GitHub
commit a40e4ac3f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
166 changed files with 8875 additions and 4653 deletions

View file

@ -269,6 +269,8 @@ static glslang::EShTargetClientVersion c_shader_client_version(glslang_target_cl
switch (client_version) {
case GLSLANG_TARGET_VULKAN_1_1:
return glslang::EShTargetVulkan_1_1;
case GLSLANG_TARGET_VULKAN_1_2:
return glslang::EShTargetVulkan_1_2;
case GLSLANG_TARGET_OPENGL_450:
return glslang::EShTargetOpenGL_450;
default:

View file

@ -35,14 +35,14 @@ if(WIN32)
add_subdirectory(OSDependent/Windows)
elseif(UNIX OR "${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia")
add_subdirectory(OSDependent/Unix)
else(WIN32)
else()
message("unknown platform")
endif(WIN32)
endif()
if(EMSCRIPTEN OR ENABLE_GLSLANG_JS)
# May be enabled on non-Emscripten builds for binary-size testing.
add_subdirectory(OSDependent/Web)
endif(EMSCRIPTEN OR ENABLE_GLSLANG_JS)
endif()
################################################################################
# GenericCodeGen
@ -129,7 +129,7 @@ if(ENABLE_HLSL)
HLSL/hlslTokenStream.h
HLSL/hlslGrammar.h
HLSL/hlslParseables.h)
endif(ENABLE_HLSL)
endif()
add_library(MachineIndependent STATIC ${MACHINEINDEPENDENT_SOURCES} ${MACHINEINDEPENDENT_HEADERS})
set_property(TARGET MachineIndependent PROPERTY POSITION_INDEPENDENT_CODE ON)
@ -194,7 +194,7 @@ if(WIN32)
source_group("MachineIndependent\\Preprocessor" REGULAR_EXPRESSION "MachineIndependent/preprocessor/*")
source_group("HLSL" REGULAR_EXPRESSION "HLSL/*")
source_group("CInterface" REGULAR_EXPRESSION "CInterface/*")
endif(WIN32)
endif()
################################################################################
# install
@ -225,4 +225,4 @@ if(ENABLE_GLSLANG_INSTALL)
install(FILES ${GLSLANG_BUILD_INFO_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/glslang)
endif(ENABLE_GLSLANG_INSTALL)
endif()

View file

@ -0,0 +1,38 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2013-2016 LunarG, Inc.
// Copyright (C) 2016-2020 Google, Inc.
// Modifications Copyright(C) 2021 Advanced Micro Devices, Inc.All rights reserved.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//

View file

@ -2167,8 +2167,21 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
TIntermSymbol* arg = intermediate.addSymbol(*argVars.back());
handleFunctionArgument(&callee, callingArgs, arg);
if (param.type->getQualifier().isParamInput()) {
intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign, arg,
intermediate.addSymbol(**inputIt)));
TIntermTyped* input = intermediate.addSymbol(**inputIt);
if (input->getType().getQualifier().builtIn == EbvFragCoord && intermediate.getDxPositionW()) {
// Replace FragCoord W with reciprocal
auto pos_xyz = handleDotDereference(loc, input, "xyz");
auto pos_w = handleDotDereference(loc, input, "w");
auto one = intermediate.addConstantUnion(1.0, EbtFloat, loc);
auto recip_w = intermediate.addBinaryMath(EOpDiv, one, pos_w, loc);
TIntermAggregate* dst = new TIntermAggregate(EOpConstructVec4);
dst->getSequence().push_back(pos_xyz);
dst->getSequence().push_back(recip_w);
dst->setType(TType(EbtFloat, EvqTemporary, 4));
dst->setLoc(loc);
input = dst;
}
intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign, arg, input));
inputIt++;
}
if (param.type->getQualifier().storage == EvqUniform) {
@ -4017,12 +4030,12 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
txsample->getSequence().push_back(txcombine);
txsample->getSequence().push_back(argCoord);
if (argBias != nullptr)
txsample->getSequence().push_back(argBias);
if (argOffset != nullptr)
txsample->getSequence().push_back(argOffset);
if (argBias != nullptr)
txsample->getSequence().push_back(argBias);
node = convertReturn(txsample, sampler);
break;
@ -6935,6 +6948,9 @@ void HlslParseContext::shareStructBufferType(TType& type)
if (lhs.isStruct() != rhs.isStruct())
return false;
if (lhs.getQualifier().builtIn != rhs.getQualifier().builtIn)
return false;
if (lhs.isStruct() && rhs.isStruct()) {
if (lhs.getStruct()->size() != rhs.getStruct()->size())
return false;

View file

@ -665,8 +665,8 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
{ "Sample", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangPS, true },
{ "Sample", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangPS, true },
{ "SampleBias", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,", EShLangPS, true },
{ "SampleBias", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,,I", EShLangPS, true },
{ "SampleBias", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,F", EShLangPS, true },
{ "SampleBias", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,F,I", EShLangPS, true },
// TODO: FXC accepts int/uint samplers here. unclear what that means.
{ "SampleCmp", /*!O*/ "S", "F", "%@,S,V,S", "FIU,s,F,", EShLangPS, true },

View file

@ -270,6 +270,7 @@ enum TBuiltInVariable {
EbvWorldToObject,
EbvWorldToObject3x4,
EbvIncomingRayFlags,
EbvCurrentRayTimeNV,
// barycentrics
EbvBaryCoordNV,
EbvBaryCoordNoPerspNV,
@ -475,6 +476,7 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
case EbvIncomingRayFlags: return "IncomingRayFlagsNV";
case EbvObjectToWorld: return "ObjectToWorldNV";
case EbvWorldToObject: return "WorldToObjectNV";
case EbvCurrentRayTimeNV: return "CurrentRayTimeNV";
case EbvBaryCoordNV: return "BaryCoordNV";
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";

View file

@ -39,6 +39,11 @@
#include <algorithm>
#include <cassert>
#ifdef _MSC_VER
#include <cfloat>
#else
#include <cmath>
#endif
#include <cstdio>
#include <cstdlib>
#include <list>
@ -61,7 +66,7 @@ std::string to_string(const T& val) {
}
#endif
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || MINGW_HAS_SECURE_API
#include <basetsd.h>
#ifndef snprintf
#define snprintf sprintf_s
@ -213,7 +218,7 @@ template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
//
// Create a TString object from an integer.
//
#if defined _MSC_VER || defined MINGW_HAS_SECURE_API
#if defined _MSC_VER || MINGW_HAS_SECURE_API
inline const TString String(const int i, const int base = 10)
{
char text[16]; // 32 bit ints are at most 10 digits in base 10
@ -302,6 +307,34 @@ template <class T> int IntLog2(T n)
return result;
}
inline bool IsInfinity(double x) {
#ifdef _MSC_VER
switch (_fpclass(x)) {
case _FPCLASS_NINF:
case _FPCLASS_PINF:
return true;
default:
return false;
}
#else
return std::isinf(x);
#endif
}
inline bool IsNan(double x) {
#ifdef _MSC_VER
switch (_fpclass(x)) {
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
return true;
default:
return false;
}
#else
return std::isnan(x);
#endif
}
} // end namespace glslang
#endif // _COMMON_INCLUDED_

View file

@ -306,6 +306,8 @@ public:
TPoolAllocator& getAllocator() const { return allocator; }
pool_allocator select_on_container_copy_construction() const { return pool_allocator{}; }
protected:
pool_allocator& operator=(const pool_allocator&) { return *this; }
TPoolAllocator& allocator;

View file

@ -65,7 +65,7 @@ struct TSpirvExecutionMode {
// spirv_execution_mode
TMap<int, TVector<const TIntermConstantUnion*>> modes;
// spirv_execution_mode_id
TMap<int, TVector<const TIntermConstantUnion*> > modeIds;
TMap<int, TVector<const TIntermTyped*> > modeIds;
};
// SPIR-V decorations
@ -75,7 +75,7 @@ struct TSpirvDecorate {
// spirv_decorate
TMap<int, TVector<const TIntermConstantUnion*> > decorates;
// spirv_decorate_id
TMap<int, TVector<const TIntermConstantUnion*> > decorateIds;
TMap<int, TVector<const TIntermTyped*>> decorateIds;
// spirv_decorate_string
TMap<int, TVector<const TIntermConstantUnion*> > decorateStrings;
};
@ -98,20 +98,12 @@ struct TSpirvInstruction {
struct TSpirvTypeParameter {
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TSpirvTypeParameter(const TIntermConstantUnion* arg) { isConstant = true; constant = arg; }
TSpirvTypeParameter(const TType* arg) { isConstant = false; type = arg; }
TSpirvTypeParameter(const TIntermConstantUnion* arg) { constant = arg; }
bool operator==(const TSpirvTypeParameter& rhs) const
{
return isConstant == rhs.isConstant && ((isConstant && constant == rhs.constant) || (!isConstant && type == rhs.type));
}
bool operator==(const TSpirvTypeParameter& rhs) const { return constant == rhs.constant; }
bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }
bool isConstant;
union {
const TIntermConstantUnion* constant;
const TType* type;
};
const TIntermConstantUnion* constant;
};
typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;

View file

@ -741,6 +741,16 @@ public:
}
}
bool isUniform() const
{
switch (storage) {
case EvqUniform:
return true;
default:
return false;
}
}
bool isIo() const
{
switch (storage) {
@ -2459,6 +2469,14 @@ public:
if (*(*structure)[li].type != *(*right.structure)[ri].type)
return false;
} else {
// Skip hidden members
if ((*structure)[li].type->hiddenMember()) {
ri--;
continue;
} else if ((*right.structure)[ri].type->hiddenMember()) {
li--;
continue;
}
// If one of the members is something that's inconsistently declared, skip over it
// for now.
if (isGLPerVertex) {
@ -2475,10 +2493,10 @@ public:
}
// If we get here, then there should only be inconsistently declared members left
} else if (li < structure->size()) {
if (!isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName()))
if (!(*structure)[li].type->hiddenMember() && !isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName()))
return false;
} else {
if (!isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName()))
if (!(*right.structure)[ri].type->hiddenMember() && !isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName()))
return false;
}
}

View file

@ -926,6 +926,7 @@ enum TOperator {
EOpMul32x16,
EOpTraceNV,
EOpTraceRayMotionNV,
EOpTraceKHR,
EOpReportIntersection,
EOpIgnoreIntersectionNV,
@ -1642,6 +1643,7 @@ public:
~TIntermAggregate() { delete pragmaTable; }
virtual TIntermAggregate* getAsAggregate() { return this; }
virtual const TIntermAggregate* getAsAggregate() const { return this; }
virtual void updatePrecision();
virtual void setOperator(TOperator o) { op = o; }
virtual TIntermSequence& getSequence() { return sequence; }
virtual const TIntermSequence& getSequence() const { return sequence; }

View file

@ -46,35 +46,6 @@ namespace {
using namespace glslang;
typedef union {
double d;
int i[2];
} DoubleIntUnion;
// Some helper functions
bool isNan(double x)
{
DoubleIntUnion u;
// tough to find a platform independent library function, do it directly
u.d = x;
int bitPatternL = u.i[0];
int bitPatternH = u.i[1];
return (bitPatternH & 0x7ff80000) == 0x7ff80000 &&
((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0);
}
bool isInf(double x)
{
DoubleIntUnion u;
// tough to find a platform independent library function, do it directly
u.d = x;
int bitPatternL = u.i[0];
int bitPatternH = u.i[1];
return (bitPatternH & 0x7ff00000) == 0x7ff00000 &&
(bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0;
}
const double pi = 3.1415926535897932384626433832795;
} // end anonymous namespace
@ -531,7 +502,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
// Note: avoid UBSAN error regarding negating 0x80000000
case EbtInt: newConstArray[i].setIConst(
unionArray[i].getIConst() == 0x80000000
static_cast<unsigned int>(unionArray[i].getIConst()) == 0x80000000
? -0x7FFFFFFF - 1
: -unionArray[i].getIConst());
break;
@ -663,12 +634,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EOpIsNan:
{
newConstArray[i].setBConst(isNan(unionArray[i].getDConst()));
newConstArray[i].setBConst(IsNan(unionArray[i].getDConst()));
break;
}
case EOpIsInf:
{
newConstArray[i].setBConst(isInf(unionArray[i].getDConst()));
newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst()));
break;
}

View file

@ -3,7 +3,7 @@
// Copyright (C) 2012-2016 LunarG, Inc.
// Copyright (C) 2015-2020 Google, Inc.
// Copyright (C) 2017 ARM Limited.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
// Modifications Copyright (C) 2020-2021 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
@ -1865,6 +1865,22 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
}
if (profile != EEsProfile && version == 450) {
commonBuiltins.append(
"uint atomicCounterAddARB(atomic_uint, uint);"
"uint atomicCounterSubtractARB(atomic_uint, uint);"
"uint atomicCounterMinARB(atomic_uint, uint);"
"uint atomicCounterMaxARB(atomic_uint, uint);"
"uint atomicCounterAndARB(atomic_uint, uint);"
"uint atomicCounterOrARB(atomic_uint, uint);"
"uint atomicCounterXorARB(atomic_uint, uint);"
"uint atomicCounterExchangeARB(atomic_uint, uint);"
"uint atomicCounterCompSwapARB(atomic_uint, uint, uint);"
"\n");
}
if (profile != EEsProfile && version >= 460) {
commonBuiltins.append(
"uint atomicCounterAdd(atomic_uint, uint);"
@ -4144,106 +4160,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"u16vec4 unpack16(uint64_t);"
"i32vec2 unpack32(int64_t);"
"u32vec2 unpack32(uint64_t);"
"float64_t radians(float64_t);"
"f64vec2 radians(f64vec2);"
"f64vec3 radians(f64vec3);"
"f64vec4 radians(f64vec4);"
"float64_t degrees(float64_t);"
"f64vec2 degrees(f64vec2);"
"f64vec3 degrees(f64vec3);"
"f64vec4 degrees(f64vec4);"
"float64_t sin(float64_t);"
"f64vec2 sin(f64vec2);"
"f64vec3 sin(f64vec3);"
"f64vec4 sin(f64vec4);"
"float64_t cos(float64_t);"
"f64vec2 cos(f64vec2);"
"f64vec3 cos(f64vec3);"
"f64vec4 cos(f64vec4);"
"float64_t tan(float64_t);"
"f64vec2 tan(f64vec2);"
"f64vec3 tan(f64vec3);"
"f64vec4 tan(f64vec4);"
"float64_t asin(float64_t);"
"f64vec2 asin(f64vec2);"
"f64vec3 asin(f64vec3);"
"f64vec4 asin(f64vec4);"
"float64_t acos(float64_t);"
"f64vec2 acos(f64vec2);"
"f64vec3 acos(f64vec3);"
"f64vec4 acos(f64vec4);"
"float64_t atan(float64_t, float64_t);"
"f64vec2 atan(f64vec2, f64vec2);"
"f64vec3 atan(f64vec3, f64vec3);"
"f64vec4 atan(f64vec4, f64vec4);"
"float64_t atan(float64_t);"
"f64vec2 atan(f64vec2);"
"f64vec3 atan(f64vec3);"
"f64vec4 atan(f64vec4);"
"float64_t sinh(float64_t);"
"f64vec2 sinh(f64vec2);"
"f64vec3 sinh(f64vec3);"
"f64vec4 sinh(f64vec4);"
"float64_t cosh(float64_t);"
"f64vec2 cosh(f64vec2);"
"f64vec3 cosh(f64vec3);"
"f64vec4 cosh(f64vec4);"
"float64_t tanh(float64_t);"
"f64vec2 tanh(f64vec2);"
"f64vec3 tanh(f64vec3);"
"f64vec4 tanh(f64vec4);"
"float64_t asinh(float64_t);"
"f64vec2 asinh(f64vec2);"
"f64vec3 asinh(f64vec3);"
"f64vec4 asinh(f64vec4);"
"float64_t acosh(float64_t);"
"f64vec2 acosh(f64vec2);"
"f64vec3 acosh(f64vec3);"
"f64vec4 acosh(f64vec4);"
"float64_t atanh(float64_t);"
"f64vec2 atanh(f64vec2);"
"f64vec3 atanh(f64vec3);"
"f64vec4 atanh(f64vec4);"
"float64_t pow(float64_t, float64_t);"
"f64vec2 pow(f64vec2, f64vec2);"
"f64vec3 pow(f64vec3, f64vec3);"
"f64vec4 pow(f64vec4, f64vec4);"
"float64_t exp(float64_t);"
"f64vec2 exp(f64vec2);"
"f64vec3 exp(f64vec3);"
"f64vec4 exp(f64vec4);"
"float64_t log(float64_t);"
"f64vec2 log(f64vec2);"
"f64vec3 log(f64vec3);"
"f64vec4 log(f64vec4);"
"float64_t exp2(float64_t);"
"f64vec2 exp2(f64vec2);"
"f64vec3 exp2(f64vec3);"
"f64vec4 exp2(f64vec4);"
"float64_t log2(float64_t);"
"f64vec2 log2(f64vec2);"
"f64vec3 log2(f64vec3);"
"f64vec4 log2(f64vec4);"
"\n");
}
@ -4638,7 +4554,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
}
// GL_ARB_shader_clock & GL_EXT_shader_realtime_clock
// GL_ARB_shader_clock& GL_EXT_shader_realtime_clock
if (profile != EEsProfile && version >= 450) {
commonBuiltins.append(
"uvec2 clock2x32ARB();"
@ -4662,7 +4578,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
}
// Builtins for GL_NV_ray_tracing/GL_EXT_ray_tracing/GL_EXT_ray_query
// Builtins for GL_NV_ray_tracing/GL_NV_ray_tracing_motion_blur/GL_EXT_ray_tracing/GL_EXT_ray_query
if (profile != EEsProfile && version >= 460) {
commonBuiltins.append("void rayQueryInitializeEXT(rayQueryEXT, accelerationStructureEXT, uint, uint, vec3, float, vec3, float);"
"void rayQueryTerminateEXT(rayQueryEXT);"
@ -4691,6 +4607,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangRayGen].append(
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void executeCallableNV(uint, int);"
"void executeCallableEXT(uint, int);"
@ -4705,12 +4622,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
stageBuiltins[EShLangClosestHit].append(
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void executeCallableNV(uint, int);"
"void executeCallableEXT(uint, int);"
"\n");
stageBuiltins[EShLangMiss].append(
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void executeCallableNV(uint, int);"
"void executeCallableEXT(uint, int);"
@ -5156,9 +5075,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
);
}
if (version >= 450)
if (version >= 430)
stageBuiltins[EShLangVertex].append(
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
);
if (version >= 450)
stageBuiltins[EShLangVertex].append(
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
@ -5294,9 +5217,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in int gl_InvocationID;"
);
if (version >= 450)
if (version >= 430)
stageBuiltins[EShLangGeometry].append(
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
);
if (version >= 450)
stageBuiltins[EShLangGeometry].append(
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
@ -5372,7 +5299,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
if (version >= 450)
stageBuiltins[EShLangTessControl].append(
"float gl_CullDistance[];"
);
if (version >= 430)
stageBuiltins[EShLangTessControl].append(
"int gl_ViewportMask[];" // GL_NV_viewport_array2
);
if (version >= 450)
stageBuiltins[EShLangTessControl].append(
"vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
"int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
"vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
@ -5475,9 +5408,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"out int gl_Layer;"
"\n");
if (version >= 450)
if (version >= 430)
stageBuiltins[EShLangTessEvaluation].append(
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
);
if (version >= 450)
stageBuiltins[EShLangTessEvaluation].append(
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
@ -5919,6 +5856,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in mat3x4 gl_WorldToObject3x4EXT;"
"in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;"
"in float gl_CurrentRayTimeNV;"
"\n";
const char *hitDecls =
"in uvec3 gl_LaunchIDNV;"
@ -5954,6 +5892,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in mat3x4 gl_WorldToObject3x4EXT;"
"in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;"
"in float gl_CurrentRayTimeNV;"
"\n";
const char *missDecls =
"in uvec3 gl_LaunchIDNV;"
@ -5972,6 +5911,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in float gl_RayTmaxEXT;"
"in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;"
"in float gl_CurrentRayTimeNV;"
"\n";
const char *callableDecls =
@ -7686,6 +7626,11 @@ static void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolT
symQualifier.builtIn = builtIn;
}
static void RetargetVariable(const char* from, const char* to, TSymbolTable& symbolTable)
{
symbolTable.retargetSymbol(from, to);
}
//
// For built-in variables inside a named block.
// SpecialQualifier() won't ever go inside a block; their member's qualifier come
@ -7753,8 +7698,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
// treat these built-ins as aliases of VertexIndex and InstanceIndex
BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable);
BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable);
RetargetVariable("gl_InstanceID", "gl_InstanceIndex", symbolTable);
RetargetVariable("gl_VertexID", "gl_VertexIndex", symbolTable);
}
if (profile != EEsProfile) {
@ -8268,6 +8213,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("atomicCounter" , 1, &E_GL_ARB_shader_atomic_counters);
}
// E_GL_ARB_shader_atomic_counter_ops
if (profile != EEsProfile && version == 450) {
symbolTable.setFunctionExtensions("atomicCounterAddARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterSubtractARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterMinARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterMaxARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterAndARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterOrARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterXorARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterExchangeARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterCompSwapARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
}
// E_GL_ARB_derivative_control
if (profile != EEsProfile && version < 450) {
symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_ARB_derivative_control);
@ -8375,7 +8333,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("clockARB", 1, &E_GL_ARB_shader_clock);
symbolTable.setFunctionExtensions("clock2x32ARB", 1, &E_GL_ARB_shader_clock);
symbolTable.setFunctionExtensions("clockRealtimeEXT", 1, &E_GL_EXT_shader_realtime_clock);
symbolTable.setFunctionExtensions("clockRealtimeEXT", 1, &E_GL_EXT_shader_realtime_clock);
symbolTable.setFunctionExtensions("clockRealtime2x32EXT", 1, &E_GL_EXT_shader_realtime_clock);
if (profile == EEsProfile && version < 320) {
@ -8796,11 +8754,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setVariableExtensions("gl_WorldToObject3x4EXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setVariableExtensions("gl_IncomingRayFlagsNV", 1, &E_GL_NV_ray_tracing);
symbolTable.setVariableExtensions("gl_IncomingRayFlagsEXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setVariableExtensions("gl_CurrentRayTimeNV", 1, &E_GL_NV_ray_tracing_motion_blur);
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
symbolTable.setFunctionExtensions("traceNV", 1, &E_GL_NV_ray_tracing);
symbolTable.setFunctionExtensions("traceRayMotionNV", 1, &E_GL_NV_ray_tracing_motion_blur);
symbolTable.setFunctionExtensions("traceRayEXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setFunctionExtensions("reportIntersectionNV", 1, &E_GL_NV_ray_tracing);
symbolTable.setFunctionExtensions("reportIntersectionEXT", 1, &E_GL_EXT_ray_tracing);
@ -8844,6 +8804,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
BuiltInVariable("gl_IncomingRayFlagsNV", EbvIncomingRayFlags, symbolTable);
BuiltInVariable("gl_IncomingRayFlagsEXT", EbvIncomingRayFlags, symbolTable);
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
BuiltInVariable("gl_CurrentRayTimeNV", EbvCurrentRayTimeNV, symbolTable);
// GL_ARB_shader_ballot
symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot);
@ -9268,6 +9229,18 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("clockRealtimeEXT", EOpReadClockDeviceKHR);
symbolTable.relateToOperator("clockRealtime2x32EXT", EOpReadClockDeviceKHR);
if (profile != EEsProfile && version == 450) {
symbolTable.relateToOperator("atomicCounterAddARB", EOpAtomicCounterAdd);
symbolTable.relateToOperator("atomicCounterSubtractARB", EOpAtomicCounterSubtract);
symbolTable.relateToOperator("atomicCounterMinARB", EOpAtomicCounterMin);
symbolTable.relateToOperator("atomicCounterMaxARB", EOpAtomicCounterMax);
symbolTable.relateToOperator("atomicCounterAndARB", EOpAtomicCounterAnd);
symbolTable.relateToOperator("atomicCounterOrARB", EOpAtomicCounterOr);
symbolTable.relateToOperator("atomicCounterXorARB", EOpAtomicCounterXor);
symbolTable.relateToOperator("atomicCounterExchangeARB", EOpAtomicCounterExchange);
symbolTable.relateToOperator("atomicCounterCompSwapARB", EOpAtomicCounterCompSwap);
}
if (profile != EEsProfile && version >= 460) {
symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicCounterAdd);
symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicCounterSubtract);
@ -9675,6 +9648,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
case EShLangMiss:
if (profile != EEsProfile && version >= 460) {
symbolTable.relateToOperator("traceNV", EOpTraceNV);
symbolTable.relateToOperator("traceRayMotionNV", EOpTraceRayMotionNV);
symbolTable.relateToOperator("traceRayEXT", EOpTraceKHR);
symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV);
symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR);

View file

@ -416,20 +416,24 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
// TODO: but, did this bypass constant folding?
//
switch (op) {
case EOpConstructInt8:
case EOpConstructUint8:
case EOpConstructInt16:
case EOpConstructUint16:
case EOpConstructInt:
case EOpConstructUint:
case EOpConstructInt64:
case EOpConstructUint64:
case EOpConstructBool:
case EOpConstructFloat:
case EOpConstructDouble:
case EOpConstructFloat16:
return child;
default: break; // some compilers want this
case EOpConstructInt8:
case EOpConstructUint8:
case EOpConstructInt16:
case EOpConstructUint16:
case EOpConstructInt:
case EOpConstructUint:
case EOpConstructInt64:
case EOpConstructUint64:
case EOpConstructBool:
case EOpConstructFloat:
case EOpConstructDouble:
case EOpConstructFloat16: {
TIntermUnary* unary_node = child->getAsUnaryNode();
if (unary_node != nullptr)
unary_node->updatePrecision();
return child;
}
default: break; // some compilers want this
}
//
@ -3776,6 +3780,28 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
return false;
}
// Propagate precision qualifiers *up* from children to parent, and then
// back *down* again to the children's subtrees.
void TIntermAggregate::updatePrecision()
{
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
TPrecisionQualifier maxPrecision = EpqNone;
TIntermSequence operands = getSequence();
for (unsigned int i = 0; i < operands.size(); ++i) {
TIntermTyped* typedNode = operands[i]->getAsTyped();
assert(typedNode);
maxPrecision = std::max(maxPrecision, typedNode->getQualifier().precision);
}
getQualifier().precision = maxPrecision;
for (unsigned int i = 0; i < operands.size(); ++i) {
TIntermTyped* typedNode = operands[i]->getAsTyped();
assert(typedNode);
typedNode->propagatePrecision(maxPrecision);
}
}
}
// Propagate precision qualifiers *up* from children to parent, and then
// back *down* again to the children's subtrees.
void TIntermBinary::updatePrecision()
@ -3876,7 +3902,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
case EbtFloat: PROMOTE(setDConst, double, Get); break; \
case EbtDouble: PROMOTE(setDConst, double, Get); break; \
case EbtInt8: PROMOTE(setI8Const, char, Get); break; \
case EbtInt8: PROMOTE(setI8Const, signed char, Get); break; \
case EbtInt16: PROMOTE(setI16Const, short, Get); break; \
case EbtInt: PROMOTE(setIConst, int, Get); break; \
case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \

View file

@ -622,6 +622,19 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding;
globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet;
// Check for declarations of this default uniform that already exist due to other compilation units.
TSymbol* symbol = symbolTable.find(memberName);
if (symbol) {
if (memberType != symbol->getType()) {
TString err;
err += "\"" + memberType.getCompleteString() + "\"";
err += " versus ";
err += "\"" + symbol->getType().getCompleteString() + "\"";
error(loc, "Types must match:", memberType.getFieldName().c_str(), err.c_str());
}
return;
}
// Add the requested member as a member to the global block.
TType* type = new TType;
type->shallowCopy(memberType);

View file

@ -327,6 +327,16 @@ void TParseContext::setAtomicCounterBlockDefaults(TType& block) const
block.getQualifier().layoutMatrix = ElmRowMajor;
}
void TParseContext::setInvariant(const TSourceLoc& loc, const char* builtin) {
TSymbol* symbol = symbolTable.find(builtin);
if (symbol && symbol->getType().getQualifier().isPipeOutput()) {
if (intermediate.inIoAccessed(builtin))
warn(loc, "changing qualification after use", "invariant", builtin);
TSymbol* csymbol = symbolTable.copyUp(symbol);
csymbol->getWritableType().getQualifier().invariant = true;
}
}
void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
{
#ifndef GLSLANG_WEB
@ -404,8 +414,33 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
intermediate.setUseVariablePointers();
} else if (tokens[0].compare("once") == 0) {
warn(loc, "not implemented", "#pragma once", "");
} else if (tokens[0].compare("glslang_binary_double_output") == 0)
} else if (tokens[0].compare("glslang_binary_double_output") == 0) {
intermediate.setBinaryDoubleOutput();
} else if (spvVersion.spv > 0 && tokens[0].compare("STDGL") == 0 &&
tokens[1].compare("invariant") == 0 && tokens[3].compare("all") == 0) {
intermediate.setInvariantAll();
// Set all builtin out variables invariant if declared
setInvariant(loc, "gl_Position");
setInvariant(loc, "gl_PointSize");
setInvariant(loc, "gl_ClipDistance");
setInvariant(loc, "gl_CullDistance");
setInvariant(loc, "gl_TessLevelOuter");
setInvariant(loc, "gl_TessLevelInner");
setInvariant(loc, "gl_PrimitiveID");
setInvariant(loc, "gl_Layer");
setInvariant(loc, "gl_ViewportIndex");
setInvariant(loc, "gl_FragDepth");
setInvariant(loc, "gl_SampleMask");
setInvariant(loc, "gl_ClipVertex");
setInvariant(loc, "gl_FrontColor");
setInvariant(loc, "gl_BackColor");
setInvariant(loc, "gl_FrontSecondaryColor");
setInvariant(loc, "gl_BackSecondaryColor");
setInvariant(loc, "gl_TexCoord");
setInvariant(loc, "gl_FogFragCoord");
setInvariant(loc, "gl_FragColor");
setInvariant(loc, "gl_FragData");
}
#endif
}
@ -2273,6 +2308,10 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
if (!(*argp)[10]->getAsConstantUnion())
error(loc, "argument must be compile-time constant", "payload number", "a");
break;
case EOpTraceRayMotionNV:
if (!(*argp)[11]->getAsConstantUnion())
error(loc, "argument must be compile-time constant", "payload number", "a");
break;
case EOpTraceKHR:
if (!(*argp)[10]->getAsConstantUnion())
error(loc, "argument must be compile-time constant", "payload number", "a");
@ -2990,11 +3029,14 @@ void TParseContext::constantValueCheck(TIntermTyped* node, const char* token)
//
// Both test, and if necessary spit out an error, to see if the node is really
// an integer.
// a 32-bit integer or can implicitly convert to one.
//
void TParseContext::integerCheck(const TIntermTyped* node, const char* token)
{
if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar())
auto from_type = node->getBasicType();
if ((from_type == EbtInt || from_type == EbtUint ||
intermediate.canImplicitlyPromote(from_type, EbtInt, EOpNull) ||
intermediate.canImplicitlyPromote(from_type, EbtUint, EOpNull)) && node->isScalar())
return;
error(node->getLoc(), "scalar integer expression required", token, "");
@ -3659,6 +3701,8 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs");
profileRequires(loc, EEsProfile, 300, nullptr, "out for stage outputs");
qualifier.storage = EvqVaryingOut;
if (intermediate.isInvariantAll())
qualifier.invariant = true;
break;
case EvqInOut:
qualifier.storage = EvqVaryingIn;
@ -3675,7 +3719,7 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
if (blockName == nullptr &&
qualifier.layoutPacking == ElpStd430)
{
error(loc, "it is invalid to declare std430 qualifier on uniform", "", "");
requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "default std430 layout for uniform");
}
break;
default:
@ -6452,6 +6496,8 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
error(loc, "can only be used with a uniform", "push_constant", "");
if (qualifier.hasSet())
error(loc, "cannot be used with push_constant", "set", "");
if (qualifier.hasBinding())
error(loc, "cannot be used with push_constant", "binding", "");
}
if (qualifier.hasBufferReference()) {
if (qualifier.storage != EvqBuffer)
@ -6606,8 +6652,10 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct
: findFunctionExact(loc, call, builtIn));
else if (version < 120)
function = findFunctionExact(loc, call, builtIn);
else if (version < 400)
function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
else if (version < 400) {
bool needfindFunction400 = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) || extensionTurnedOn(E_GL_ARB_gpu_shader5);
function = needfindFunction400 ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
}
else if (explicitTypesEnabled)
function = findFunctionExplicitTypes(loc, call, builtIn);
else
@ -7650,7 +7698,13 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
return nullptr;
}
return intermediate.setAggregateOperator(aggrNode, op, type, loc);
TIntermTyped *ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc);
TIntermAggregate *agg_node = ret_node->getAsAggregate();
if (agg_node && (agg_node->isVector() || agg_node->isArray() || agg_node->isMatrix()))
agg_node->updatePrecision();
return ret_node;
}
// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
@ -9196,11 +9250,14 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre
// "it is an error to have no statement between a label and the end of the switch statement."
// The specifications were updated to remove this (being ill-defined what a "statement" was),
// so, this became a warning. However, 3.0 tests still check for the error.
if (isEsProfile() && version <= 300 && ! relaxedErrors())
if (isEsProfile() && (version <= 300 || version >= 320) && ! relaxedErrors())
error(loc, "last case/default label not followed by statements", "switch", "");
else if (!isEsProfile() && (version <= 430 || version >= 460))
error(loc, "last case/default label not followed by statements", "switch", "");
else
warn(loc, "last case/default label not followed by statements", "switch", "");
// emulate a break for error recovery
lastStatements = intermediate.makeAggregate(intermediate.addBranch(EOpBreak, loc));
lastStatements->setOperator(EOpSequence);

View file

@ -241,6 +241,7 @@ protected:
// override this to set the language-specific name
virtual const char* getAtomicCounterBlockName() const { return ""; }
virtual void setAtomicCounterBlockDefaults(TType&) const {}
virtual void setInvariant(const TSourceLoc&, const char*) {}
virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
bool isAtomicCounterBlock(const TSymbol& symbol) {
const TVariable* var = symbol.getAsVariable();
@ -471,7 +472,7 @@ public:
// Determine loop control from attributes
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
// Function attributes
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&);
// GL_EXT_spirv_intrinsics
TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
@ -479,7 +480,6 @@ public:
TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
TSpirvRequirement* spirvReq2);
TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
TSpirvTypeParameters* makeSpirvTypeParameters(const TPublicType& type);
TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
TSpirvTypeParameters* spirvTypeParams2);
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);
@ -511,6 +511,7 @@ protected:
virtual const char* getAtomicCounterBlockName() const override;
virtual void finalizeAtomicCounterBlockLayout(TVariable&) override;
virtual void setAtomicCounterBlockDefaults(TType& block) const override;
virtual void setInvariant(const TSourceLoc& loc, const char* builtin) override;
public:
//

View file

@ -1343,7 +1343,6 @@ int ShInitialize()
glslang::GetGlobalLock();
++NumberOfClients;
glslang::ReleaseGlobalLock();
if (PerProcessGPA == nullptr)
PerProcessGPA = new TPoolAllocator();
@ -1353,6 +1352,7 @@ int ShInitialize()
glslang::HlslScanContext::fillInKeywordMap();
#endif
glslang::ReleaseGlobalLock();
return 1;
}
@ -1415,9 +1415,10 @@ int ShFinalize()
--NumberOfClients;
assert(NumberOfClients >= 0);
bool finalize = NumberOfClients == 0;
glslang::ReleaseGlobalLock();
if (! finalize)
if (! finalize) {
glslang::ReleaseGlobalLock();
return 1;
}
for (int version = 0; version < VersionCount; ++version) {
for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
@ -1455,6 +1456,7 @@ int ShFinalize()
glslang::HlslScanContext::deleteKeywordMap();
#endif
glslang::ReleaseGlobalLock();
return 1;
}
@ -1827,6 +1829,7 @@ void TShader::setUniqueId(unsigned long long id)
}
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
void TShader::setDxPositionW(bool invert) { intermediate->setDxPositionW(invert); }
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
#ifndef GLSLANG_WEB

View file

@ -130,11 +130,11 @@ void TIntermediate::insertSpirvExecutionModeId(int executionMode, const TIntermA
spirvExecutionMode = new TSpirvExecutionMode;
assert(args);
TVector<const TIntermConstantUnion*> extraOperands;
TVector<const TIntermTyped*> extraOperands;
for (auto arg : args->getSequence()) {
auto extraOperand = arg->getAsConstantUnion();
assert(extraOperand != nullptr);
auto extraOperand = arg->getAsTyped();
assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant());
extraOperands.push_back(extraOperand);
}
spirvExecutionMode->modeIds[executionMode] = extraOperands;
@ -165,10 +165,10 @@ void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args
spirvDecorate = new TSpirvDecorate;
assert(args);
TVector<const TIntermConstantUnion*> extraOperands;
TVector<const TIntermTyped*> extraOperands;
for (auto arg : args->getSequence()) {
auto extraOperand = arg->getAsConstantUnion();
assert(extraOperand != nullptr);
auto extraOperand = arg->getAsTyped();
assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant());
extraOperands.push_back(extraOperand);
}
spirvDecorate->decorateIds[decoration] = extraOperands;
@ -201,25 +201,27 @@ TString TQualifier::getSpirvDecorateQualifierString() const
const auto appendBool = [&](bool b) { qualifierString.append(std::to_string(b).c_str()); };
const auto appendStr = [&](const char* s) { qualifierString.append(s); };
const auto appendDecorate = [&](const TIntermConstantUnion* constant) {
const auto appendDecorate = [&](const TIntermTyped* constant) {
auto& constArray = constant->getAsConstantUnion() != nullptr ? constant->getAsConstantUnion()->getConstArray()
: constant->getAsSymbolNode()->getConstArray();
if (constant->getBasicType() == EbtFloat) {
float value = static_cast<float>(constant->getConstArray()[0].getDConst());
float value = static_cast<float>(constArray[0].getDConst());
appendFloat(value);
}
else if (constant->getBasicType() == EbtInt) {
int value = constant->getConstArray()[0].getIConst();
int value = constArray[0].getIConst();
appendInt(value);
}
else if (constant->getBasicType() == EbtUint) {
unsigned value = constant->getConstArray()[0].getUConst();
unsigned value = constArray[0].getUConst();
appendUint(value);
}
else if (constant->getBasicType() == EbtBool) {
bool value = constant->getConstArray()[0].getBConst();
bool value = constArray[0].getBConst();
appendBool(value);
}
else if (constant->getBasicType() == EbtString) {
const TString* value = constant->getConstArray()[0].getSConst();
const TString* value = constArray[0].getSConst();
appendStr(value->c_str());
}
else
@ -290,13 +292,6 @@ TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& l
return spirvTypeParams;
}
TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TPublicType& type)
{
TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters;
spirvTypeParams->push_back(TSpirvTypeParameter(new TType(type)));
return spirvTypeParams;
}
TSpirvTypeParameters* TParseContext::mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, TSpirvTypeParameters* spirvTypeParams2)
{
// Merge SPIR-V type parameters of the second one to the first one

View file

@ -279,8 +279,14 @@ TFunction::~TFunction()
//
TSymbolTableLevel::~TSymbolTableLevel()
{
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
delete (*it).second;
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
const TString& name = it->first;
auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
[&name](const std::pair<TString, TString>& i) { return i.first == name; });
if (retargetIter == retargetedSymbols.end())
delete (*it).second;
}
delete [] defaultPrecision;
}
@ -418,6 +424,10 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
symTableLevel->anonId = anonId;
symTableLevel->thisLevel = thisLevel;
symTableLevel->retargetedSymbols.clear();
for (auto &s : retargetedSymbols) {
symTableLevel->retargetedSymbols.push_back({s.first, s.second});
}
std::vector<bool> containerCopied(anonId, false);
tLevel::const_iterator iter;
for (iter = level.begin(); iter != level.end(); ++iter) {
@ -433,8 +443,21 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
symTableLevel->insert(*container, false);
containerCopied[anon->getAnonId()] = true;
}
} else
} else {
const TString& name = iter->first;
auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
[&name](const std::pair<TString, TString>& i) { return i.first == name; });
if (retargetIter != retargetedSymbols.end())
continue;
symTableLevel->insert(*iter->second->clone(), false);
}
}
// Now point retargeted symbols to the newly created versions of them
for (auto &s : retargetedSymbols) {
TSymbol* sym = symTableLevel->find(s.second);
if (!sym)
continue;
symTableLevel->insert(s.first, sym);
}
return symTableLevel;

View file

@ -84,7 +84,7 @@ typedef TVector<const char*> TExtensionList;
class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
explicit TSymbol(const TString *n) : name(n), extensions(0), writable(true) { }
explicit TSymbol(const TString *n) : name(n), uniqueId(0), extensions(0), writable(true) { }
virtual TSymbol* clone() const = 0;
virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
@ -413,13 +413,20 @@ public:
TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
~TSymbolTableLevel();
bool insert(TSymbol& symbol, bool separateNameSpaces)
bool insert(const TString& name, TSymbol* symbol) {
return level.insert(tLevelPair(name, symbol)).second;
}
bool insert(TSymbol& symbol, bool separateNameSpaces, const TString& forcedKeyName = TString())
{
//
// returning true means symbol was added to the table with no semantic errors
//
const TString& name = symbol.getName();
if (name == "") {
if (forcedKeyName.length()) {
return level.insert(tLevelPair(forcedKeyName, &symbol)).second;
}
else if (name == "") {
symbol.getAsVariable()->setAnonId(anonId++);
// An empty name means an anonymous container, exposing its members to the external scope.
// Give it a name and insert its members in the symbol table, pointing to the container.
@ -471,6 +478,16 @@ public:
return true;
}
void retargetSymbol(const TString& from, const TString& to) {
tLevel::const_iterator fromIt = level.find(from);
tLevel::const_iterator toIt = level.find(to);
if (fromIt == level.end() || toIt == level.end())
return;
delete fromIt->second;
level[from] = toIt->second;
retargetedSymbols.push_back({from, to});
}
TSymbol* find(const TString& name) const
{
tLevel::const_iterator it = level.find(name);
@ -583,6 +600,8 @@ protected:
tLevel level; // named mappings
TPrecisionQualifier *defaultPrecision;
// pair<FromName, ToName>
TVector<std::pair<TString, TString>> retargetedSymbols;
int anonId;
bool thisLevel; // True if this level of the symbol table is a structure scope containing member function
// that are supposed to see anonymous access to member variables.
@ -788,6 +807,12 @@ public:
return symbol;
}
void retargetSymbol(const TString& from, const TString& to) {
int level = currentLevel();
table[level]->retargetSymbol(from, to);
}
// Find of a symbol that returns how many layers deep of nested
// structures-with-member-functions ('this' scopes) deep the symbol was
// found in.

View file

@ -165,7 +165,9 @@ void TParseVersions::initializeExtensionBehavior()
EShTargetLanguageVersion minSpvVersion;
} extensionData;
const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4} };
const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4},
{E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4}
};
for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) {
// Add only extensions which require > spv1.0 to save space in map
@ -198,6 +200,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_explicit_uniform_location] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_image_load_store] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_atomic_counters] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_atomic_counter_ops] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_draw_parameters] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_group_vote] = EBhDisable;
extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable;
@ -222,6 +225,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_shading_language_packing] = EBhDisable;
extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable;
extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable;
extensionBehavior[E_GL_ARB_draw_instanced] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
@ -281,6 +285,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable;
extensionBehavior[E_GL_NV_shading_rate_image] = EBhDisable;
extensionBehavior[E_GL_NV_ray_tracing] = EBhDisable;
extensionBehavior[E_GL_NV_ray_tracing_motion_blur] = EBhDisable;
extensionBehavior[E_GL_NV_fragment_shader_barycentric] = EBhDisable;
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
@ -461,6 +466,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_ARB_shader_storage_buffer_object 1\n"
"#define GL_ARB_texture_query_lod 1\n"
"#define GL_ARB_vertex_attrib_64bit 1\n"
"#define GL_ARB_draw_instanced 1\n"
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
"#define GL_EXT_shader_image_load_formatted 1\n"
"#define GL_EXT_post_depth_coverage 1\n"
@ -478,6 +484,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_debug_printf 1\n"
"#define GL_EXT_fragment_shading_rate 1\n"
"#define GL_EXT_shared_memory_block 1\n"
"#define GL_EXT_shader_integer_mix 1\n"
// GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n"
@ -518,6 +525,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_NV_shader_subgroup_partitioned 1\n"
"#define GL_NV_shading_rate_image 1\n"
"#define GL_NV_ray_tracing 1\n"
"#define GL_NV_ray_tracing_motion_blur 1\n"
"#define GL_NV_fragment_shader_barycentric 1\n"
"#define GL_NV_compute_shader_derivatives 1\n"
"#define GL_NV_shader_texture_footprint 1\n"

View file

@ -136,6 +136,7 @@ const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attri
const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location";
const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store";
const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters";
const char* const E_GL_ARB_shader_atomic_counter_ops = "GL_ARB_shader_atomic_counter_ops";
const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters";
const char* const E_GL_ARB_shader_group_vote = "GL_ARB_shader_group_vote";
const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control";
@ -160,6 +161,7 @@ const char* const E_GL_ARB_shader_storage_buffer_object = "GL_ARB_shader_storage
const char* const E_GL_ARB_shading_language_packing = "GL_ARB_shading_language_packing";
const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_lod";
const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit";
const char* const E_GL_ARB_draw_instanced = "GL_ARB_draw_instanced";
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
@ -247,6 +249,7 @@ const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_
const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned";
const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image";
const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing";
const char* const E_GL_NV_ray_tracing_motion_blur = "GL_NV_ray_tracing_motion_blur";
const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric";
const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives";
const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint";

View file

@ -347,7 +347,7 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
//
// Function attributes
//
void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes, TFunction* function)
void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes)
{
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
if (it->size() > 0) {

View file

@ -983,20 +983,20 @@ function_prototype
$$.function = $1;
$$.loc = $2.loc;
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
parseContext.handleFunctionAttributes($2.loc, *$3);
}
| attribute function_declarator RIGHT_PAREN {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$1);
}
| attribute function_declarator RIGHT_PAREN attribute {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$1);
parseContext.handleFunctionAttributes($3.loc, *$4);
}
;
@ -3926,6 +3926,7 @@ iteration_statement_nonattributed
--parseContext.controlFlowNestingLevel;
}
| DO {
parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
++parseContext.statementNestingLevel;
++parseContext.controlFlowNestingLevel;
@ -3937,6 +3938,7 @@ iteration_statement_nonattributed
parseContext.boolCheck($8.loc, $6);
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
--parseContext.loopNestingLevel;
--parseContext.statementNestingLevel;
--parseContext.controlFlowNestingLevel;
@ -4365,9 +4367,6 @@ spirv_type_parameter
: constant_expression {
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
}
| type_specifier {
$$ = parseContext.makeSpirvTypeParameters($1);
}
spirv_instruction_qualifier
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {

View file

@ -983,20 +983,20 @@ function_prototype
$$.function = $1;
$$.loc = $2.loc;
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
parseContext.handleFunctionAttributes($2.loc, *$3);
}
| attribute function_declarator RIGHT_PAREN {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$1);
}
| attribute function_declarator RIGHT_PAREN attribute {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$1);
parseContext.handleFunctionAttributes($3.loc, *$4);
}
;
@ -3926,6 +3926,7 @@ iteration_statement_nonattributed
--parseContext.controlFlowNestingLevel;
}
| DO {
parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
++parseContext.statementNestingLevel;
++parseContext.controlFlowNestingLevel;
@ -3937,6 +3938,7 @@ iteration_statement_nonattributed
parseContext.boolCheck($8.loc, $6);
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
--parseContext.loopNestingLevel;
--parseContext.statementNestingLevel;
--parseContext.controlFlowNestingLevel;
@ -4365,9 +4367,6 @@ spirv_type_parameter
: constant_expression {
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
}
| type_specifier {
$$ = parseContext.makeSpirvTypeParameters($1);
}
spirv_instruction_qualifier
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {

File diff suppressed because it is too large Load diff

View file

@ -48,37 +48,6 @@
#endif
#include <cstdint>
namespace {
bool IsInfinity(double x) {
#ifdef _MSC_VER
switch (_fpclass(x)) {
case _FPCLASS_NINF:
case _FPCLASS_PINF:
return true;
default:
return false;
}
#else
return std::isinf(x);
#endif
}
bool IsNan(double x) {
#ifdef _MSC_VER
switch (_fpclass(x)) {
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
return true;
default:
return false;
}
#else
return std::isnan(x);
#endif
}
}
namespace glslang {
@ -1089,6 +1058,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
case EOpTraceNV: out.debug << "traceNV"; break;
case EOpTraceRayMotionNV: out.debug << "traceRayMotionNV"; break;
case EOpTraceKHR: out.debug << "traceRayKHR"; break;
case EOpReportIntersection: out.debug << "reportIntersectionNV"; break;
case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break;

View file

@ -79,7 +79,7 @@ public:
target = &inputList;
else if (base->getQualifier().storage == EvqVaryingOut)
target = &outputList;
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant() && !base->getQualifier().isShaderRecord())
target = &uniformList;
// If a global is being visited, then we should also traverse it incase it's evaluation
// ends up visiting inputs we want to tag as live
@ -514,6 +514,24 @@ struct TSymbolValidater
return;
}
else {
// Deal with input/output pairs where one is a block member but the other is loose,
// e.g. with ARB_separate_shader_objects
if (type1.getBasicType() == EbtBlock &&
type1.isStruct() && !type2.isStruct()) {
// Iterate through block members tracking layout
glslang::TString name;
type1.getStruct()->begin()->type->appendMangledName(name);
if (name == mangleName2
&& type1.getQualifier().layoutLocation == type2.getQualifier().layoutLocation) return;
}
if (type2.getBasicType() == EbtBlock &&
type2.isStruct() && !type1.isStruct()) {
// Iterate through block members tracking layout
glslang::TString name;
type2.getStruct()->begin()->type->appendMangledName(name);
if (name == mangleName1
&& type1.getQualifier().layoutLocation == type2.getQualifier().layoutLocation) return;
}
TString err = "Invalid In/Out variable type : " + entKey.first;
infoSink.info.message(EPrefixInternalError, err.c_str());
hadError = true;
@ -748,7 +766,7 @@ private:
};
TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate)
: intermediate(intermediate)
: referenceIntermediate(intermediate)
, nextUniformLocation(intermediate.getUniformLocationBase())
, nextInputLocation(0)
, nextOutputLocation(0)
@ -760,17 +778,17 @@ TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate
int TDefaultIoResolverBase::getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const {
return stageIntermediates[stage] ? selectBaseBinding(stageIntermediates[stage]->getShiftBinding(res), stageIntermediates[stage]->getShiftBindingForSet(res, set))
: selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set));
: selectBaseBinding(referenceIntermediate.getShiftBinding(res), referenceIntermediate.getShiftBindingForSet(res, set));
}
const std::vector<std::string>& TDefaultIoResolverBase::getResourceSetBinding(EShLanguage stage) const {
return stageIntermediates[stage] ? stageIntermediates[stage]->getResourceSetBinding()
: intermediate.getResourceSetBinding();
: referenceIntermediate.getResourceSetBinding();
}
bool TDefaultIoResolverBase::doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }
bool TDefaultIoResolverBase::doAutoBindingMapping() const { return referenceIntermediate.getAutoMapBindings(); }
bool TDefaultIoResolverBase::doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); }
bool TDefaultIoResolverBase::doAutoLocationMapping() const { return referenceIntermediate.getAutoMapLocations(); }
TDefaultIoResolverBase::TSlotSet::iterator TDefaultIoResolverBase::findSlot(int set, int slot) {
return std::lower_bound(slots[set].begin(), slots[set].end(), slot);
@ -827,7 +845,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
}
// no locations added if already present, a built-in variable, a block, or an opaque
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) {
type.isAtomic() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@ -839,7 +857,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
return ent.newLocation = -1;
}
}
int location = intermediate.getUniformLocationOverride(name);
int location = referenceIntermediate.getUniformLocationOverride(name);
if (location != -1) {
return ent.newLocation = location;
}
@ -1024,7 +1042,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
} else {
// no locations added if already present, a built-in variable, a block, or an opaque
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) {
type.isAtomic() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@ -1037,7 +1055,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
}
}
}
int location = intermediate.getUniformLocationOverride(name.c_str());
int location = referenceIntermediate.getUniformLocationOverride(name.c_str());
if (location != -1) {
return ent.newLocation = location;
}
@ -1086,7 +1104,7 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent
const TType& type = ent.symbol->getType();
const TString& name = ent.symbol->getAccessName();
// On OpenGL arrays of opaque types take a separate binding for each element
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
int numBindings = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
TResourceType resource = getResourceType(type);
// don't need to handle uniform symbol, it will be handled in resolveUniformLocation
if (resource == EResUbo && type.getBasicType() != EbtBlock) {
@ -1095,7 +1113,7 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent
// There is no 'set' qualifier in OpenGL shading language, each resource has its own
// binding name space, so remap the 'set' to resource type which make each resource
// binding is valid from 0 to MAX_XXRESOURCE_BINDINGS
int set = intermediate.getSpv().openGl != 0 ? resource : ent.newSet;
int set = referenceIntermediate.getSpv().openGl != 0 ? resource : ent.newSet;
int resourceKey = set;
if (resource < EResCount) {
if (type.getQualifier().hasBinding()) {
@ -1223,7 +1241,7 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
const TType& type = ent.symbol->getType();
const TString& name = ent.symbol->getAccessName();
TResourceType resource = getResourceType(type);
int set = intermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent);
int set = referenceIntermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent);
int resourceKey = set;
if (type.getQualifier().hasBinding()) {
@ -1233,7 +1251,7 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
if (iter == varSlotMap.end()) {
// Reserve the slots for the ubo, ssbo and opaques who has explicit binding
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
int numBindings = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
varSlotMap[name] = binding;
reserveSlot(resourceKey, binding, numBindings);
} else {
@ -1288,7 +1306,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
const TType& type = ent.symbol->getType();
const int set = getLayoutSet(type);
// 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 = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
TResourceType resource = getResourceType(type);
if (resource < EResCount) {
if (type.getQualifier().hasBinding()) {
@ -1633,6 +1651,37 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
});
resolver->endResolve(EShLangCount);
if (autoPushConstantBlockName.length()) {
bool upgraded = false;
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (intermediates[stage] != nullptr) {
TVarLiveMap** pUniformVarMap = uniformResolve.uniformVarMap;
auto at = pUniformVarMap[stage]->find(autoPushConstantBlockName);
if (at == pUniformVarMap[stage]->end())
continue;
TQualifier& qualifier = at->second.symbol->getQualifier();
if (!qualifier.isUniform())
continue;
TType& t = at->second.symbol->getWritableType();
int size, stride;
TIntermediate::getBaseAlignment(t, size, stride, autoPushConstantBlockPacking,
qualifier.layoutMatrix == ElmRowMajor);
if (size <= int(autoPushConstantMaxSize)) {
qualifier.setBlockStorage(EbsPushConstant);
qualifier.layoutPacking = autoPushConstantBlockPacking;
upgraded = true;
}
}
}
// If it's been upgraded to push_constant, then remove it from the uniformVector
// so it doesn't get a set/binding assigned to it.
if (upgraded) {
auto at = std::find_if(uniformVector.begin(), uniformVector.end(),
[this](const TVarLivePair& p) { return p.first == autoPushConstantBlockName; });
if (at != uniformVector.end())
uniformVector.erase(at);
}
}
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (intermediates[stage] != nullptr) {
// traverse each stage, set new location to each input/output and unifom symbol, set new binding to

View file

@ -165,7 +165,7 @@ public:
protected:
TDefaultIoResolverBase(TDefaultIoResolverBase&);
TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&);
const TIntermediate& intermediate;
const TIntermediate& referenceIntermediate;
int nextUniformLocation;
int nextInputLocation;
int nextOutputLocation;
@ -291,7 +291,7 @@ public:
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
};
// I/O mapper for OpenGL
// I/O mapper for GLSL
class TGlslIoMapper : public TIoMapper {
public:
TGlslIoMapper() {
@ -301,6 +301,8 @@ public:
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
profile = ENoProfile;
version = 0;
autoPushConstantMaxSize = 128;
autoPushConstantBlockPacking = ElpStd430;
}
virtual ~TGlslIoMapper() {
for (size_t stage = 0; stage < EShLangCount; stage++) {
@ -320,6 +322,13 @@ public:
intermediates[stage] = nullptr;
}
}
// If set, the uniform block with the given name will be changed to be backed by
// push_constant if it's size is <= maxSize
void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
autoPushConstantBlockName = name;
autoPushConstantMaxSize = maxSize;
autoPushConstantBlockPacking = packing;
}
// grow the reflection stage by stage
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
bool doMap(TIoMapResolver*, TInfoSink&) override;
@ -329,6 +338,11 @@ public:
bool hadError = false;
EProfile profile;
int version;
private:
TString autoPushConstantBlockName;
unsigned int autoPushConstantMaxSize;
TLayoutPacking autoPushConstantBlockPacking;
};
} // end namespace glslang

View file

@ -312,10 +312,12 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
MERGE_TRUE(autoMapBindings);
MERGE_TRUE(autoMapLocations);
MERGE_TRUE(invertY);
MERGE_TRUE(dxPositionW);
MERGE_TRUE(flattenUniformArrays);
MERGE_TRUE(useUnknownFormat);
MERGE_TRUE(hlslOffsets);
MERGE_TRUE(useStorageBuffer);
MERGE_TRUE(invariantAll);
MERGE_TRUE(hlslIoMapping);
// TODO: sourceFile
@ -758,7 +760,10 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
auto checkName = [this, unitSymbol, &infoSink](const TString& name) {
for (unsigned int i = 0; i < unitSymbol->getType().getStruct()->size(); ++i) {
if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()) {
if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()
&& !((*unitSymbol->getType().getStruct())[i].type->getQualifier().hasLocation()
|| unitSymbol->getType().getQualifier().hasLocation())
) {
error(infoSink, "Anonymous member name used for global variable or other anonymous member: ");
infoSink.info << (*unitSymbol->getType().getStruct())[i].type->getCompleteString() << "\n";
}
@ -857,9 +862,19 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock &&
symbol.getType().getStruct() && unitSymbol.getType().getStruct() &&
symbol.getType().sameStructType(unitSymbol.getType())) {
for (unsigned int i = 0; i < symbol.getType().getStruct()->size(); ++i) {
const TQualifier& qualifier = (*symbol.getType().getStruct())[i].type->getQualifier();
const TQualifier& unitQualifier = (*unitSymbol.getType().getStruct())[i].type->getQualifier();
unsigned int li = 0;
unsigned int ri = 0;
while (li < symbol.getType().getStruct()->size() && ri < unitSymbol.getType().getStruct()->size()) {
if ((*symbol.getType().getStruct())[li].type->hiddenMember()) {
++li;
continue;
}
if ((*unitSymbol.getType().getStruct())[ri].type->hiddenMember()) {
++ri;
continue;
}
const TQualifier& qualifier = (*symbol.getType().getStruct())[li].type->getQualifier();
const TQualifier & unitQualifier = (*unitSymbol.getType().getStruct())[ri].type->getQualifier();
if (qualifier.layoutMatrix != unitQualifier.layoutMatrix ||
qualifier.layoutOffset != unitQualifier.layoutOffset ||
qualifier.layoutAlign != unitQualifier.layoutAlign ||
@ -868,6 +883,8 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
error(infoSink, "Interface block member layout qualifiers must match:");
writeTypeComparison = true;
}
++li;
++ri;
}
}
@ -953,10 +970,10 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
// current implementation only has one offset.
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation ||
(symbol.getQualifier().hasLocation() && unitSymbol.getQualifier().hasLocation() && symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation) ||
symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent ||
symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex ||
symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding ||
(symbol.getQualifier().hasBinding() && unitSymbol.getQualifier().hasBinding() && symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding) ||
(symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset))) {
error(infoSink, "Layout qualification must match:");
writeTypeComparison = true;
@ -1933,7 +1950,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
}
// rule 9
if (type.getBasicType() == EbtStruct) {
if (type.getBasicType() == EbtStruct || type.getBasicType() == EbtBlock) {
const TTypeList& memberList = *type.getStruct();
size = 0;
@ -2158,8 +2175,9 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
return type.isArray() &&
((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) ||
(language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
(language == EShLangTessControl && (type.getQualifier().storage == EvqVaryingIn || type.getQualifier().storage == EvqVaryingOut) &&
! type.getQualifier().patch) ||
(language == EShLangTessEvaluation && type.getQualifier().storage == EvqVaryingIn) ||
(language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
type.getQualifier().pervertexNV) ||
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&

View file

@ -290,7 +290,9 @@ public:
resources(TBuiltInResource{}),
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
invertY(false),
dxPositionW(false),
useStorageBuffer(false),
invariantAll(false),
nanMinMaxClamp(false),
depthReplacing(false),
uniqueId(0),
@ -459,6 +461,14 @@ public:
}
bool getInvertY() const { return invertY; }
void setDxPositionW(bool dxPosW)
{
dxPositionW = dxPosW;
if (dxPositionW)
processes.addProcess("dx-position-w");
}
bool getDxPositionW() const { return dxPositionW; }
#ifdef ENABLE_HLSL
void setSource(EShSource s) { source = s; }
EShSource getSource() const { return source; }
@ -560,6 +570,8 @@ public:
void setUseStorageBuffer() { useStorageBuffer = true; }
bool usingStorageBuffer() const { return useStorageBuffer; }
void setInvariantAll() { invariantAll = true; }
bool isInvariantAll() const { return invariantAll; }
void setDepthReplacing() { depthReplacing = true; }
bool isDepthReplacing() const { return depthReplacing; }
bool setLocalSize(int dim, int size)
@ -1067,7 +1079,9 @@ protected:
int numPushConstants;
bool recursive;
bool invertY;
bool dxPositionW;
bool useStorageBuffer;
bool invariantAll;
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
bool depthReplacing;
int localSize[3];

View file

@ -56,4 +56,4 @@ if(ENABLE_GLSLANG_INSTALL)
install(TARGETS OSDependent EXPORT OSDependentTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
endif(ENABLE_GLSLANG_INSTALL)
endif()

View file

@ -172,7 +172,7 @@ namespace {
pthread_mutex_t gMutex;
}
void InitGlobalLock()
static void InitMutex(void)
{
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
@ -180,6 +180,12 @@ void InitGlobalLock()
pthread_mutex_init(&gMutex, &mutexattr);
}
void InitGlobalLock()
{
static pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_once(&once, InitMutex);
}
void GetGlobalLock()
{
pthread_mutex_lock(&gMutex);

View file

@ -55,7 +55,7 @@ if(ENABLE_GLSLANG_JS)
if(ENABLE_EMSCRIPTEN_SINGLE_FILE)
target_link_libraries(glslang.js "-s SINGLE_FILE=1")
endif(ENABLE_EMSCRIPTEN_SINGLE_FILE)
endif()
if(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE)
target_link_libraries(glslang.js "-s ENVIRONMENT=node -s BINARYEN_ASYNC_COMPILATION=0")
@ -67,5 +67,5 @@ if(ENABLE_GLSLANG_JS)
add_custom_command(TARGET glslang.js POST_BUILD
COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/glslang.after.js >> ${CMAKE_CURRENT_BINARY_DIR}/glslang.js)
endif()
endif(EMSCRIPTEN)
endif(ENABLE_GLSLANG_JS)
endif()
endif()

View file

@ -45,10 +45,10 @@ endif()
if(WIN32)
source_group("Source" FILES ${SOURCES})
endif(WIN32)
endif()
if(ENABLE_GLSLANG_INSTALL)
install(TARGETS OSDependent EXPORT OSDependentTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
endif(ENABLE_GLSLANG_INSTALL)
endif()

View file

@ -485,6 +485,7 @@ public:
GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc);
GLSLANG_EXPORT void setUniformLocationBase(int base);
GLSLANG_EXPORT void setInvertY(bool invert);
GLSLANG_EXPORT void setDxPositionW(bool dxPosW);
#ifdef ENABLE_HLSL
GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);