Saves another 20K.
// Translate glslang profile to SPIR-V source language.
spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile)
{
+#ifdef GLSLANG_WEB
+ return spv::SourceLanguageESSL;
+#endif
+
switch (source) {
case glslang::EShSourceGlsl:
switch (profile) {
{
switch (builtIn) {
case glslang::EbvPointSize:
+#ifndef GLSLANG_WEB
// Defer adding the capability until the built-in is actually used.
if (! memberDeclaration) {
switch (glslangIntermediate->getStage()) {
break;
}
}
+#endif
return spv::BuiltInPointSize;
case glslang::EbvPosition: return spv::BuiltInPosition;
builder.setAccessChainLValue(id);
}
+#ifndef GLSLANG_WEB
// Process linkage-only nodes for any special additional interface work.
if (linkageOnly) {
if (glslangIntermediate->getHlslFunctionality1()) {
}
}
}
+#endif
}
bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
return false;
+#ifndef GLSLANG_WEB
case glslang::EOpEmitStreamVertex:
builder.createNoResultOp(spv::OpEmitStreamVertex, operand);
return false;
case glslang::EOpEndStreamPrimitive:
builder.createNoResultOp(spv::OpEndStreamPrimitive, operand);
return false;
+#endif
default:
logger->missingFunctionality("unknown glslang unary");
std::vector<std::vector<spv::Decoration>> paramDecorations; // list of decorations per parameter
glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence();
+#ifdef ENABLE_HLSL
bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() ==
glslangIntermediate->implicitThisName;
+#else
+ bool implicitThis = false;
+#endif
paramDecorations.resize(parameters.size());
for (int p = 0; p < (int)parameters.size(); ++p) {
// Intrinsics with no arguments (or no return value, and no precision).
spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId)
{
+#ifndef GLSLANG_WEB
// GLSL memory barriers use queuefamily scope in new model, device scope in old model
spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
switch (op) {
-#ifndef GLSLANG_WEB
case glslang::EOpEmitVertex:
builder.createNoResultOp(spv::OpEmitVertex);
return 0;
builder.addCapability(spv::CapabilityShaderClockKHR);
return builder.createOp(spv::OpReadClockKHR, typeId, args);
}
-#endif
default:
- logger->missingFunctionality("unknown operation with no arguments");
- return 0;
+ break;
}
+#endif
+
+ logger->missingFunctionality("unknown operation with no arguments");
+
+ return 0;
}
spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol)
// We now know we have a specialization constant to build
+#ifndef GLSLANG_WEB
// gl_WorkGroupSize is a special case until the front-end handles hierarchical specialization constants,
// even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ...
if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) {
}
return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true);
}
+#endif
// An AST node labelled as specialization constant should be a symbol node.
// Its initializer should either be a sub tree with constant nodes, or a constant union array.
// Write SPIR-V out to a text file with 32-bit hexadecimal words
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName)
{
+#ifndef GLSLANG_WEB
std::ofstream out;
out.open(baseName, std::ios::binary | std::ios::out);
if (out.fail())
out << "};";
}
out.close();
+#endif
}
//
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
+#ifndef GLSLANG_WEB
+
#include "Logger.h"
#include <algorithm>
}
} // end spv namespace
+
+#endif
\ No newline at end of file
public:
SpvBuildLogger() {}
+#ifdef GLSLANG_WEB
+ void tbdFunctionality(const std::string& f) { }
+ void missingFunctionality(const std::string& f) { }
+ void warning(const std::string& w) { }
+ void error(const std::string& e) { errors.push_back(e); }
+ std::string getAllMessages() { return ""; }
+#else
+
// Registers a TBD functionality.
void tbdFunctionality(const std::string& f);
// Registers a missing functionality.
// Returns all messages accumulated in the order of:
// TBD functionalities, missing functionalities, warnings, errors.
std::string getAllMessages() const;
+#endif
private:
SpvBuildLogger(const SpvBuildLogger&);
#include "SpvBuilder.h"
+#ifndef GLSLANG_WEB
#include "hex_float.h"
+#endif
#ifndef _WIN32
#include <cstdio>
Id Builder::makeDoubleConstant(double d, bool specConstant)
{
+#ifdef GLSLANG_WEB
+ assert(0);
+ return NoResult;
+#else
Op opcode = specConstant ? OpSpecConstant : OpConstant;
Id typeId = makeFloatType(64);
union { double db; unsigned long long ull; } u;
module.mapInstruction(c);
return c->getResultId();
+#endif
}
Id Builder::makeFloat16Constant(float f16, bool specConstant)
{
+#ifdef GLSLANG_WEB
+ assert(0);
+ return NoResult;
+#else
Op opcode = specConstant ? OpSpecConstant : OpConstant;
Id typeId = makeFloatType(16);
module.mapInstruction(c);
return c->getResultId();
+#endif
}
Id Builder::makeFpConstant(Id type, double d, bool specConstant)
#ifndef GLSLANG_SPV_TOOLS_H
#define GLSLANG_SPV_TOOLS_H
+#ifdef ENABLE_OPT
#include <vector>
#include <ostream>
+#endif
#include "../glslang/MachineIndependent/localintermediate.h"
#include "Logger.h"
bool validate;
};
-#if ENABLE_OPT
+#ifdef ENABLE_OPT
// Use the SPIRV-Tools disassembler to print SPIR-V.
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
shader->setPreamble(UserPreamble.get());
shader->addProcesses(Processes);
+#ifndef GLSLANG_WEB
// Set IO mapper binding shift values
for (int r = 0; r < glslang::EResCount; ++r) {
const glslang::TResourceType res = glslang::TResourceType(r);
i != baseBindingForSet[res][compUnit.stage].end(); ++i)
shader->setShiftBindingForSet(res, i->second, i->first);
}
-
- shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0);
- shader->setNanMinMaxClamp(NaNClamp);
shader->setResourceSetBinding(baseResourceSetBinding[compUnit.stage]);
-#ifdef ENABLE_HLSL
- if (Options & EOptionHlslIoMapping)
- shader->setHlslIoMapping(true);
-#endif
-
if (Options & EOptionAutoMapBindings)
shader->setAutoMapBindings(true);
if (Options & EOptionAutoMapLocations)
shader->setAutoMapLocations(true);
- if (Options & EOptionInvertY)
- shader->setInvertY(true);
-
for (auto& uniOverride : uniformLocationOverrides) {
shader->addUniformLocationOverride(uniOverride.first.c_str(),
uniOverride.second);
}
shader->setUniformLocationBase(uniformBase);
+#endif
+
+ shader->setNanMinMaxClamp(NaNClamp);
+
+#ifdef ENABLE_HLSL
+ shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
+ if (Options & EOptionHlslIoMapping)
+ shader->setHlslIoMapping(true);
+#endif
+
+ if (Options & EOptionInvertY)
+ shader->setInvertY(true);
// Set up the environment, some subsettings take precedence over earlier
// ways of setting things.
-812032 ../build/install/bin/glslangValidator.exe
+601088 ../build/install/bin/glslangValidator.exe
// OpModuleProcessed shift-UBO-binding 6
// OpModuleProcessed shift-ssbo-binding 3
// OpModuleProcessed shift-uav-binding 5
-// OpModuleProcessed flatten-uniform-arrays
// OpModuleProcessed no-storage-format
// OpModuleProcessed resource-set-binding t0 0 0
-// OpModuleProcessed hlsl-iomap
// OpModuleProcessed auto-map-bindings
// OpModuleProcessed auto-map-locations
+// OpModuleProcessed flatten-uniform-arrays
+// OpModuleProcessed hlsl-iomap
// OpModuleProcessed client vulkan100
// OpModuleProcessed target-env vulkan1.0
// OpModuleProcessed source-entrypoint origMain
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
-; Bound: 42
+; Bound: 33
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %_ %ps %gl_VertexIndex %gl_InstanceIndex
+ OpEntryPoint Vertex %main "main" %gl_Position %ps %gl_VertexIndex %gl_PointSize %gl_InstanceIndex
OpSource ESSL 310
OpName %main "main"
- OpName %gl_PerVertex "gl_PerVertex"
- OpMemberName %gl_PerVertex 0 "gl_Position"
- OpMemberName %gl_PerVertex 1 "gl_PointSize"
- OpName %_ ""
+ OpName %gl_Position "gl_Position"
OpName %ps "ps"
OpName %gl_VertexIndex "gl_VertexIndex"
+ OpName %gl_PointSize "gl_PointSize"
OpName %gl_InstanceIndex "gl_InstanceIndex"
- OpMemberDecorate %gl_PerVertex 0 Invariant
- OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
- OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
- OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_Position Invariant
+ OpDecorate %gl_Position BuiltIn Position
OpDecorate %ps RelaxedPrecision
OpDecorate %ps Location 0
- OpDecorate %15 RelaxedPrecision
+ OpDecorate %12 RelaxedPrecision
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
- OpDecorate %30 RelaxedPrecision
+ OpDecorate %gl_PointSize BuiltIn PointSize
+ OpDecorate %25 RelaxedPrecision
OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
-%gl_PerVertex = OpTypeStruct %v4float %float
-%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
- %_ = OpVariable %_ptr_Output_gl_PerVertex Output
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%gl_Position = OpVariable %_ptr_Output_v4float Output
%_ptr_Input_float = OpTypePointer Input %float
%ps = OpVariable %_ptr_Input_float Input
-%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %int = OpTypeInt 32 1
%int_4 = OpConstant %int 4
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
- %int_1 = OpConstant %int 1
%_ptr_Output_float = OpTypePointer Output %float
+%gl_PointSize = OpVariable %_ptr_Output_float Output
%int_5 = OpConstant %int 5
%gl_InstanceIndex = OpVariable %_ptr_Input_int Input
%main = OpFunction %void None %3
%5 = OpLabel
- %15 = OpLoad %float %ps
- %16 = OpCompositeConstruct %v4float %15 %15 %15 %15
- %18 = OpAccessChain %_ptr_Output_v4float %_ %int_0
- OpStore %18 %16
- %22 = OpLoad %int %gl_VertexIndex
- %23 = OpISub %int %int_4 %22
- %24 = OpConvertSToF %float %23
- %25 = OpAccessChain %_ptr_Output_v4float %_ %int_0
- %26 = OpLoad %v4float %25
- %27 = OpVectorTimesScalar %v4float %26 %24
- %28 = OpAccessChain %_ptr_Output_v4float %_ %int_0
- OpStore %28 %27
- %30 = OpLoad %float %ps
- %32 = OpAccessChain %_ptr_Output_float %_ %int_1
- OpStore %32 %30
- %35 = OpLoad %int %gl_InstanceIndex
- %36 = OpISub %int %int_5 %35
- %37 = OpConvertSToF %float %36
- %38 = OpAccessChain %_ptr_Output_float %_ %int_1
- %39 = OpLoad %float %38
- %40 = OpFMul %float %39 %37
- %41 = OpAccessChain %_ptr_Output_float %_ %int_1
- OpStore %41 %40
+ %12 = OpLoad %float %ps
+ %13 = OpCompositeConstruct %v4float %12 %12 %12 %12
+ OpStore %gl_Position %13
+ %18 = OpLoad %int %gl_VertexIndex
+ %19 = OpISub %int %int_4 %18
+ %20 = OpConvertSToF %float %19
+ %21 = OpLoad %v4float %gl_Position
+ %22 = OpVectorTimesScalar %v4float %21 %20
+ OpStore %gl_Position %22
+ %25 = OpLoad %float %ps
+ OpStore %gl_PointSize %25
+ %28 = OpLoad %int %gl_InstanceIndex
+ %29 = OpISub %int %int_5 %28
+ %30 = OpConvertSToF %float %29
+ %31 = OpLoad %float %gl_PointSize
+ %32 = OpFMul %float %31 %30
+ OpStore %gl_PointSize %32
OpReturn
OpFunctionEnd
layoutLocation = layoutLocationEnd;
layoutComponent = layoutComponentEnd;
layoutIndex = layoutIndexEnd;
+#ifndef GLSLANG_WEB
clearStreamLayout();
clearXfbLayout();
+#endif
}
+
+#ifndef GLSLANG_WEB
void clearStreamLayout()
{
layoutStream = layoutStreamEnd;
layoutXfbStride = layoutXfbStrideEnd;
layoutXfbOffset = layoutXfbOffsetEnd;
}
+#endif
bool hasNonXfbLayout() const
{
forEachFunction(commonBuiltins, BaseFunctions);
forEachFunction(stageBuiltins[EShLangFragment], DerivativeFunctions);
+#ifdef GLSLANG_WEB
+ return;
+#endif
+
if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450))
forEachFunction(stageBuiltins[EShLangCompute], DerivativeFunctions);
}
commonBuiltins.append(
"mediump vec2 unpackHalf2x16(highp uint);"
"\n");
- } else if (profile != EEsProfile && version >= 420) {
+ }
+#ifndef GLSLANG_WEB
+ else if (profile != EEsProfile && version >= 420) {
commonBuiltins.append(
" vec2 unpackHalf2x16(highp uint);"
"\n");
}
-#ifndef GLSLANG_WEB
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 400)) {
commonBuiltins.append(
"mediump float gl_PointSize;" // needs qualifier fixed later
);
} else {
-#endif
if (spvVersion.vulkan == 0)
stageBuiltins[EShLangVertex].append(
"in highp int gl_VertexID;" // needs qualifier fixed later
"in highp int gl_InstanceID;" // needs qualifier fixed later
);
if (spvVersion.vulkan > 0)
+#endif
stageBuiltins[EShLangVertex].append(
"in highp int gl_VertexIndex;"
"in highp int gl_InstanceIndex;"
);
+#ifndef GLSLANG_WEB
if (version < 310)
+#endif
stageBuiltins[EShLangVertex].append(
"highp vec4 gl_Position;" // needs qualifier fixed later
"highp float gl_PointSize;" // needs qualifier fixed later
);
+#ifndef GLSLANG_WEB
else
stageBuiltins[EShLangVertex].append(
"out gl_PerVertex {"
"highp float gl_PointSize;" // needs qualifier fixed later
"};"
);
-#ifndef GLSLANG_WEB
}
}
// In this function proper, enumerate the types, then calls the next set of functions
// to enumerate all the uses for that type.
//
- bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140);
- bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130);
// enumerate all the types
#ifdef GLSLANG_WEB
const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint };
const int image = 0;
+ bool skipBuffer = true;
+ bool skipCubeArrayed = true;
#else
const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, EbtFloat16 };
for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler
+ bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140);
+ bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130);
#endif
{
for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not
switch(language) {
case EShLangVertex:
+ if (spvVersion.vulkan > 0) {
+ BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable);
+ BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable);
+ }
+
#ifndef GLSLANG_WEB
+ if (spvVersion.vulkan == 0) {
+ SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable);
+ SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
+ }
+
if (profile != EEsProfile) {
if (version >= 440) {
symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters);
symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic);
symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic);
}
-#endif
-
- if (spvVersion.vulkan == 0) {
- SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable);
- SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
- }
-
- if (spvVersion.vulkan > 0) {
- BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable);
- BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable);
- }
-
-#ifndef GLSLANG_WEB
if (version >= 300 /* both ES and non-ES */) {
symbolTable.setVariableExtensions("gl_ViewID_OVR", Num_OVR_multiview_EXTs, OVR_multiview_EXTs);
BuiltInVariable("gl_ViewID_OVR", EbvViewIndex, symbolTable);
symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers);
symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers);
}
-#endif
// Fall through
case EShLangTessControl:
-
-#ifndef GLSLANG_WEB
if (profile == EEsProfile && version >= 310) {
BuiltInVariable("gl_BoundingBoxEXT", EbvBoundingBox, symbolTable);
symbolTable.setVariableExtensions("gl_BoundingBoxEXT", 1,
BuiltInVariable("gl_BoundingBox", EbvBoundingBox, symbolTable);
}
}
-#endif
// Fall through
case EShLangTessEvaluation:
case EShLangGeometry:
+#endif
SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable);
SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable);
case EbtFloat: PROMOTE(setDConst, double, Get); break; \
case EbtInt: PROMOTE(setIConst, int, Get); break; \
case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \
- case EbtBool: PROMOTE(setBConst, bool, Get); break; \
+ case EbtBool: PROMOTE_TO_BOOL(Get); break; \
default: return node; \
}
#else
globalInputDefaults.clear();
globalOutputDefaults.clear();
+#ifndef GLSLANG_WEB
// "Shaders in the transform
// feedback capturing mode have an initial global default of
// layout(xfb_buffer = 0) out;"
if (language == EShLangGeometry)
globalOutputDefaults.layoutStream = 0;
+#endif
if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main")
infoSink.info.message(EPrefixError, "Source entry point must be \"main\"");
void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
{
+#ifndef GLSLANG_WEB
if (pragmaCallback)
pragmaCallback(loc.line, tokens);
warn(loc, "not implemented", "#pragma once", "");
} else if (tokens[0].compare("glslang_binary_double_output") == 0)
intermediate.setBinaryDoubleOutput();
+#endif
}
//
// See if the operation is being done in an illegal location.
void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
{
+#ifndef GLSLANG_WEB
switch (op) {
case EOpBarrier:
if (language == EShLangTessControl) {
default:
break;
}
+#endif
}
#ifndef GLSLANG_WEB
bool errorReturn = false;
switch(binaryNode->getOp()) {
+#ifndef GLSLANG_WEB
case EOpIndexDirect:
case EOpIndexIndirect:
// ... tessellation control shader ...
error(loc, "tessellation-control per-vertex output l-value must be indexed with gl_InvocationID", "[]", "");
}
}
-
- break; // left node is checked by base class
- case EOpIndexDirectStruct:
break; // left node is checked by base class
+#endif
case EOpVectorSwizzle:
errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft());
if (!errorReturn) {
if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)
error(loc, "vertex input cannot be further qualified", "", "");
break;
-
- case EShLangTessControl:
- if (qualifier.patch)
- error(loc, "can only use on output in tessellation-control shader", "patch", "");
- break;
-
- case EShLangTessEvaluation:
- break;
-
- case EShLangGeometry:
- break;
-
case EShLangFragment:
if (publicType.userDef) {
profileRequires(loc, EEsProfile, 300, nullptr, "fragment-shader struct input");
requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array");
}
break;
-
- case EShLangCompute:
+#ifndef GLSLANG_WEB
+ case EShLangCompute:
if (! symbolTable.atBuiltInLevel())
error(loc, "global storage input qualifier cannot be used in a compute shader", "in", "");
break;
-
+ case EShLangTessControl:
+ if (qualifier.patch)
+ error(loc, "can only use on output in tessellation-control shader", "patch", "");
+ break;
+#endif
default:
break;
}
}
break;
-
- case EShLangTessControl:
- break;
-
- case EShLangTessEvaluation:
- if (qualifier.patch)
- error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
- break;
-
- case EShLangGeometry:
- break;
-
case EShLangFragment:
profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output");
if (publicType.basicType == EbtStruct) {
error(loc, "cannot contain a double, int64, or uint64", GetStorageQualifierString(qualifier.storage), "");
break;
+#ifndef GLSLANG_WEB
case EShLangCompute:
error(loc, "global storage output qualifier cannot be used in a compute shader", "out", "");
break;
-
+ case EShLangTessEvaluation:
+ if (qualifier.patch)
+ error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
+ break;
+#endif
default:
break;
}
if (symbol == nullptr)
reservedErrorCheck(loc, identifier);
-#ifndef GLSLANG_WEB
inheritGlobalDefaults(type.getQualifier());
-#endif
// Declare the variable
if (type.isArray()) {
// Pick up global defaults from the provide global defaults into dst.
void TParseContext::inheritGlobalDefaults(TQualifier& dst) const
{
+#ifndef GLSLANG_WEB
if (dst.storage == EvqVaryingOut) {
if (! dst.hasStream() && language == EShLangGeometry)
dst.layoutStream = globalOutputDefaults.layoutStream;
if (! dst.hasXfbBuffer())
dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
}
+#endif
}
//
if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.isPushConstant())
requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier");
break;
+#ifndef GLSLANG_WEB
case EvqBuffer:
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block");
if (language == EShLangFragment) {
profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block");
}
-#ifndef GLSLANG_WEB
else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) {
error(loc, "input blocks cannot be used in a mesh shader", "out", "");
}
-#endif
break;
case EvqVaryingOut:
profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block");
error(loc, "output blocks cannot be used in a task shader", "out", "");
}
break;
-#ifndef GLSLANG_WEB
case EvqPayloadNV:
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV block");
requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask),
intermediate->addProcesses(p);
}
+void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
+void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
+
+#ifndef GLSLANG_WEB
+
// Set binding base for given resource type
void TShader::setShiftBinding(TResourceType res, unsigned int base) {
intermediate->setShiftBinding(res, base);
// Enables binding automapping using TIoMapper
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
// Enables position.Y output negation in vertex shader
-void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
+
// Fragile: currently within one stage: simple auto-assignment of location
void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
void TShader::addUniformLocationOverride(const char* name, int loc)
{
intermediate->setUniformLocationBase(base);
}
-// See comment above TDefaultHlslIoMapper in iomapper.cpp:
-#ifdef ENABLE_HLSL
-void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
-#endif
-void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
-void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
+#endif
+
+#ifdef ENABLE_HLSL
+// See comment above TDefaultHlslIoMapper in iomapper.cpp:
+void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
+void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
+#endif
//
// Turn the shader strings into a parse tree in the TIntermediate.
{
switch(stage) {
case EShLangVertex: return "vertex";
+ case EShLangFragment: return "fragment";
+#ifndef GLSLANG_WEB
case EShLangTessControl: return "tessellation control";
case EShLangTessEvaluation: return "tessellation evaluation";
case EShLangGeometry: return "geometry";
- case EShLangFragment: return "fragment";
case EShLangCompute: return "compute";
case EShLangRayGenNV: return "ray-generation";
case EShLangIntersectNV: return "intersection";
case EShLangCallableNV: return "callable";
case EShLangMeshNV: return "mesh";
case EShLangTaskNV: return "task";
+#endif
default: return "unknown stage";
}
}
$$.init($1.loc);
$$.qualifier.storage = EvqUniform;
}
+GLSLANG_WEB_EXCLUDE_ON
| SHARED {
parseContext.globalCheck($1.loc, "shared");
parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
$$.init($1.loc);
$$.qualifier.storage = EvqShared;
}
-GLSLANG_WEB_EXCLUDE_ON
| BUFFER {
parseContext.globalCheck($1.loc, "buffer");
$$.init($1.loc);
$$.init($1.loc);
$$.qualifier.storage = EvqUniform;
}
+
| SHARED {
parseContext.globalCheck($1.loc, "shared");
parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
$$.init($1.loc);
$$.qualifier.storage = EvqShared;
}
-
| BUFFER {
parseContext.globalCheck($1.loc, "buffer");
$$.init($1.loc);
1143, 1170, 1179, 1186, 1194, 1201, 1208, 1216, 1226, 1233,
1244, 1250, 1253, 1260, 1264, 1268, 1277, 1287, 1290, 1301,
1304, 1307, 1311, 1315, 1320, 1324, 1331, 1335, 1340, 1346,
- 1352, 1359, 1364, 1373, 1378, 1390, 1404, 1410, 1415, 1423,
+ 1352, 1359, 1365, 1373, 1378, 1390, 1404, 1410, 1415, 1423,
1431, 1439, 1447, 1454, 1458, 1463, 1468, 1473, 1478, 1483,
1487, 1491, 1495, 1499, 1505, 1516, 1523, 1526, 1535, 1540,
1550, 1555, 1563, 1567, 1577, 1580, 1586, 1592, 1599, 1609,
break;
case 162:
-#line 1364 "MachineIndependent/glslang.y" /* yacc.c:1646 */
+#line 1365 "MachineIndependent/glslang.y" /* yacc.c:1646 */
{
parseContext.globalCheck((yyvsp[0].lex).loc, "shared");
parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
// overlap/alias/missing I/O, etc.
inOutLocationCheck(infoSink);
+#ifndef GLSLANG_WEB
// invocations
if (invocations == TQualifier::layoutNotSet)
invocations = 1;
-#ifndef GLSLANG_WEB
if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipVertex"))
error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipVertex (gl_ClipDistance is preferred)");
if (inIoAccessed("gl_CullDistance") && inIoAccessed("gl_ClipVertex"))
// So, for the case of dvec3, we need two independent ioRanges.
int collision = -1; // no collision
+#ifndef GLSLANG_WEB
if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
(qualifier.isPipeInput() || qualifier.isPipeOutput())) {
// Dealing with dvec3 in/out split across two locations.
if (collision < 0)
usedIo[set].push_back(range2);
}
- } else {
+ } else
+#endif
+ {
// Not a dvec3 in/out split across two locations, generic path.
// Need a single IO-range block.
class TIntermediate {
public:
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
- implicitThisName("@this"), implicitCounterName("@count"),
language(l),
#ifdef ENABLE_HLSL
+ implicitThisName("@this"), implicitCounterName("@count"),
source(EShSourceNone),
#endif
profile(p), version(v), treeRoot(0),
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
+ invertY(false),
+ useStorageBuffer(false),
+ nanMinMaxClamp(false),
+ depthReplacing(false)
+#ifndef GLSLANG_WEB
+ ,
+ useVulkanMemoryModel(false),
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
pixelCenterInteger(false), originUpperLeft(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
- postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
+ postDepthCoverage(false), depthLayout(EldNone),
hlslFunctionality1(false),
blendEquations(0), xfbMode(false), multiStream(false),
-#ifndef GLSLANG_WEB
layoutOverrideCoverage(false),
geoPassthroughEXT(false),
numShaderRecordNVBlocks(0),
computeDerivativeMode(LayoutDerivativeNone),
primitives(TQualifier::layoutNotSet),
numTaskNVBlocks(0),
-#endif
autoMapBindings(false),
autoMapLocations(false),
- invertY(false),
flattenUniformArrays(false),
useUnknownFormat(false),
hlslOffsets(false),
- useStorageBuffer(false),
- useVulkanMemoryModel(false),
hlslIoMapping(false),
useVariablePointers(false),
textureSamplerTransformMode(EShTexSampTransKeep),
needToLegalize(false),
binaryDoubleOutput(false),
usePhysicalStorageBuffer(false),
- uniformLocationBase(0),
- nanMinMaxClamp(false)
+ uniformLocationBase(0)
+#endif
{
+#ifndef GLSLANG_WEB
localSize[0] = 1;
localSize[1] = 1;
localSize[2] = 1;
localSizeSpecId[1] = TQualifier::layoutNotSet;
localSizeSpecId[2] = TQualifier::layoutNotSet;
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
-
shiftBinding.fill(0);
- }
- void setLimits(const TBuiltInResource& r) { resources = r; }
-
- bool postProcess(TIntermNode*, EShLanguage);
-#ifdef GLSLANG_WEB
- void output(TInfoSink&, bool tree) { }
-#else
- void output(TInfoSink&, bool tree);
-#endif
- void removeTree();
-
-#ifdef ENABLE_HLSL
- void setSource(EShSource s) { source = s; }
- EShSource getSource() const { return source; }
-#else
- void setSource(EShSource s) { assert(s == EShSourceGlsl); }
- EShSource getSource() const { return EShSourceGlsl; }
#endif
- void setEntryPointName(const char* ep)
- {
- entryPointName = ep;
- processes.addProcess("entry-point");
- processes.addArgument(entryPointName);
- }
- void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; }
- const std::string& getEntryPointName() const { return entryPointName; }
- const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
-
- void setShiftBinding(TResourceType res, unsigned int shift)
- {
- shiftBinding[res] = shift;
-
- const char* name = getResourceName(res);
- if (name != nullptr)
- processes.addIfNonZero(name, shift);
- }
-
- unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
-
- void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set)
- {
- if (shift == 0) // ignore if there's no shift: it's a no-op.
- return;
-
- shiftBindingForSet[res][set] = shift;
-
- const char* name = getResourceName(res);
- if (name != nullptr) {
- processes.addProcess(name);
- processes.addArgument(shift);
- processes.addArgument(set);
- }
- }
-
- int getShiftBindingForSet(TResourceType res, unsigned int set) const
- {
- const auto shift = shiftBindingForSet[res].find(set);
- return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
- }
- bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
-
- void setResourceSetBinding(const std::vector<std::string>& shift)
- {
- resourceSetBinding = shift;
- if (shift.size() > 0) {
- processes.addProcess("resource-set-binding");
- for (int s = 0; s < (int)shift.size(); ++s)
- processes.addArgument(shift[s]);
- }
- }
- const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
- void setAutoMapBindings(bool map)
- {
- autoMapBindings = map;
- if (autoMapBindings)
- processes.addProcess("auto-map-bindings");
- }
- bool getAutoMapBindings() const { return autoMapBindings; }
- void setAutoMapLocations(bool map)
- {
- autoMapLocations = map;
- if (autoMapLocations)
- processes.addProcess("auto-map-locations");
- }
- bool getAutoMapLocations() const { return autoMapLocations; }
- void setInvertY(bool invert)
- {
- invertY = invert;
- if (invertY)
- processes.addProcess("invert-y");
- }
- bool getInvertY() const { return invertY; }
-
- void setFlattenUniformArrays(bool flatten)
- {
- flattenUniformArrays = flatten;
- if (flattenUniformArrays)
- processes.addProcess("flatten-uniform-arrays");
- }
- bool getFlattenUniformArrays() const { return flattenUniformArrays; }
- void setNoStorageFormat(bool b)
- {
- useUnknownFormat = b;
- if (useUnknownFormat)
- processes.addProcess("no-storage-format");
- }
- bool getNoStorageFormat() const { return useUnknownFormat; }
- void setUseStorageBuffer()
- {
- useStorageBuffer = true;
- processes.addProcess("use-storage-buffer");
}
- bool usingStorageBuffer() const { return useStorageBuffer; }
- void setUseVulkanMemoryModel()
- {
- useVulkanMemoryModel = true;
- processes.addProcess("use-vulkan-memory-model");
- }
- bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
- void setUsePhysicalStorageBuffer()
- {
- usePhysicalStorageBuffer = true;
- }
- bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
- void setUseVariablePointers()
- {
- useVariablePointers = true;
- processes.addProcess("use-variable-pointers");
- }
- bool usingVariablePointers() const { return useVariablePointers; }
-
- template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
- bool hasCounterBufferName(const TString& name) const {
- size_t len = strlen(implicitCounterName);
- return name.size() > len &&
- name.compare(name.size() - len, len, implicitCounterName) == 0;
- }
-
- void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
void setVersion(int v) { version = v; }
int getVersion() const { return version; }
int getNumEntryPoints() const { return numEntryPoints; }
int getNumErrors() const { return numErrors; }
void addPushConstantCount() { ++numPushConstants; }
-#ifdef GLSLANG_WEB
- int getNumPushConstants() const { return 0; }
- void addShaderRecordNVCount() { }
- void addTaskNVCount() { }
+ void setLimits(const TBuiltInResource& r) { resources = r; }
+
+ bool postProcess(TIntermNode*, EShLanguage);
+ void removeTree();
+
+ void setEntryPointName(const char* ep)
+ {
+ entryPointName = ep;
+ processes.addProcess("entry-point");
+ processes.addArgument(entryPointName);
+ }
+ void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; }
+ const std::string& getEntryPointName() const { return entryPointName; }
+ const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
+
+ void setInvertY(bool invert)
+ {
+ invertY = invert;
+ if (invertY)
+ processes.addProcess("invert-y");
+ }
+ bool getInvertY() const { return invertY; }
+
+#ifdef ENABLE_HLSL
+ void setSource(EShSource s) { source = s; }
+ EShSource getSource() const { return source; }
#else
- int getNumPushConstants() const { return numPushConstants; }
- void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; }
- void addTaskNVCount() { ++numTaskNVBlocks; }
+ void setSource(EShSource s) { assert(s == EShSourceGlsl); }
+ EShSource getSource() const { return EShSourceGlsl; }
#endif
bool isRecursive() const { return recursive; }
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
+ void setUseStorageBuffer()
+ {
+ useStorageBuffer = true;
+ processes.addProcess("use-storage-buffer");
+ }
+ bool usingStorageBuffer() const { return useStorageBuffer; }
+ void setDepthReplacing() { depthReplacing = true; }
+ bool isDepthReplacing() const { return depthReplacing; }
+
+#ifdef GLSLANG_WEB
+ void output(TInfoSink&, bool tree) { }
+
+ bool getXfbMode() const { return false; }
+ bool isMultiStream() const { return false; }
+ TLayoutGeometry getOutputPrimitive() const { return ElgNone; }
+ bool getPostDepthCoverage() const { return false; }
+ bool getEarlyFragmentTests() const { return false; }
+ TLayoutDepth getDepth() const { return EldNone; }
+ bool getPixelCenterInteger() const { return false; }
+ void setOriginUpperLeft() { }
+ bool getOriginUpperLeft() const { return true; }
+ TInterlockOrdering getInterlockOrdering() const { return EioNone; }
+
+ bool getAutoMapBindings() const { return false; }
+ bool getAutoMapLocations() const { return false; }
+ int getNumPushConstants() const { return 0; }
+ void addShaderRecordNVCount() { }
+ void addTaskNVCount() { }
+ void setUseVulkanMemoryModel() { }
+ bool usingVulkanMemoryModel() const { return false; }
+ bool usingPhysicalStorageBuffer() const { return false; }
+ bool usingVariablePointers() const { return false; }
+#else
+ void output(TInfoSink&, bool tree);
+
+ void setShiftBinding(TResourceType res, unsigned int shift)
+ {
+ shiftBinding[res] = shift;
+
+ const char* name = getResourceName(res);
+ if (name != nullptr)
+ processes.addIfNonZero(name, shift);
+ }
+
+ unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
+
+ void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set)
+ {
+ if (shift == 0) // ignore if there's no shift: it's a no-op.
+ return;
+
+ shiftBindingForSet[res][set] = shift;
+
+ const char* name = getResourceName(res);
+ if (name != nullptr) {
+ processes.addProcess(name);
+ processes.addArgument(shift);
+ processes.addArgument(set);
+ }
+ }
+
+ int getShiftBindingForSet(TResourceType res, unsigned int set) const
+ {
+ const auto shift = shiftBindingForSet[res].find(set);
+ return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
+ }
+ bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
+
+ void setResourceSetBinding(const std::vector<std::string>& shift)
+ {
+ resourceSetBinding = shift;
+ if (shift.size() > 0) {
+ processes.addProcess("resource-set-binding");
+ for (int s = 0; s < (int)shift.size(); ++s)
+ processes.addArgument(shift[s]);
+ }
+ }
+ const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
+ void setAutoMapBindings(bool map)
+ {
+ autoMapBindings = map;
+ if (autoMapBindings)
+ processes.addProcess("auto-map-bindings");
+ }
+ bool getAutoMapBindings() const { return autoMapBindings; }
+ void setAutoMapLocations(bool map)
+ {
+ autoMapLocations = map;
+ if (autoMapLocations)
+ processes.addProcess("auto-map-locations");
+ }
+ bool getAutoMapLocations() const { return autoMapLocations; }
+
+ void setFlattenUniformArrays(bool flatten)
+ {
+ flattenUniformArrays = flatten;
+ if (flattenUniformArrays)
+ processes.addProcess("flatten-uniform-arrays");
+ }
+ bool getFlattenUniformArrays() const { return flattenUniformArrays; }
+ void setNoStorageFormat(bool b)
+ {
+ useUnknownFormat = b;
+ if (useUnknownFormat)
+ processes.addProcess("no-storage-format");
+ }
+ bool getNoStorageFormat() const { return useUnknownFormat; }
+ void setUseVulkanMemoryModel()
+ {
+ useVulkanMemoryModel = true;
+ processes.addProcess("use-vulkan-memory-model");
+ }
+ bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
+ void setUsePhysicalStorageBuffer()
+ {
+ usePhysicalStorageBuffer = true;
+ }
+ bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
+ void setUseVariablePointers()
+ {
+ useVariablePointers = true;
+ processes.addProcess("use-variable-pointers");
+ }
+ bool usingVariablePointers() const { return useVariablePointers; }
+
+ template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
+ bool hasCounterBufferName(const TString& name) const {
+ size_t len = strlen(implicitCounterName);
+ return name.size() > len &&
+ name.compare(name.size() - len, len, implicitCounterName) == 0;
+ }
+
+ void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
+ int getNumPushConstants() const { return numPushConstants; }
+ void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; }
+ void addTaskNVCount() { ++numTaskNVBlocks; }
+
bool setInvocations(int i)
{
if (invocations != TQualifier::layoutNotSet)
return true;
}
int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; }
-
void setXfbMode() { xfbMode = true; }
bool getXfbMode() const { return xfbMode; }
void setMultiStream() { multiStream = true; }
return true;
}
TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; }
- void setOriginUpperLeft() { originUpperLeft = true; }
- bool getOriginUpperLeft() const { return originUpperLeft; }
- void setPixelCenterInteger() { pixelCenterInteger = true; }
- bool getPixelCenterInteger() const { return pixelCenterInteger; }
- void setEarlyFragmentTests() { earlyFragmentTests = true; }
- bool getEarlyFragmentTests() const { return earlyFragmentTests; }
void setPostDepthCoverage() { postDepthCoverage = true; }
bool getPostDepthCoverage() const { return postDepthCoverage; }
+ void setEarlyFragmentTests() { earlyFragmentTests = true; }
+ bool getEarlyFragmentTests() const { return earlyFragmentTests; }
bool setDepth(TLayoutDepth d)
{
if (depthLayout != EldNone)
return true;
}
TLayoutDepth getDepth() const { return depthLayout; }
- void setDepthReplacing() { depthReplacing = true; }
- bool isDepthReplacing() const { return depthReplacing; }
+ void setOriginUpperLeft() { originUpperLeft = true; }
+ bool getOriginUpperLeft() const { return originUpperLeft; }
+ void setPixelCenterInteger() { pixelCenterInteger = true; }
+ bool getPixelCenterInteger() const { return pixelCenterInteger; }
+ void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
+ unsigned int getBlendEquations() const { return blendEquations; }
+ bool setXfbBufferStride(int buffer, unsigned stride)
+ {
+ if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd)
+ return xfbBuffers[buffer].stride == stride;
+ xfbBuffers[buffer].stride = stride;
+ return true;
+ }
+ unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
+ int addXfbBufferOffset(const TType&);
+ unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
+ unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const;
+ void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
+ bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
+ void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
+ bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
+ void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
+ ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
+ bool setPrimitives(int m)
+ {
+ if (primitives != TQualifier::layoutNotSet)
+ return primitives == m;
+ primitives = m;
+ return true;
+ }
+ int getPrimitives() const { return primitives; }
+ const char* addSemanticName(const TString& name)
+ {
+ return semanticNameSet.insert(name).first->c_str();
+ }
+ void addUniformLocationOverride(const char* nameStr, int location)
+ {
+ std::string name = nameStr;
+ uniformLocationOverrides[name] = location;
+ }
+
+ int getUniformLocationOverride(const char* nameStr) const
+ {
+ std::string name = nameStr;
+ auto pos = uniformLocationOverrides.find(name);
+ if (pos == uniformLocationOverrides.end())
+ return -1;
+ else
+ return pos->second;
+ }
+
+ void setUniformLocationBase(int base) { uniformLocationBase = base; }
+ int getUniformLocationBase() const { return uniformLocationBase; }
+
+ void setNeedsLegalization() { needToLegalize = true; }
+ bool needsLegalization() const { return needToLegalize; }
+
+ void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
+ bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
+#endif
#ifdef ENABLE_HLSL
void setHlslFunctionality1() { hlslFunctionality1 = true; }
bool usingHlslIoMapping() { return false; }
#endif
- void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
- unsigned int getBlendEquations() const { return blendEquations; }
-
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
void merge(TInfoSink&, TIntermediate&);
void finalCheck(TInfoSink&, bool keepUncalled);
static int computeTypeLocationSize(const TType&, EShLanguage);
static int computeTypeUniformLocationSize(const TType&);
-#ifndef GLSLANG_WEB
- bool setXfbBufferStride(int buffer, unsigned stride)
- {
- if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd)
- return xfbBuffers[buffer].stride == stride;
- xfbBuffers[buffer].stride = stride;
- return true;
- }
- unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
- int addXfbBufferOffset(const TType&);
- unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
- unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const;
-#endif
static int getBaseAlignmentScalar(const TType&, int& size);
static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);
static int getBlockSize(const TType& blockType);
static int computeBufferReferenceTypeSize(const TType&);
bool promote(TIntermOperator*);
-
-#ifndef GLSLANG_WEB
- void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
- bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
- void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
- bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
- void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
- ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
- bool setPrimitives(int m)
- {
- if (primitives != TQualifier::layoutNotSet)
- return primitives == m;
- primitives = m;
- return true;
- }
- int getPrimitives() const { return primitives; }
-#endif
-
- const char* addSemanticName(const TString& name)
- {
- return semanticNameSet.insert(name).first->c_str();
- }
+ void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; }
+ bool getNanMinMaxClamp() const { return nanMinMaxClamp; }
void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; }
const std::string& getSourceFile() const { return sourceFile; }
void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
- void addUniformLocationOverride(const char* nameStr, int location)
- {
- std::string name = nameStr;
- uniformLocationOverrides[name] = location;
- }
-
- int getUniformLocationOverride(const char* nameStr) const
- {
- std::string name = nameStr;
- auto pos = uniformLocationOverrides.find(name);
- if (pos == uniformLocationOverrides.end())
- return -1;
- else
- return pos->second;
- }
-
- void setUniformLocationBase(int base) { uniformLocationBase = base; }
- int getUniformLocationBase() const { return uniformLocationBase; }
-
- void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; }
- bool getNanMinMaxClamp() const { return nanMinMaxClamp; }
-
- void setNeedsLegalization() { needToLegalize = true; }
- bool needsLegalization() const { return needToLegalize; }
-
- void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
- bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
-
- const char* const implicitThisName;
- const char* const implicitCounterName;
-
// Certain explicit conversions are allowed conditionally
#ifdef GLSLANG_WEB
bool getArithemeticInt8Enabled() const { return false; }
bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
-#ifdef GLSLANG_WEB
- bool extensionRequested(const char *extension) const { return false; }
-#else
- // I think this function should go away.
+
+ // JohnK: I think this function should go away.
// This data structure is just a log to pass on to back ends.
// Versioning and extensions are handled in Version.cpp, with a rich
// set of functions for querying stages, versions, extension enable/disabled, etc.
+#ifdef GLSLANG_WEB
+ bool extensionRequested(const char *extension) const { return false; }
+#else
bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
#endif
+
static const char* getResourceName(TResourceType);
const EShLanguage language; // stage, known at construction time
#ifdef ENABLE_HLSL
+public:
+ const char* const implicitThisName;
+ const char* const implicitCounterName;
+protected:
EShSource source; // source language, known a bit later
#endif
std::string entryPointName;
int numErrors;
int numPushConstants;
bool recursive;
+ bool invertY;
+ bool useStorageBuffer;
+ bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
+ bool depthReplacing;
+#ifndef GLSLANG_WEB
+ bool useVulkanMemoryModel;
int invocations;
int vertices;
TLayoutGeometry inputPrimitive;
bool earlyFragmentTests;
bool postDepthCoverage;
TLayoutDepth depthLayout;
- bool depthReplacing;
bool hlslFunctionality1;
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
bool xfbMode;
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
bool multiStream;
-
-#ifndef GLSLANG_WEB
bool layoutOverrideCoverage;
bool geoPassthroughEXT;
int numShaderRecordNVBlocks;
ComputeDerivativeMode computeDerivativeMode;
int primitives;
int numTaskNVBlocks;
-#endif
// Base shift values
std::array<unsigned int, EResCount> shiftBinding;
std::vector<std::string> resourceSetBinding;
bool autoMapBindings;
bool autoMapLocations;
- bool invertY;
bool flattenUniformArrays;
bool useUnknownFormat;
bool hlslOffsets;
- bool useStorageBuffer;
- bool useVulkanMemoryModel;
bool hlslIoMapping;
bool useVariablePointers;
- std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
- std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
- std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
- std::unordered_set<int> usedConstantId; // specialization constant ids used
std::set<TString> semanticNameSet;
EShTextureSamplerTransformMode textureSamplerTransformMode;
+ bool needToLegalize;
+ bool binaryDoubleOutput;
+ bool usePhysicalStorageBuffer;
+
+ std::unordered_map<std::string, int> uniformLocationOverrides;
+ int uniformLocationBase;
+#endif
+
+ std::unordered_set<int> usedConstantId; // specialization constant ids used
+ std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
+ std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
+ // set of names of statically read/written I/O that might need extra checking
+ std::set<TString> ioAccessed;
// source code of shader, useful as part of debug information
std::string sourceFile;
std::string sourceText;
// for OpModuleProcessed, or equivalent
TProcesses processes;
- bool needToLegalize;
- bool binaryDoubleOutput;
- bool usePhysicalStorageBuffer;
-
- std::unordered_map<std::string, int> uniformLocationOverrides;
- int uniformLocationBase;
- bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
-
private:
void operator=(TIntermediate&); // prevent assignments
};