Updated glslang.

This commit is contained in:
Branimir Karadžić 2016-12-21 22:59:02 -08:00
parent afe33307da
commit 0d93dd074d
54 changed files with 1700 additions and 1099 deletions

View File

@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 2.8.11)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
option(ENABLE_AMD_EXTENSIONS "Enables support of AMD-specific extensions" ON)
option(ENABLE_GLSLANG_BINARIES "Builds glslangValidator and spirv-remap" ON)
option(ENABLE_NV_EXTENSIONS "Enables support of Nvidia-specific extensions" ON)
enable_testing()
@ -13,6 +16,10 @@ if(ENABLE_AMD_EXTENSIONS)
add_definitions(-DAMD_EXTENSIONS)
endif(ENABLE_AMD_EXTENSIONS)
if(ENABLE_NV_EXTENSIONS)
add_definitions(-DNV_EXTENSIONS)
endif(ENABLE_NV_EXTENSIONS)
if(WIN32)
set(CMAKE_DEBUG_POSTFIX "d")
include(ChooseMSVCCRT.cmake)
@ -52,7 +59,9 @@ add_subdirectory(External)
add_subdirectory(glslang)
add_subdirectory(OGLCompilersDLL)
add_subdirectory(StandAlone)
if(ENABLE_GLSLANG_BINARIES)
add_subdirectory(StandAlone)
endif()
add_subdirectory(SPIRV)
add_subdirectory(hlsl)
add_subdirectory(gtests)

View File

@ -33,6 +33,11 @@ if(ENABLE_AMD_EXTENSIONS)
GLSL.ext.AMD.h)
endif(ENABLE_AMD_EXTENSIONS)
if(ENABLE_NV_EXTENSIONS)
set(HEADERS
GLSL.ext.NV.h)
endif(ENABLE_NV_EXTENSIONS)
add_library(SPIRV STATIC ${SOURCES} ${HEADERS})
set_property(TARGET SPIRV PROPERTY FOLDER glslang)

49
3rdparty/glslang/SPIRV/GLSL.ext.NV.h vendored Normal file
View File

@ -0,0 +1,49 @@
/*
** Copyright (c) 2014-2016 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
** to deal in the Materials without restriction, including without limitation
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
** and/or sell copies of the Materials, and to permit persons to whom the
** Materials are furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Materials.
**
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
** IN THE MATERIALS.
*/
#ifndef GLSLextNV_H
#define GLSLextNV_H
enum BuiltIn;
enum Decoration;
enum Op;
static const int GLSLextNVVersion = 100;
static const int GLSLextNVRevision = 2;
//SPV_NV_sample_mask_override_coverage
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
static const Decoration OverrideCoverageNV = static_cast<Decoration>(5248);
//SPV_NV_geometry_shader_passthrough
const char* const E_SPV_NV_geometry_shader_passthrough = "SPV_NV_geometry_shader_passthrough";
static const Decoration PassthroughNV = static_cast<Decoration>(5250);
static const Capability GeometryShaderPassthroughNV = static_cast<Capability>(5251);
#endif // #ifndef GLSLextNV_H

View File

@ -47,6 +47,9 @@ namespace spv {
#ifdef AMD_EXTENSIONS
#include "GLSL.ext.AMD.h"
#endif
#ifdef NV_EXTENSIONS
#include "GLSL.ext.NV.h"
#endif
}
// Glslang includes
@ -436,6 +439,7 @@ spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qual
return spv::DecorationMax;
}
// Translate a glslang built-in variable to a SPIR-V built in decoration. Also generate
// associated capabilities when required. For some built-in variables, a capability
// is generated only when using the variable in an executable instruction, but not when
@ -4127,7 +4131,8 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op
spv::Op opCode = spv::OpNop;
std::vector<spv::Id> spvGroupOperands;
if (op == glslang::EOpBallot || op == glslang::EOpReadFirstInvocation) {
if (op == glslang::EOpBallot || op == glslang::EOpReadFirstInvocation ||
op == glslang::EOpReadInvocation) {
builder.addExtension(spv::E_SPV_KHR_shader_ballot);
builder.addCapability(spv::CapabilitySubgroupBallotKHR);
} else {
@ -4167,7 +4172,7 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op
}
case glslang::EOpReadInvocation:
opCode = spv::OpGroupBroadcast;
opCode = spv::OpSubgroupReadInvocationKHR;
if (builder.isVectorType(typeId))
return CreateInvocationsVectorOperation(opCode, typeId, operands);
break;
@ -4279,13 +4284,15 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast ||
op == spv::OpSubgroupReadInvocationKHR ||
op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD || op == spv::OpGroupSMinNonUniformAMD ||
op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD || op == spv::OpGroupSMaxNonUniformAMD ||
op == spv::OpGroupFAddNonUniformAMD || op == spv::OpGroupIAddNonUniformAMD);
#else
assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast);
op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast ||
op == spv::OpSubgroupReadInvocationKHR);
#endif
// Handle group invocation operations scalar by scalar.
@ -4305,13 +4312,16 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
std::vector<unsigned int> indexes;
indexes.push_back(comp);
spv::Id scalar = builder.createCompositeExtract(operands[0], scalarType, indexes);
std::vector<spv::Id> spvGroupOperands;
spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
if (op == spv::OpGroupBroadcast) {
if (op == spv::OpSubgroupReadInvocationKHR) {
spvGroupOperands.push_back(scalar);
spvGroupOperands.push_back(operands[1]);
} else if (op == spv::OpGroupBroadcast) {
spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
spvGroupOperands.push_back(scalar);
spvGroupOperands.push_back(operands[1]);
} else {
spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
spvGroupOperands.push_back(spv::GroupOperationReduce);
spvGroupOperands.push_back(scalar);
}
@ -4721,6 +4731,26 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
if (builtIn != spv::BuiltInMax)
addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
#ifdef NV_EXTENSIONS
if (builtIn == spv::BuiltInSampleMask) {
spv::Decoration decoration;
// GL_NV_sample_mask_override_coverage extension
if (glslangIntermediate->getLayoutOverrideCoverage())
decoration = (spv::Decoration)spv::OverrideCoverageNV;
else
decoration = (spv::Decoration)spv::DecorationMax;
addDecoration(id, decoration);
if (decoration != spv::DecorationMax) {
builder.addExtension(spv::E_SPV_NV_sample_mask_override_coverage);
}
}
if (symbol->getQualifier().layoutPassthrough) {
addDecoration(id, spv::PassthroughNV);
builder.addCapability(spv::GeometryShaderPassthroughNV);
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
}
#endif
return id;
}

View File

@ -327,12 +327,10 @@ namespace spv {
bound(maxBound); // reset header ID bound to as big as it now needs to be
}
// Mark debug instructions for stripping
void spirvbin_t::stripDebug()
{
if ((options & STRIP) == 0)
return;
// build local Id and name maps
// Strip instructions in the stripOp set: debug info.
process(
[&](spv::Op opCode, unsigned start) {
// remember opcodes we want to strip later
@ -343,6 +341,32 @@ namespace spv {
op_fn_nop);
}
// Mark instructions that refer to now-removed IDs for stripping
void spirvbin_t::stripDeadRefs()
{
process(
[&](spv::Op opCode, unsigned start) {
// strip opcodes pointing to removed data
switch (opCode) {
case spv::OpName:
case spv::OpMemberName:
case spv::OpDecorate:
case spv::OpMemberDecorate:
if (idPosR.find(asId(start+1)) == idPosR.end())
stripInst(start);
break;
default:
break; // leave it alone
}
return true;
},
op_fn_nop);
strip();
}
// Update local maps of ID, type, etc positions
void spirvbin_t::buildLocalMaps()
{
msg(2, 2, std::string("build local maps: "));
@ -351,7 +375,6 @@ namespace spv {
idMapL.clear();
// preserve nameMap, so we don't clear that.
fnPos.clear();
fnPosDCE.clear();
fnCalls.clear();
typeConstPos.clear();
idPosR.clear();
@ -366,10 +389,6 @@ namespace spv {
// build local Id and name maps
process(
[&](spv::Op opCode, unsigned start) {
// remember opcodes we want to strip later
if ((options & STRIP) && isStripOp(opCode))
stripInst(start);
unsigned word = start+1;
spv::Id typeId = spv::NoResult;
@ -957,7 +976,6 @@ namespace spv {
if (call_it == fnCalls.end() || call_it->second == 0) {
changed = true;
stripRange.push_back(fn->second);
fnPosDCE.insert(*fn);
// decrease counts of called functions
process(
@ -1011,11 +1029,15 @@ namespace spv {
// Remove single-use function variables + associated decorations and names
process(
[&](spv::Op opCode, unsigned start) {
if ((opCode == spv::OpVariable && varUseCount[asId(start+2)] == 1) ||
(opCode == spv::OpDecorate && varUseCount[asId(start+1)] == 1) ||
(opCode == spv::OpName && varUseCount[asId(start+1)] == 1)) {
stripInst(start);
}
spv::Id id = spv::NoResult;
if (opCode == spv::OpVariable)
id = asId(start+2);
if (opCode == spv::OpDecorate || opCode == spv::OpName)
id = asId(start+1);
if (id != spv::NoResult && varUseCount[id] == 1)
stripInst(start);
return true;
},
op_fn_nop);
@ -1276,25 +1298,31 @@ namespace spv {
// Set up opcode tables from SpvDoc
spv::Parameterize();
validate(); // validate header
buildLocalMaps();
validate(); // validate header
buildLocalMaps(); // build ID maps
msg(3, 4, std::string("ID bound: ") + std::to_string(bound()));
if (options & STRIP) stripDebug();
strip(); // strip out data we decided to eliminate
if (options & OPT_LOADSTORE) optLoadStore();
if (options & OPT_FWD_LS) forwardLoadStores();
if (options & DCE_FUNCS) dceFuncs();
if (options & DCE_VARS) dceVars();
if (options & DCE_TYPES) dceTypes();
strip(); // strip out data we decided to eliminate
strip(); // strip out data we decided to eliminate
stripDeadRefs(); // remove references to things we DCEed
// after the last strip, we must clean any debug info referring to now-deleted data
if (options & MAP_TYPES) mapTypeConst();
if (options & MAP_NAMES) mapNames();
if (options & MAP_FUNCS) mapFnBodies();
mapRemainder(); // map any unmapped IDs
applyMap(); // Now remap each shader to the new IDs we've come up with
if (options & MAP_ALL) {
mapRemainder(); // map any unmapped IDs
applyMap(); // Now remap each shader to the new IDs we've come up with
}
}
// remap from a memory image

View File

@ -239,7 +239,8 @@ private:
void applyMap(); // remap per local name map
void mapRemainder(); // map any IDs we haven't touched yet
void stripDebug(); // strip debug info
void stripDebug(); // strip all debug info
void stripDeadRefs(); // strips debug info for now-dead references after DCE
void strip(); // remove debug symbols
std::vector<spirword_t> spv; // SPIR words
@ -264,7 +265,6 @@ private:
// Function start and end. use unordered_map because we'll have
// many fewer functions than IDs.
std::unordered_map<spv::Id, range_t> fnPos;
std::unordered_map<spv::Id, range_t> fnPosDCE; // deleted functions
// Which functions are called, anywhere in the module, with a call count
std::unordered_map<spv::Id, int> fnCalls;

View File

@ -53,6 +53,9 @@ namespace spv {
#include "GLSL.std.450.h"
#ifdef AMD_EXTENSIONS
#include "GLSL.ext.AMD.h"
#endif
#ifdef NV_EXTENSIONS
#include "GLSL.ext.NV.h"
#endif
}
}
@ -64,6 +67,10 @@ namespace spv {
static const char* GLSLextAMDGetDebugNames(const char*, unsigned);
#endif
#ifdef NV_EXTENSIONS
static const char* GLSLextNVGetDebugNames(const char*, unsigned);
#endif
static void Kill(std::ostream& out, const char* message)
{
out << std::endl << "Disassembly failed: " << message << std::endl;
@ -75,6 +82,9 @@ enum ExtInstSet {
GLSL450Inst,
#ifdef AMD_EXTENSIONS
GLSLextAMDInst,
#endif
#ifdef NV_EXTENSIONS
GLSLextNVInst,
#endif
OpenCLExtInst,
};
@ -469,6 +479,11 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
strcmp(spv::E_SPV_AMD_gcn_shader, name) == 0) {
extInstSet = GLSLextAMDInst;
#endif
#ifdef NV_EXTENSIONS
}else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 ||
strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0) {
extInstSet = GLSLextNVInst;
#endif
}
unsigned entrypoint = stream[word - 1];
@ -479,6 +494,11 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
#ifdef AMD_EXTENSIONS
} else if (extInstSet == GLSLextAMDInst) {
out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")";
#endif
#ifdef NV_EXTENSIONS
}
else if (extInstSet == GLSLextNVInst) {
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
#endif
}
}
@ -631,6 +651,23 @@ static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint
}
#endif
#ifdef NV_EXTENSIONS
static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
{
if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 ||
strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0) {
switch (entrypoint) {
case OverrideCoverageNV: return "OverrideCoverageNV";
case PassthroughNV: return "PassthroughNV";
case GeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
default: return "Bad";
}
}
return "Bad";
}
#endif
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
{
SpirvStream SpirvStream(out, stream);

View File

@ -50,6 +50,9 @@ namespace spv {
// Include C-based headers that don't have a namespace
#ifdef AMD_EXTENSIONS
#include "GLSL.ext.AMD.h"
#endif
#ifdef NV_EXTENSIONS
#include "GLSL.ext.NV.h"
#endif
}
}
@ -255,6 +258,10 @@ const char* DecorationString(int decoration)
#ifdef AMD_EXTENSIONS
case 4999: return "ExplicitInterpAMD";
#endif
#ifdef NV_EXTENSIONS
case 5248: return "OverrideCoverageNV";
case 5250: return "PassthroughNV";
#endif
}
}
@ -812,6 +819,11 @@ const char* CapabilityString(int info)
case 4423: return "SubgroupBallotKHR";
case 4427: return "DrawParameters";
#ifdef NV_EXTENSIONS
case 5251: return "GeometryShaderPassthroughNV";
#endif
}
}
@ -1146,6 +1158,7 @@ const char* OpcodeString(int op)
case 4421: return "OpSubgroupBallotKHR";
case 4422: return "OpSubgroupFirstInvocationKHR";
case 4432: return "OpSubgroupReadInvocationKHR";
#ifdef AMD_EXTENSIONS
case 5000: return "OpGroupIAddNonUniformAMD";
@ -2758,6 +2771,10 @@ void Parameterize()
InstructionDesc[OpSubgroupFirstInvocationKHR].operands.push(OperandId, "'Value'");
InstructionDesc[OpSubgroupReadInvocationKHR].capabilities.push_back(CapabilityGroups);
InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Value'");
InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Index'");
#ifdef AMD_EXTENSIONS
InstructionDesc[OpGroupIAddNonUniformAMD].capabilities.push_back(CapabilityGroups);
InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandScope, "'Execution'");

View File

@ -905,6 +905,7 @@ enum Op {
OpImageSparseRead = 320,
OpSubgroupBallotKHR = 4421,
OpSubgroupFirstInvocationKHR = 4422,
OpSubgroupReadInvocationKHR = 4432,
OpMax = 0x7fffffff,
};

View File

@ -77,9 +77,8 @@ ERROR: 0:192: 'gl_ClipDistance' : left of '[' is not of type array, matrix, or
ERROR: 0:192: 'assign' : l-value required (can't modify a const)
ERROR: 0:195: 'gl_ModelViewMatrix' : identifiers starting with "gl_" are reserved
ERROR: 0:200: 'token pasting (##)' : not supported for this version or the enabled extensions
ERROR: 0:200: '##' : token pasting not implemented (internal error)
ERROR: 0:200: '' : syntax error
ERROR: 80 compilation errors. No code generated.
ERROR: 0:203: 'token pasting (##)' : not supported for this version or the enabled extensions
ERROR: 79 compilation errors. No code generated.
Shader version: 120
@ -427,7 +426,8 @@ ERROR: node is still EOpNull!
0:? 'c2D' (in 2-component vector of float)
0:? 'c3D' (in 3-component vector of float)
0:? 'v4' (uniform 4-component vector of float)
0:? 'abc' (global int)
0:? 'abcdef' (global int)
0:? 'qrstuv' (global int)
Linked vertex stage:
@ -499,5 +499,6 @@ ERROR: node is still EOpNull!
0:? 'c2D' (in 2-component vector of float)
0:? 'c3D' (in 3-component vector of float)
0:? 'v4' (uniform 4-component vector of float)
0:? 'abc' (global int)
0:? 'abcdef' (global int)
0:? 'qrstuv' (global int)

View File

@ -3,9 +3,7 @@ ERROR: 0:59: 'gl_InstanceID' : undeclared identifier
ERROR: 0:59: '=' : cannot convert from 'temp float' to 'temp int'
ERROR: 0:61: 'texelFetch' : no matching overloaded function found
ERROR: 0:61: 'assign' : cannot convert from 'const float' to 'temp int'
ERROR: 0:75: '##' : token pasting not implemented (internal error)
ERROR: 0:75: '' : syntax error
ERROR: 6 compilation errors. No code generated.
ERROR: 4 compilation errors. No code generated.
Shader version: 130
@ -149,7 +147,8 @@ ERROR: node is still EOpNull!
0:? 'v4' (uniform 4-component vector of float)
0:? 'gl_ClipDistance' (smooth out implicitly-sized array of float ClipDistance)
0:? 'gl_TexCoord' (smooth out implicitly-sized array of 4-component vector of float TexCoord)
0:? 'abc' (global int)
0:? 'abcdef' (global int)
0:? 'qrstuv' (global int)
0:? 'gl_VertexID' (gl_VertexId int VertexId)
@ -281,6 +280,7 @@ ERROR: node is still EOpNull!
0:? 'v4' (uniform 4-component vector of float)
0:? 'gl_ClipDistance' (smooth out 2-element array of float ClipDistance)
0:? 'gl_TexCoord' (smooth out 1-element array of 4-component vector of float TexCoord)
0:? 'abc' (global int)
0:? 'abcdef' (global int)
0:? 'qrstuv' (global int)
0:? 'gl_VertexID' (gl_VertexId int VertexId)

View File

@ -3,8 +3,9 @@ ERROR: 0:2: 'preprocessor evaluation' : bad expression
ERROR: 0:2: '#if' : unexpected tokens following directive
ERROR: 0:5: 'string' : End of line in string
ERROR: 0:5: 'macro expansion' : expected '(' following n
ERROR: 0:5: '""' : string literals not supported
ERROR: 0:5: '' : syntax error
ERROR: 5 compilation errors. No code generated.
ERROR: 6 compilation errors. No code generated.
Shader version: 100

View File

@ -12,18 +12,27 @@ gl_FragCoord origin is upper left
0:12 Function Parameters:
0:? Sequence
0:15 Sequence
0:15 move second child to first child (temp int)
0:15 'sample' (temp int)
0:15 Constant:
0:15 3 (const int)
0:15 move second child to first child (temp 4-component vector of float)
0:15 'sample' (temp 4-component vector of float)
0:? Constant:
0:? 3.000000
0:? 4.000000
0:? 5.000000
0:? 6.000000
0:17 Sequence
0:17 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:? Constant:
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:17 vector swizzle (temp 4-component vector of float)
0:17 'sample' (temp 4-component vector of float)
0:17 Sequence
0:17 Constant:
0:17 0 (const int)
0:17 Constant:
0:17 1 (const int)
0:17 Constant:
0:17 2 (const int)
0:17 Constant:
0:17 3 (const int)
0:17 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
@ -45,54 +54,67 @@ gl_FragCoord origin is upper left
0:12 Function Parameters:
0:? Sequence
0:15 Sequence
0:15 move second child to first child (temp int)
0:15 'sample' (temp int)
0:15 Constant:
0:15 3 (const int)
0:15 move second child to first child (temp 4-component vector of float)
0:15 'sample' (temp 4-component vector of float)
0:? Constant:
0:? 3.000000
0:? 4.000000
0:? 5.000000
0:? 6.000000
0:17 Sequence
0:17 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:? Constant:
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:17 vector swizzle (temp 4-component vector of float)
0:17 'sample' (temp 4-component vector of float)
0:17 Sequence
0:17 Constant:
0:17 0 (const int)
0:17 Constant:
0:17 1 (const int)
0:17 Constant:
0:17 2 (const int)
0:17 Constant:
0:17 3 (const int)
0:17 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 24
// Id's are bound by 28
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 20
EntryPoint Fragment 4 "main" 25
ExecutionMode 4 OriginUpperLeft
Name 4 "main"
Name 10 "sample(i1;"
Name 9 "x"
Name 15 "sample"
Name 20 "@entryPointOutput"
Decorate 20(@entryPointOutput) Location 0
Name 18 "sample"
Name 25 "@entryPointOutput"
Decorate 25(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
8: TypeFunction 6(int) 7(ptr)
16: 6(int) Constant 3
17: TypeFloat 32
18: TypeVector 17(float) 4
19: TypePointer Output 18(fvec4)
20(@entryPointOutput): 19(ptr) Variable Output
21: 17(float) Constant 0
22: 18(fvec4) ConstantComposite 21 21 21 21
15: TypeFloat 32
16: TypeVector 15(float) 4
17: TypePointer Function 16(fvec4)
19: 15(float) Constant 1077936128
20: 15(float) Constant 1082130432
21: 15(float) Constant 1084227584
22: 15(float) Constant 1086324736
23: 16(fvec4) ConstantComposite 19 20 21 22
24: TypePointer Output 16(fvec4)
25(@entryPointOutput): 24(ptr) Variable Output
4(main): 2 Function None 3
5: Label
15(sample): 7(ptr) Variable Function
Store 15(sample) 16
Store 20(@entryPointOutput) 22
18(sample): 17(ptr) Variable Function
Store 18(sample) 23
26: 16(fvec4) Load 18(sample)
Store 25(@entryPointOutput) 26
Return
FunctionEnd
10(sample(i1;): 6(int) Function None 8

View File

@ -3,34 +3,33 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 19
// Id's are bound by 22
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 14 16
EntryPoint Fragment 4 "main" 17 19
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
Name 9 "dead_fn("
Name 14 "outf4"
Name 16 "inf"
Name 17 "outf4"
Name 19 "inf"
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 3
8: TypeFunction 7(fvec3)
10: 6(float) Constant 0
11: 7(fvec3) ConstantComposite 10 10 10
12: TypeVector 6(float) 4
13: TypePointer Output 12(fvec4)
14(outf4): 13(ptr) Variable Output
15: TypePointer Input 6(float)
16(inf): 15(ptr) Variable Input
11: 6(float) Constant 0
12: 7(fvec3) ConstantComposite 11 11 11
15: TypeVector 6(float) 4
16: TypePointer Output 15(fvec4)
17(outf4): 16(ptr) Variable Output
18: TypePointer Input 6(float)
19(inf): 18(ptr) Variable Input
4(main): 2 Function None 3
5: Label
17: 6(float) Load 16(inf)
18: 12(fvec4) CompositeConstruct 17 17 17 17
Store 14(outf4) 18
20: 6(float) Load 19(inf)
21: 15(fvec4) CompositeConstruct 20 20 20 20
Store 17(outf4) 21
Return
FunctionEnd

View File

@ -3,18 +3,18 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 20
// Id's are bound by 22
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 15 17
EntryPoint Fragment 4 "main" 17 19
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
Name 9 "dead_fn("
Name 15 "outf4"
Name 17 "inf"
Name 17 "outf4"
Name 19 "inf"
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@ -22,16 +22,16 @@ Warning, version 450 is not yet complete; most version-specific features are pre
8: TypeFunction 7(fvec3)
11: 6(float) Constant 0
12: 7(fvec3) ConstantComposite 11 11 11
13: TypeVector 6(float) 4
14: TypePointer Output 13(fvec4)
15(outf4): 14(ptr) Variable Output
16: TypePointer Input 6(float)
17(inf): 16(ptr) Variable Input
15: TypeVector 6(float) 4
16: TypePointer Output 15(fvec4)
17(outf4): 16(ptr) Variable Output
18: TypePointer Input 6(float)
19(inf): 18(ptr) Variable Input
4(main): 2 Function None 3
5: Label
18: 6(float) Load 17(inf)
19: 13(fvec4) CompositeConstruct 18 18 18 18
Store 15(outf4) 19
20: 6(float) Load 19(inf)
21: 15(fvec4) CompositeConstruct 20 20 20 20
Store 17(outf4) 21
Return
FunctionEnd
9(dead_fn(): 7(fvec3) Function None 8

View File

@ -3,12 +3,12 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 20
// Id's are bound by 22
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 15 17
EntryPoint Fragment 4 "main" 17 19
ExecutionMode 4 OriginUpperLeft
2: TypeVoid
3: TypeFunction 2
@ -17,16 +17,16 @@ Warning, version 450 is not yet complete; most version-specific features are pre
8: TypeFunction 7(fvec3)
11: 6(float) Constant 0
12: 7(fvec3) ConstantComposite 11 11 11
13: TypeVector 6(float) 4
14: TypePointer Output 13(fvec4)
15: 14(ptr) Variable Output
16: TypePointer Input 6(float)
17: 16(ptr) Variable Input
15: TypeVector 6(float) 4
16: TypePointer Output 15(fvec4)
17: 16(ptr) Variable Output
18: TypePointer Input 6(float)
19: 18(ptr) Variable Input
4: 2 Function None 3
5: Label
18: 6(float) Load 17
19: 13(fvec4) CompositeConstruct 18 18 18 18
Store 15 19
20: 6(float) Load 19
21: 15(fvec4) CompositeConstruct 20 20 20 20
Store 17 21
Return
FunctionEnd
9: 7(fvec3) Function None 8

View File

@ -3,7 +3,7 @@ WARNING: 0:4: 'immediate sampler state' : unimplemented
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 190
// Id's are bound by 191
Capability Shader
Capability Sampled1D
@ -57,9 +57,9 @@ WARNING: 0:4: 'immediate sampler state' : unimplemented
Name 173 "psout"
Name 180 "Color"
Name 184 "Depth"
Name 187 "g_sSamp2d"
Name 188 "g_sSamp2D_b"
Name 189 "g_tTex1df4a"
Name 188 "g_sSamp2d"
Name 189 "g_sSamp2D_b"
Name 190 "g_tTex1df4a"
Decorate 41(g_tTex1df4) DescriptorSet 0
Decorate 41(g_tTex1df4) Binding 0
Decorate 45(g_sSamp) DescriptorSet 0
@ -77,10 +77,10 @@ WARNING: 0:4: 'immediate sampler state' : unimplemented
Decorate 165(g_tTexcdu4) DescriptorSet 0
Decorate 180(Color) Location 0
Decorate 184(Depth) BuiltIn FragDepth
Decorate 187(g_sSamp2d) DescriptorSet 0
Decorate 188(g_sSamp2D_b) DescriptorSet 0
Decorate 189(g_tTex1df4a) DescriptorSet 0
Decorate 189(g_tTex1df4a) Binding 1
Decorate 188(g_sSamp2d) DescriptorSet 0
Decorate 189(g_sSamp2D_b) DescriptorSet 0
Decorate 190(g_tTex1df4a) DescriptorSet 0
Decorate 190(g_tTex1df4a) Binding 1
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
@ -184,9 +184,9 @@ WARNING: 0:4: 'immediate sampler state' : unimplemented
180(Color): 179(ptr) Variable Output
183: TypePointer Output 35(float)
184(Depth): 183(ptr) Variable Output
187(g_sSamp2d): 44(ptr) Variable UniformConstant
188(g_sSamp2D_b): 44(ptr) Variable UniformConstant
189(g_tTex1df4a): 40(ptr) Variable UniformConstant
188(g_sSamp2d): 44(ptr) Variable UniformConstant
189(g_sSamp2D_b): 44(ptr) Variable UniformConstant
190(g_tTex1df4a): 40(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
9(mtest): 8(ptr) Variable Function

View File

@ -3,7 +3,7 @@ WARNING: 0:4: 'immediate sampler state' : unimplemented
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 190
// Id's are bound by 191
Capability Shader
Capability Sampled1D
@ -28,10 +28,10 @@ WARNING: 0:4: 'immediate sampler state' : unimplemented
Decorate 165 DescriptorSet 0
Decorate 180 Location 0
Decorate 184 BuiltIn FragDepth
Decorate 187 DescriptorSet 0
Decorate 188 DescriptorSet 0
Decorate 189 DescriptorSet 0
Decorate 189 Binding 1
Decorate 190 DescriptorSet 0
Decorate 190 Binding 1
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
@ -135,9 +135,9 @@ WARNING: 0:4: 'immediate sampler state' : unimplemented
180: 179(ptr) Variable Output
183: TypePointer Output 35(float)
184: 183(ptr) Variable Output
187: 44(ptr) Variable UniformConstant
188: 44(ptr) Variable UniformConstant
189: 40(ptr) Variable UniformConstant
189: 44(ptr) Variable UniformConstant
190: 40(ptr) Variable UniformConstant
4: 2 Function None 3
5: Label
9: 8(ptr) Variable Function

View File

@ -1,13 +1,13 @@
remap.hlsl.templatetypes.none.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 149
// Id's are bound by 150
Capability Shader
Capability Float64
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 146 148
EntryPoint Fragment 4 "main" 146 149
ExecutionMode 4 OriginUpperLeft
Name 4 "main"
Name 9 "r00"
@ -39,9 +39,9 @@ remap.hlsl.templatetypes.none.frag
Name 136 "r65"
Name 141 "r66"
Name 146 "@entryPointOutput"
Name 148 "input"
Name 149 "input"
Decorate 146(@entryPointOutput) Location 0
Decorate 148(input) Location 0
Decorate 149(input) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@ -157,8 +157,8 @@ remap.hlsl.templatetypes.none.frag
144: 139 ConstantComposite 72 126 142 143
145: TypePointer Output 6(float)
146(@entryPointOutput): 145(ptr) Variable Output
147: TypePointer Input 7(fvec4)
148(input): 147(ptr) Variable Input
148: TypePointer Input 7(fvec4)
149(input): 148(ptr) Variable Input
4(main): 2 Function None 3
5: Label
9(r00): 8(ptr) Variable Function

View File

@ -3,12 +3,12 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 82
// Id's are bound by 86
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 50 69 71
EntryPoint Fragment 4 "main" 53 73 75
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
@ -18,13 +18,13 @@ Warning, version 450 is not yet complete; most version-specific features are pre
Name 13 "bound"
Name 17 "r"
Name 19 "x"
Name 42 "param"
Name 50 "ini4"
Name 69 "outf4"
Name 71 "inf"
Name 74 "param"
Name 44 "param"
Name 53 "ini4"
Name 73 "outf4"
Name 75 "inf"
Name 78 "param"
Decorate 50(ini4) Flat
Name 82 "param"
Decorate 53(ini4) Flat
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
@ -37,35 +37,35 @@ Warning, version 450 is not yet complete; most version-specific features are pre
28: TypeBool
30: 8(float) Constant 1056964608
34: 6(int) Constant 1
38: 6(int) Constant 2
48: TypeVector 6(int) 4
49: TypePointer Input 48(ivec4)
50(ini4): 49(ptr) Variable Input
51: TypeInt 32 0
52: 51(int) Constant 1
53: TypePointer Input 6(int)
56: 51(int) Constant 2
61: 51(int) Constant 0
67: TypeVector 8(float) 4
68: TypePointer Output 67(fvec4)
69(outf4): 68(ptr) Variable Output
70: TypePointer Input 8(float)
71(inf): 70(ptr) Variable Input
40: 6(int) Constant 2
51: TypeVector 6(int) 4
52: TypePointer Input 51(ivec4)
53(ini4): 52(ptr) Variable Input
54: TypeInt 32 0
55: 54(int) Constant 1
56: TypePointer Input 6(int)
59: 54(int) Constant 2
64: 54(int) Constant 0
71: TypeVector 8(float) 4
72: TypePointer Output 71(fvec4)
73(outf4): 72(ptr) Variable Output
74: TypePointer Input 8(float)
75(inf): 74(ptr) Variable Input
4(main): 2 Function None 3
5: Label
74(param): 7(ptr) Variable Function
78(param): 7(ptr) Variable Function
72: 8(float) Load 71(inf)
73: 6(int) ConvertFToS 72
Store 74(param) 73
75: 8(float) FunctionCall 11(Test1(i1;) 74(param)
76: 8(float) Load 71(inf)
82(param): 7(ptr) Variable Function
76: 8(float) Load 75(inf)
77: 6(int) ConvertFToS 76
Store 78(param) 77
79: 8(float) FunctionCall 14(Test2(i1;) 78(param)
80: 8(float) FAdd 75 79
81: 67(fvec4) CompositeConstruct 80 80 80 80
Store 69(outf4) 81
79: 8(float) FunctionCall 11(Test1(i1;) 78(param)
80: 8(float) Load 75(inf)
81: 6(int) ConvertFToS 80
Store 82(param) 81
83: 8(float) FunctionCall 14(Test2(i1;) 82(param)
84: 8(float) FAdd 79 83
85: 71(fvec4) CompositeConstruct 84 84 84 84
Store 73(outf4) 85
Return
FunctionEnd
11(Test1(i1;): 8(float) Function None 9
@ -101,31 +101,31 @@ Warning, version 450 is not yet complete; most version-specific features are pre
14(Test2(i1;): 8(float) Function None 9
13(bound): 7(ptr) FunctionParameter
15: Label
42(param): 7(ptr) Variable Function
37: 6(int) Load 13(bound)
39: 28(bool) SGreaterThan 37 38
SelectionMerge 41 None
BranchConditional 39 40 45
40: Label
43: 6(int) Load 13(bound)
Store 42(param) 43
44: 8(float) FunctionCall 11(Test1(i1;) 42(param)
ReturnValue 44
45: Label
46: 6(int) Load 13(bound)
47: 6(int) IMul 46 38
54: 53(ptr) AccessChain 50(ini4) 52
55: 6(int) Load 54
57: 53(ptr) AccessChain 50(ini4) 56
44(param): 7(ptr) Variable Function
39: 6(int) Load 13(bound)
41: 28(bool) SGreaterThan 39 40
SelectionMerge 43 None
BranchConditional 41 42 48
42: Label
45: 6(int) Load 13(bound)
Store 44(param) 45
46: 8(float) FunctionCall 11(Test1(i1;) 44(param)
ReturnValue 46
48: Label
49: 6(int) Load 13(bound)
50: 6(int) IMul 49 40
57: 56(ptr) AccessChain 53(ini4) 55
58: 6(int) Load 57
59: 6(int) IMul 55 58
60: 6(int) IAdd 47 59
62: 53(ptr) AccessChain 50(ini4) 61
63: 6(int) Load 62
64: 6(int) IAdd 60 63
65: 8(float) ConvertSToF 64
ReturnValue 65
41: Label
66: 8(float) Undef
ReturnValue 66
60: 56(ptr) AccessChain 53(ini4) 59
61: 6(int) Load 60
62: 6(int) IMul 58 61
63: 6(int) IAdd 50 62
65: 56(ptr) AccessChain 53(ini4) 64
66: 6(int) Load 65
67: 6(int) IAdd 63 66
68: 8(float) ConvertSToF 67
ReturnValue 68
43: Label
70: 8(float) Undef
ReturnValue 70
FunctionEnd

View File

@ -3,12 +3,12 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 87
// Id's are bound by 91
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 55 74 76
EntryPoint Fragment 4 "main" 58 78 80
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
@ -18,13 +18,13 @@ Warning, version 450 is not yet complete; most version-specific features are pre
Name 13 "bound"
Name 17 "r"
Name 19 "x"
Name 47 "param"
Name 55 "ini4"
Name 74 "outf4"
Name 76 "inf"
Name 79 "param"
Name 49 "param"
Name 58 "ini4"
Name 78 "outf4"
Name 80 "inf"
Name 83 "param"
Decorate 55(ini4) Flat
Name 87 "param"
Decorate 58(ini4) Flat
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
@ -38,36 +38,36 @@ Warning, version 450 is not yet complete; most version-specific features are pre
30: 8(float) Constant 1056964608
34: 6(int) Constant 1
36: 8(float) Constant 1045220557
41: 6(int) Constant 2
51: 6(int) Constant 4
53: TypeVector 6(int) 4
54: TypePointer Input 53(ivec4)
55(ini4): 54(ptr) Variable Input
56: TypeInt 32 0
57: 56(int) Constant 1
58: TypePointer Input 6(int)
61: 56(int) Constant 2
66: 56(int) Constant 0
72: TypeVector 8(float) 4
73: TypePointer Output 72(fvec4)
74(outf4): 73(ptr) Variable Output
75: TypePointer Input 8(float)
76(inf): 75(ptr) Variable Input
43: 6(int) Constant 2
54: 6(int) Constant 4
56: TypeVector 6(int) 4
57: TypePointer Input 56(ivec4)
58(ini4): 57(ptr) Variable Input
59: TypeInt 32 0
60: 59(int) Constant 1
61: TypePointer Input 6(int)
64: 59(int) Constant 2
69: 59(int) Constant 0
76: TypeVector 8(float) 4
77: TypePointer Output 76(fvec4)
78(outf4): 77(ptr) Variable Output
79: TypePointer Input 8(float)
80(inf): 79(ptr) Variable Input
4(main): 2 Function None 3
5: Label
79(param): 7(ptr) Variable Function
83(param): 7(ptr) Variable Function
77: 8(float) Load 76(inf)
78: 6(int) ConvertFToS 77
Store 79(param) 78
80: 8(float) FunctionCall 11(Test1(i1;) 79(param)
81: 8(float) Load 76(inf)
87(param): 7(ptr) Variable Function
81: 8(float) Load 80(inf)
82: 6(int) ConvertFToS 81
Store 83(param) 82
84: 8(float) FunctionCall 14(Test2(i1;) 83(param)
85: 8(float) FAdd 80 84
86: 72(fvec4) CompositeConstruct 85 85 85 85
Store 74(outf4) 86
84: 8(float) FunctionCall 11(Test1(i1;) 83(param)
85: 8(float) Load 80(inf)
86: 6(int) ConvertFToS 85
Store 87(param) 86
88: 8(float) FunctionCall 14(Test2(i1;) 87(param)
89: 8(float) FAdd 84 88
90: 76(fvec4) CompositeConstruct 89 89 89 89
Store 78(outf4) 90
Return
FunctionEnd
11(Test1(i1;): 8(float) Function None 9
@ -106,32 +106,32 @@ Warning, version 450 is not yet complete; most version-specific features are pre
14(Test2(i1;): 8(float) Function None 9
13(bound): 7(ptr) FunctionParameter
15: Label
47(param): 7(ptr) Variable Function
40: 6(int) Load 13(bound)
42: 28(bool) SGreaterThan 40 41
SelectionMerge 44 None
BranchConditional 42 43 49
43: Label
45: 6(int) Load 13(bound)
46: 6(int) IMul 45 41
Store 47(param) 46
48: 8(float) FunctionCall 11(Test1(i1;) 47(param)
ReturnValue 48
49: Label
50: 6(int) Load 13(bound)
52: 6(int) IMul 50 51
59: 58(ptr) AccessChain 55(ini4) 57
60: 6(int) Load 59
62: 58(ptr) AccessChain 55(ini4) 61
49(param): 7(ptr) Variable Function
42: 6(int) Load 13(bound)
44: 28(bool) SGreaterThan 42 43
SelectionMerge 46 None
BranchConditional 44 45 52
45: Label
47: 6(int) Load 13(bound)
48: 6(int) IMul 47 43
Store 49(param) 48
50: 8(float) FunctionCall 11(Test1(i1;) 49(param)
ReturnValue 50
52: Label
53: 6(int) Load 13(bound)
55: 6(int) IMul 53 54
62: 61(ptr) AccessChain 58(ini4) 60
63: 6(int) Load 62
64: 6(int) IMul 60 63
65: 6(int) IAdd 52 64
67: 58(ptr) AccessChain 55(ini4) 66
68: 6(int) Load 67
69: 6(int) IAdd 65 68
70: 8(float) ConvertSToF 69
ReturnValue 70
44: Label
71: 8(float) Undef
ReturnValue 71
65: 61(ptr) AccessChain 58(ini4) 64
66: 6(int) Load 65
67: 6(int) IMul 63 66
68: 6(int) IAdd 55 67
70: 61(ptr) AccessChain 58(ini4) 69
71: 6(int) Load 70
72: 6(int) IAdd 68 71
73: 8(float) ConvertSToF 72
ReturnValue 73
46: Label
75: 8(float) Undef
ReturnValue 75
FunctionEnd

View File

@ -5,7 +5,7 @@ WARNING: 0:5: '' : all default precisions are highp; use precision statements to
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 44
// Id's are bound by 48
Capability Shader
1: ExtInstImport "GLSL.std.450"
@ -20,8 +20,8 @@ WARNING: 0:5: '' : all default precisions are highp; use precision statements to
Decorate 23(FragColor) RelaxedPrecision
Decorate 23(FragColor) Location 0
Decorate 29 RelaxedPrecision
Decorate 35 RelaxedPrecision
Decorate 41 RelaxedPrecision
Decorate 36 RelaxedPrecision
Decorate 43 RelaxedPrecision
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@ -36,12 +36,12 @@ WARNING: 0:5: '' : all default precisions are highp; use precision statements to
23(FragColor): 22(ptr) Variable Output
24: 10(int) Constant 0
27: 6(float) Constant 0
30: 10(int) Constant 1
33: 6(float) Constant 1065353216
36: 10(int) Constant 2
39: 6(float) Constant 1073741824
42: 6(float) Constant 3212836864
43: 7(fvec4) ConstantComposite 42 42 42 42
31: 10(int) Constant 1
34: 6(float) Constant 1065353216
38: 10(int) Constant 2
41: 6(float) Constant 1073741824
45: 6(float) Constant 3212836864
46: 7(fvec4) ConstantComposite 45 45 45 45
4(main): 2 Function None 3
5: Label
13: 12(ptr) AccessChain 9(in0) 11
@ -53,7 +53,7 @@ WARNING: 0:5: '' : all default precisions are highp; use precision statements to
case 1: 18
case 2: 19
20: Label
Store 23(FragColor) 43
Store 23(FragColor) 46
Branch 21
17: Label
25: 12(ptr) AccessChain 9(in0) 24
@ -63,18 +63,18 @@ WARNING: 0:5: '' : all default precisions are highp; use precision statements to
Store 23(FragColor) 29
Branch 21
18: Label
31: 12(ptr) AccessChain 9(in0) 30
32: 6(float) Load 31
34: 6(float) FAdd 32 33
35: 7(fvec4) CompositeConstruct 34 34 34 34
Store 23(FragColor) 35
32: 12(ptr) AccessChain 9(in0) 31
33: 6(float) Load 32
35: 6(float) FAdd 33 34
36: 7(fvec4) CompositeConstruct 35 35 35 35
Store 23(FragColor) 36
Branch 21
19: Label
37: 12(ptr) AccessChain 9(in0) 36
38: 6(float) Load 37
40: 6(float) FAdd 38 39
41: 7(fvec4) CompositeConstruct 40 40 40 40
Store 23(FragColor) 41
39: 12(ptr) AccessChain 9(in0) 38
40: 6(float) Load 39
42: 6(float) FAdd 40 41
43: 7(fvec4) CompositeConstruct 42 42 42 42
Store 23(FragColor) 43
Branch 21
21: Label
Return

View File

@ -0,0 +1,46 @@
spv.GeometryShaderPassthrough.geom
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 15
Capability Geometry
Capability GeometryShaderPassthroughNV
Extension "SPV_NV_geometry_shader_passthrough"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Geometry 4 "main" 10 14
ExecutionMode 4 Triangles
ExecutionMode 4 Invocations 1
ExecutionMode 4 OutputVertices
Source GLSL 450
SourceExtension "GL_NV_geometry_shader_passthrough"
Name 4 "main"
Name 8 "gl_PerVertex"
MemberName 8(gl_PerVertex) 0 "gl_Position"
Name 10 ""
Name 12 "Inputs"
MemberName 12(Inputs) 0 "texcoord"
MemberName 12(Inputs) 1 "baseColor"
Name 14 ""
MemberDecorate 8(gl_PerVertex) 0 BuiltIn Position
Decorate 8(gl_PerVertex) Block
Decorate 10 PassthroughNV
Decorate 12(Inputs) Block
Decorate 14 PassthroughNV
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8(gl_PerVertex): TypeStruct 7(fvec4)
9: TypePointer Input 8(gl_PerVertex)
10: 9(ptr) Variable Input
11: TypeVector 6(float) 2
12(Inputs): TypeStruct 11(fvec2) 7(fvec4)
13: TypePointer Input 12(Inputs)
14: 13(ptr) Variable Input
4(main): 2 Function None 3
5: Label
Return
FunctionEnd

View File

@ -0,0 +1,42 @@
spv.sampleMaskOverrideCoverage.frag
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 20
Capability Shader
Capability SampleRateShading
Extension "SPV_NV_sample_mask_override_coverage"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 11 19
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_NV_sample_mask_override_coverage"
Name 4 "main"
Name 11 "gl_SampleMask"
Name 19 "color"
Decorate 11(gl_SampleMask) BuiltIn SampleMask
Decorate 11(gl_SampleMask) OverrideCoverageNV
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypeInt 32 0
8: 7(int) Constant 1
9: TypeArray 6(int) 8
10: TypePointer Output 9
11(gl_SampleMask): 10(ptr) Variable Output
12: 6(int) Constant 0
13: 6(int) Constant 4294967295
14: TypePointer Output 6(int)
16: TypeFloat 32
17: TypeVector 16(float) 4
18: TypePointer Input 17(fvec4)
19(color): 18(ptr) Variable Input
4(main): 2 Function None 3
5: Label
15: 14(ptr) AccessChain 11(gl_SampleMask) 12
Store 15 13
Return
FunctionEnd

View File

@ -3,11 +3,10 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 299
// Id's are bound by 298
Capability Shader
Capability Int64
Capability Groups
Capability SubgroupBallotKHR
Extension "SPV_KHR_shader_ballot"
1: ExtInstImport "GLSL.std.450"
@ -45,7 +44,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre
Decorate 52(Buffers) BufferBlock
Decorate 55(data) DescriptorSet 0
Decorate 55(data) Binding 0
Decorate 298 BuiltIn WorkgroupSize
Decorate 297 BuiltIn WorkgroupSize
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 0
@ -77,23 +76,22 @@ Warning, version 450 is not yet complete; most version-specific features are pre
57: 50(int) Constant 0
58: 6(int) Constant 0
59: TypePointer Uniform 48(float)
63: 6(int) Constant 3
67: 50(int) Constant 1
68: TypeVector 48(float) 2
69: TypePointer Uniform 49(fvec4)
83: 50(int) Constant 2
84: TypeVector 48(float) 3
100: 50(int) Constant 3
115: TypePointer Uniform 50(int)
122: TypeVector 50(int) 2
123: TypePointer Uniform 51(ivec4)
137: TypeVector 50(int) 3
167: TypePointer Uniform 6(int)
174: TypePointer Uniform 38(ivec4)
188: TypeVector 6(int) 3
296: 6(int) Constant 8
297: 6(int) Constant 1
298: 188(ivec3) ConstantComposite 296 296 297
66: 50(int) Constant 1
67: TypeVector 48(float) 2
68: TypePointer Uniform 49(fvec4)
82: 50(int) Constant 2
83: TypeVector 48(float) 3
99: 50(int) Constant 3
114: TypePointer Uniform 50(int)
121: TypeVector 50(int) 2
122: TypePointer Uniform 51(ivec4)
136: TypeVector 50(int) 3
166: TypePointer Uniform 6(int)
173: TypePointer Uniform 38(ivec4)
187: TypeVector 6(int) 3
295: 6(int) Constant 8
296: 6(int) Constant 1
297: 187(ivec3) ConstantComposite 295 295 296
4(main): 2 Function None 3
5: Label
8(invocation): 7(ptr) Variable Function
@ -121,256 +119,256 @@ Warning, version 450 is not yet complete; most version-specific features are pre
44: 17(int) Bitcast 43
45: 36(bool) IEqual 35 44
SelectionMerge 47 None
BranchConditional 45 46 217
BranchConditional 45 46 216
46: Label
56: 6(int) Load 8(invocation)
60: 59(ptr) AccessChain 55(data) 57 57 58
61: 48(float) Load 60
62: 6(int) Load 8(invocation)
64: 48(float) GroupBroadcast 63 61 62
65: 59(ptr) AccessChain 55(data) 56 57 58
Store 65 64
66: 6(int) Load 8(invocation)
70: 69(ptr) AccessChain 55(data) 67 57
71: 49(fvec4) Load 70
72: 68(fvec2) VectorShuffle 71 71 0 1
73: 6(int) Load 8(invocation)
74: 48(float) CompositeExtract 72 0
75: 48(float) GroupBroadcast 63 74 73
76: 48(float) CompositeExtract 72 1
77: 48(float) GroupBroadcast 63 76 73
78: 68(fvec2) CompositeConstruct 75 77
79: 69(ptr) AccessChain 55(data) 66 57
80: 49(fvec4) Load 79
81: 49(fvec4) VectorShuffle 80 78 4 5 2 3
Store 79 81
82: 6(int) Load 8(invocation)
85: 69(ptr) AccessChain 55(data) 83 57
86: 49(fvec4) Load 85
87: 84(fvec3) VectorShuffle 86 86 0 1 2
88: 6(int) Load 8(invocation)
89: 48(float) CompositeExtract 87 0
90: 48(float) GroupBroadcast 63 89 88
91: 48(float) CompositeExtract 87 1
92: 48(float) GroupBroadcast 63 91 88
93: 48(float) CompositeExtract 87 2
94: 48(float) GroupBroadcast 63 93 88
95: 84(fvec3) CompositeConstruct 90 92 94
96: 69(ptr) AccessChain 55(data) 82 57
97: 49(fvec4) Load 96
98: 49(fvec4) VectorShuffle 97 95 4 5 6 3
Store 96 98
99: 6(int) Load 8(invocation)
101: 69(ptr) AccessChain 55(data) 100 57
102: 49(fvec4) Load 101
103: 6(int) Load 8(invocation)
104: 48(float) CompositeExtract 102 0
105: 48(float) GroupBroadcast 63 104 103
106: 48(float) CompositeExtract 102 1
107: 48(float) GroupBroadcast 63 106 103
108: 48(float) CompositeExtract 102 2
109: 48(float) GroupBroadcast 63 108 103
110: 48(float) CompositeExtract 102 3
111: 48(float) GroupBroadcast 63 110 103
112: 49(fvec4) CompositeConstruct 105 107 109 111
113: 69(ptr) AccessChain 55(data) 99 57
Store 113 112
114: 6(int) Load 8(invocation)
116: 115(ptr) AccessChain 55(data) 57 67 58
117: 50(int) Load 116
118: 6(int) Load 8(invocation)
119: 50(int) GroupBroadcast 63 117 118
120: 115(ptr) AccessChain 55(data) 114 67 58
Store 120 119
121: 6(int) Load 8(invocation)
124: 123(ptr) AccessChain 55(data) 67 67
125: 51(ivec4) Load 124
126: 122(ivec2) VectorShuffle 125 125 0 1
127: 6(int) Load 8(invocation)
128: 50(int) CompositeExtract 126 0
129: 50(int) GroupBroadcast 63 128 127
130: 50(int) CompositeExtract 126 1
131: 50(int) GroupBroadcast 63 130 127
132: 122(ivec2) CompositeConstruct 129 131
133: 123(ptr) AccessChain 55(data) 121 67
134: 51(ivec4) Load 133
135: 51(ivec4) VectorShuffle 134 132 4 5 2 3
Store 133 135
136: 6(int) Load 8(invocation)
138: 123(ptr) AccessChain 55(data) 83 67
139: 51(ivec4) Load 138
140: 137(ivec3) VectorShuffle 139 139 0 1 2
141: 6(int) Load 8(invocation)
142: 50(int) CompositeExtract 140 0
143: 50(int) GroupBroadcast 63 142 141
144: 50(int) CompositeExtract 140 1
145: 50(int) GroupBroadcast 63 144 141
146: 50(int) CompositeExtract 140 2
147: 50(int) GroupBroadcast 63 146 141
148: 137(ivec3) CompositeConstruct 143 145 147
149: 123(ptr) AccessChain 55(data) 136 67
150: 51(ivec4) Load 149
151: 51(ivec4) VectorShuffle 150 148 4 5 6 3
Store 149 151
152: 6(int) Load 8(invocation)
153: 123(ptr) AccessChain 55(data) 100 67
154: 51(ivec4) Load 153
155: 6(int) Load 8(invocation)
156: 50(int) CompositeExtract 154 0
157: 50(int) GroupBroadcast 63 156 155
158: 50(int) CompositeExtract 154 1
159: 50(int) GroupBroadcast 63 158 155
160: 50(int) CompositeExtract 154 2
161: 50(int) GroupBroadcast 63 160 155
162: 50(int) CompositeExtract 154 3
163: 50(int) GroupBroadcast 63 162 155
164: 51(ivec4) CompositeConstruct 157 159 161 163
165: 123(ptr) AccessChain 55(data) 152 67
Store 165 164
166: 6(int) Load 8(invocation)
168: 167(ptr) AccessChain 55(data) 57 83 58
169: 6(int) Load 168
170: 6(int) Load 8(invocation)
171: 6(int) GroupBroadcast 63 169 170
172: 167(ptr) AccessChain 55(data) 166 83 58
Store 172 171
173: 6(int) Load 8(invocation)
175: 174(ptr) AccessChain 55(data) 67 83
176: 38(ivec4) Load 175
177: 42(ivec2) VectorShuffle 176 176 0 1
178: 6(int) Load 8(invocation)
179: 6(int) CompositeExtract 177 0
180: 6(int) GroupBroadcast 63 179 178
181: 6(int) CompositeExtract 177 1
182: 6(int) GroupBroadcast 63 181 178
183: 42(ivec2) CompositeConstruct 180 182
184: 174(ptr) AccessChain 55(data) 173 83
185: 38(ivec4) Load 184
186: 38(ivec4) VectorShuffle 185 183 4 5 2 3
Store 184 186
187: 6(int) Load 8(invocation)
189: 174(ptr) AccessChain 55(data) 83 83
190: 38(ivec4) Load 189
191: 188(ivec3) VectorShuffle 190 190 0 1 2
192: 6(int) Load 8(invocation)
193: 6(int) CompositeExtract 191 0
194: 6(int) GroupBroadcast 63 193 192
195: 6(int) CompositeExtract 191 1
196: 6(int) GroupBroadcast 63 195 192
197: 6(int) CompositeExtract 191 2
198: 6(int) GroupBroadcast 63 197 192
199: 188(ivec3) CompositeConstruct 194 196 198
200: 174(ptr) AccessChain 55(data) 187 83
201: 38(ivec4) Load 200
202: 38(ivec4) VectorShuffle 201 199 4 5 6 3
Store 200 202
203: 6(int) Load 8(invocation)
204: 174(ptr) AccessChain 55(data) 100 83
205: 38(ivec4) Load 204
206: 6(int) Load 8(invocation)
207: 6(int) CompositeExtract 205 0
208: 6(int) GroupBroadcast 63 207 206
209: 6(int) CompositeExtract 205 1
210: 6(int) GroupBroadcast 63 209 206
211: 6(int) CompositeExtract 205 2
212: 6(int) GroupBroadcast 63 211 206
213: 6(int) CompositeExtract 205 3
214: 6(int) GroupBroadcast 63 213 206
215: 38(ivec4) CompositeConstruct 208 210 212 214
216: 174(ptr) AccessChain 55(data) 203 83
Store 216 215
63: 48(float) SubgroupReadInvocationKHR 61 62
64: 59(ptr) AccessChain 55(data) 56 57 58
Store 64 63
65: 6(int) Load 8(invocation)
69: 68(ptr) AccessChain 55(data) 66 57
70: 49(fvec4) Load 69
71: 67(fvec2) VectorShuffle 70 70 0 1
72: 6(int) Load 8(invocation)
73: 48(float) CompositeExtract 71 0
74: 48(float) SubgroupReadInvocationKHR 73 72
75: 48(float) CompositeExtract 71 1
76: 48(float) SubgroupReadInvocationKHR 75 72
77: 67(fvec2) CompositeConstruct 74 76
78: 68(ptr) AccessChain 55(data) 65 57
79: 49(fvec4) Load 78
80: 49(fvec4) VectorShuffle 79 77 4 5 2 3
Store 78 80
81: 6(int) Load 8(invocation)
84: 68(ptr) AccessChain 55(data) 82 57
85: 49(fvec4) Load 84
86: 83(fvec3) VectorShuffle 85 85 0 1 2
87: 6(int) Load 8(invocation)
88: 48(float) CompositeExtract 86 0
89: 48(float) SubgroupReadInvocationKHR 88 87
90: 48(float) CompositeExtract 86 1
91: 48(float) SubgroupReadInvocationKHR 90 87
92: 48(float) CompositeExtract 86 2
93: 48(float) SubgroupReadInvocationKHR 92 87
94: 83(fvec3) CompositeConstruct 89 91 93
95: 68(ptr) AccessChain 55(data) 81 57
96: 49(fvec4) Load 95
97: 49(fvec4) VectorShuffle 96 94 4 5 6 3
Store 95 97
98: 6(int) Load 8(invocation)
100: 68(ptr) AccessChain 55(data) 99 57
101: 49(fvec4) Load 100
102: 6(int) Load 8(invocation)
103: 48(float) CompositeExtract 101 0
104: 48(float) SubgroupReadInvocationKHR 103 102
105: 48(float) CompositeExtract 101 1
106: 48(float) SubgroupReadInvocationKHR 105 102
107: 48(float) CompositeExtract 101 2
108: 48(float) SubgroupReadInvocationKHR 107 102
109: 48(float) CompositeExtract 101 3
110: 48(float) SubgroupReadInvocationKHR 109 102
111: 49(fvec4) CompositeConstruct 104 106 108 110
112: 68(ptr) AccessChain 55(data) 98 57
Store 112 111
113: 6(int) Load 8(invocation)
115: 114(ptr) AccessChain 55(data) 57 66 58
116: 50(int) Load 115
117: 6(int) Load 8(invocation)
118: 50(int) SubgroupReadInvocationKHR 116 117
119: 114(ptr) AccessChain 55(data) 113 66 58
Store 119 118
120: 6(int) Load 8(invocation)
123: 122(ptr) AccessChain 55(data) 66 66
124: 51(ivec4) Load 123
125: 121(ivec2) VectorShuffle 124 124 0 1
126: 6(int) Load 8(invocation)
127: 50(int) CompositeExtract 125 0
128: 50(int) SubgroupReadInvocationKHR 127 126
129: 50(int) CompositeExtract 125 1
130: 50(int) SubgroupReadInvocationKHR 129 126
131: 121(ivec2) CompositeConstruct 128 130
132: 122(ptr) AccessChain 55(data) 120 66
133: 51(ivec4) Load 132
134: 51(ivec4) VectorShuffle 133 131 4 5 2 3
Store 132 134
135: 6(int) Load 8(invocation)
137: 122(ptr) AccessChain 55(data) 82 66
138: 51(ivec4) Load 137
139: 136(ivec3) VectorShuffle 138 138 0 1 2
140: 6(int) Load 8(invocation)
141: 50(int) CompositeExtract 139 0
142: 50(int) SubgroupReadInvocationKHR 141 140
143: 50(int) CompositeExtract 139 1
144: 50(int) SubgroupReadInvocationKHR 143 140
145: 50(int) CompositeExtract 139 2
146: 50(int) SubgroupReadInvocationKHR 145 140
147: 136(ivec3) CompositeConstruct 142 144 146
148: 122(ptr) AccessChain 55(data) 135 66
149: 51(ivec4) Load 148
150: 51(ivec4) VectorShuffle 149 147 4 5 6 3
Store 148 150
151: 6(int) Load 8(invocation)
152: 122(ptr) AccessChain 55(data) 99 66
153: 51(ivec4) Load 152
154: 6(int) Load 8(invocation)
155: 50(int) CompositeExtract 153 0
156: 50(int) SubgroupReadInvocationKHR 155 154
157: 50(int) CompositeExtract 153 1
158: 50(int) SubgroupReadInvocationKHR 157 154
159: 50(int) CompositeExtract 153 2
160: 50(int) SubgroupReadInvocationKHR 159 154
161: 50(int) CompositeExtract 153 3
162: 50(int) SubgroupReadInvocationKHR 161 154
163: 51(ivec4) CompositeConstruct 156 158 160 162
164: 122(ptr) AccessChain 55(data) 151 66
Store 164 163
165: 6(int) Load 8(invocation)
167: 166(ptr) AccessChain 55(data) 57 82 58
168: 6(int) Load 167
169: 6(int) Load 8(invocation)
170: 6(int) SubgroupReadInvocationKHR 168 169
171: 166(ptr) AccessChain 55(data) 165 82 58
Store 171 170
172: 6(int) Load 8(invocation)
174: 173(ptr) AccessChain 55(data) 66 82
175: 38(ivec4) Load 174
176: 42(ivec2) VectorShuffle 175 175 0 1
177: 6(int) Load 8(invocation)
178: 6(int) CompositeExtract 176 0
179: 6(int) SubgroupReadInvocationKHR 178 177
180: 6(int) CompositeExtract 176 1
181: 6(int) SubgroupReadInvocationKHR 180 177
182: 42(ivec2) CompositeConstruct 179 181
183: 173(ptr) AccessChain 55(data) 172 82
184: 38(ivec4) Load 183
185: 38(ivec4) VectorShuffle 184 182 4 5 2 3
Store 183 185
186: 6(int) Load 8(invocation)
188: 173(ptr) AccessChain 55(data) 82 82
189: 38(ivec4) Load 188
190: 187(ivec3) VectorShuffle 189 189 0 1 2
191: 6(int) Load 8(invocation)
192: 6(int) CompositeExtract 190 0
193: 6(int) SubgroupReadInvocationKHR 192 191
194: 6(int) CompositeExtract 190 1
195: 6(int) SubgroupReadInvocationKHR 194 191
196: 6(int) CompositeExtract 190 2
197: 6(int) SubgroupReadInvocationKHR 196 191
198: 187(ivec3) CompositeConstruct 193 195 197
199: 173(ptr) AccessChain 55(data) 186 82
200: 38(ivec4) Load 199
201: 38(ivec4) VectorShuffle 200 198 4 5 6 3
Store 199 201
202: 6(int) Load 8(invocation)
203: 173(ptr) AccessChain 55(data) 99 82
204: 38(ivec4) Load 203
205: 6(int) Load 8(invocation)
206: 6(int) CompositeExtract 204 0
207: 6(int) SubgroupReadInvocationKHR 206 205
208: 6(int) CompositeExtract 204 1
209: 6(int) SubgroupReadInvocationKHR 208 205
210: 6(int) CompositeExtract 204 2
211: 6(int) SubgroupReadInvocationKHR 210 205
212: 6(int) CompositeExtract 204 3
213: 6(int) SubgroupReadInvocationKHR 212 205
214: 38(ivec4) CompositeConstruct 207 209 211 213
215: 173(ptr) AccessChain 55(data) 202 82
Store 215 214
Branch 47
217: Label
218: 6(int) Load 8(invocation)
219: 59(ptr) AccessChain 55(data) 57 57 58
220: 48(float) Load 219
221: 48(float) SubgroupFirstInvocationKHR 220
222: 59(ptr) AccessChain 55(data) 218 57 58
Store 222 221
223: 6(int) Load 8(invocation)
224: 69(ptr) AccessChain 55(data) 67 57
225: 49(fvec4) Load 224
226: 68(fvec2) VectorShuffle 225 225 0 1
227: 68(fvec2) SubgroupFirstInvocationKHR 226
228: 69(ptr) AccessChain 55(data) 223 57
229: 49(fvec4) Load 228
230: 49(fvec4) VectorShuffle 229 227 4 5 2 3
Store 228 230
231: 6(int) Load 8(invocation)
232: 69(ptr) AccessChain 55(data) 83 57
233: 49(fvec4) Load 232
234: 84(fvec3) VectorShuffle 233 233 0 1 2
235: 84(fvec3) SubgroupFirstInvocationKHR 234
236: 69(ptr) AccessChain 55(data) 231 57
237: 49(fvec4) Load 236
238: 49(fvec4) VectorShuffle 237 235 4 5 6 3
Store 236 238
239: 6(int) Load 8(invocation)
240: 69(ptr) AccessChain 55(data) 100 57
241: 49(fvec4) Load 240
242: 49(fvec4) SubgroupFirstInvocationKHR 241
243: 69(ptr) AccessChain 55(data) 239 57
Store 243 242
244: 6(int) Load 8(invocation)
245: 115(ptr) AccessChain 55(data) 57 67 58
246: 50(int) Load 245
247: 50(int) SubgroupFirstInvocationKHR 246
248: 115(ptr) AccessChain 55(data) 244 67 58
Store 248 247
249: 6(int) Load 8(invocation)
250: 123(ptr) AccessChain 55(data) 67 67
251: 51(ivec4) Load 250
252: 122(ivec2) VectorShuffle 251 251 0 1
253: 122(ivec2) SubgroupFirstInvocationKHR 252
254: 123(ptr) AccessChain 55(data) 249 67
255: 51(ivec4) Load 254
256: 51(ivec4) VectorShuffle 255 253 4 5 2 3
Store 254 256
257: 6(int) Load 8(invocation)
258: 123(ptr) AccessChain 55(data) 83 67
259: 51(ivec4) Load 258
260: 137(ivec3) VectorShuffle 259 259 0 1 2
261: 137(ivec3) SubgroupFirstInvocationKHR 260
262: 123(ptr) AccessChain 55(data) 257 67
263: 51(ivec4) Load 262
264: 51(ivec4) VectorShuffle 263 261 4 5 6 3
Store 262 264
265: 6(int) Load 8(invocation)
266: 123(ptr) AccessChain 55(data) 100 67
267: 51(ivec4) Load 266
268: 51(ivec4) SubgroupFirstInvocationKHR 267
269: 123(ptr) AccessChain 55(data) 265 67
Store 269 268
270: 6(int) Load 8(invocation)
271: 167(ptr) AccessChain 55(data) 57 83 58
272: 6(int) Load 271
273: 6(int) SubgroupFirstInvocationKHR 272
274: 167(ptr) AccessChain 55(data) 270 83 58
Store 274 273
275: 6(int) Load 8(invocation)
276: 174(ptr) AccessChain 55(data) 67 83
277: 38(ivec4) Load 276
278: 42(ivec2) VectorShuffle 277 277 0 1
279: 42(ivec2) SubgroupFirstInvocationKHR 278
280: 174(ptr) AccessChain 55(data) 275 83
281: 38(ivec4) Load 280
282: 38(ivec4) VectorShuffle 281 279 4 5 2 3
Store 280 282
283: 6(int) Load 8(invocation)
284: 174(ptr) AccessChain 55(data) 83 83
285: 38(ivec4) Load 284
286: 188(ivec3) VectorShuffle 285 285 0 1 2
287: 188(ivec3) SubgroupFirstInvocationKHR 286
288: 174(ptr) AccessChain 55(data) 283 83
289: 38(ivec4) Load 288
290: 38(ivec4) VectorShuffle 289 287 4 5 6 3
Store 288 290
291: 6(int) Load 8(invocation)
292: 174(ptr) AccessChain 55(data) 100 83
293: 38(ivec4) Load 292
294: 38(ivec4) SubgroupFirstInvocationKHR 293
295: 174(ptr) AccessChain 55(data) 291 83
Store 295 294
216: Label
217: 6(int) Load 8(invocation)
218: 59(ptr) AccessChain 55(data) 57 57 58
219: 48(float) Load 218
220: 48(float) SubgroupFirstInvocationKHR 219
221: 59(ptr) AccessChain 55(data) 217 57 58
Store 221 220
222: 6(int) Load 8(invocation)
223: 68(ptr) AccessChain 55(data) 66 57
224: 49(fvec4) Load 223
225: 67(fvec2) VectorShuffle 224 224 0 1
226: 67(fvec2) SubgroupFirstInvocationKHR 225
227: 68(ptr) AccessChain 55(data) 222 57
228: 49(fvec4) Load 227
229: 49(fvec4) VectorShuffle 228 226 4 5 2 3
Store 227 229
230: 6(int) Load 8(invocation)
231: 68(ptr) AccessChain 55(data) 82 57
232: 49(fvec4) Load 231
233: 83(fvec3) VectorShuffle 232 232 0 1 2
234: 83(fvec3) SubgroupFirstInvocationKHR 233
235: 68(ptr) AccessChain 55(data) 230 57
236: 49(fvec4) Load 235
237: 49(fvec4) VectorShuffle 236 234 4 5 6 3
Store 235 237
238: 6(int) Load 8(invocation)
239: 68(ptr) AccessChain 55(data) 99 57
240: 49(fvec4) Load 239
241: 49(fvec4) SubgroupFirstInvocationKHR 240
242: 68(ptr) AccessChain 55(data) 238 57
Store 242 241
243: 6(int) Load 8(invocation)
244: 114(ptr) AccessChain 55(data) 57 66 58
245: 50(int) Load 244
246: 50(int) SubgroupFirstInvocationKHR 245
247: 114(ptr) AccessChain 55(data) 243 66 58
Store 247 246
248: 6(int) Load 8(invocation)
249: 122(ptr) AccessChain 55(data) 66 66
250: 51(ivec4) Load 249
251: 121(ivec2) VectorShuffle 250 250 0 1
252: 121(ivec2) SubgroupFirstInvocationKHR 251
253: 122(ptr) AccessChain 55(data) 248 66
254: 51(ivec4) Load 253
255: 51(ivec4) VectorShuffle 254 252 4 5 2 3
Store 253 255
256: 6(int) Load 8(invocation)
257: 122(ptr) AccessChain 55(data) 82 66
258: 51(ivec4) Load 257
259: 136(ivec3) VectorShuffle 258 258 0 1 2
260: 136(ivec3) SubgroupFirstInvocationKHR 259
261: 122(ptr) AccessChain 55(data) 256 66
262: 51(ivec4) Load 261
263: 51(ivec4) VectorShuffle 262 260 4 5 6 3
Store 261 263
264: 6(int) Load 8(invocation)
265: 122(ptr) AccessChain 55(data) 99 66
266: 51(ivec4) Load 265
267: 51(ivec4) SubgroupFirstInvocationKHR 266
268: 122(ptr) AccessChain 55(data) 264 66
Store 268 267
269: 6(int) Load 8(invocation)
270: 166(ptr) AccessChain 55(data) 57 82 58
271: 6(int) Load 270
272: 6(int) SubgroupFirstInvocationKHR 271
273: 166(ptr) AccessChain 55(data) 269 82 58
Store 273 272
274: 6(int) Load 8(invocation)
275: 173(ptr) AccessChain 55(data) 66 82
276: 38(ivec4) Load 275
277: 42(ivec2) VectorShuffle 276 276 0 1
278: 42(ivec2) SubgroupFirstInvocationKHR 277
279: 173(ptr) AccessChain 55(data) 274 82
280: 38(ivec4) Load 279
281: 38(ivec4) VectorShuffle 280 278 4 5 2 3
Store 279 281
282: 6(int) Load 8(invocation)
283: 173(ptr) AccessChain 55(data) 82 82
284: 38(ivec4) Load 283
285: 187(ivec3) VectorShuffle 284 284 0 1 2
286: 187(ivec3) SubgroupFirstInvocationKHR 285
287: 173(ptr) AccessChain 55(data) 282 82
288: 38(ivec4) Load 287
289: 38(ivec4) VectorShuffle 288 286 4 5 6 3
Store 287 289
290: 6(int) Load 8(invocation)
291: 173(ptr) AccessChain 55(data) 99 82
292: 38(ivec4) Load 291
293: 38(ivec4) SubgroupFirstInvocationKHR 292
294: 173(ptr) AccessChain 55(data) 290 82
Store 294 293
Branch 47
47: Label
Return

View File

@ -0,0 +1,112 @@
tokenPaste.vert
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
ERROR: 0:38: '##' : unexpected location
ERROR: 0:40: '##' : unexpected location; end of replacement list
ERROR: 0:49: '##' : combined tokens are too long
ERROR: 0:52: '##' : not supported for these tokens
ERROR: 0:69: '##' : combined token is invalid
ERROR: 5 compilation errors. No code generated.
Shader version: 450
ERROR: node is still EOpNull!
0:52 Sequence
0:52 move second child to first child (temp int)
0:52 'a' (global int)
0:52 Constant:
0:52 11 (const int)
0:58 Sequence
0:58 move second child to first child (temp int)
0:58 'cop' (global int)
0:58 Constant:
0:58 160 (const int)
0:59 Sequence
0:59 move second child to first child (temp bool)
0:59 'dop' (global bool)
0:59 Constant:
0:59 true (const bool)
0:63 Function Definition: ShouldntExpandToThis( (global void)
0:63 Function Parameters:
0:65 Sequence
0:65 Sequence
0:65 move second child to first child (temp int)
0:65 'e' (temp int)
0:65 Constant:
0:65 16 (const int)
0:66 right shift second child into first child (temp int)
0:66 'e' (temp int)
0:66 Constant:
0:66 2 (const int)
0:69 Sequence
0:69 move second child to first child (temp bool)
0:69 'f' (temp bool)
0:69 Compare Greater Than (temp bool)
0:69 'e' (temp int)
0:69 Constant:
0:69 5 (const int)
0:? Linker Objects
0:? 'SecondExpansion' (global int)
0:? 'PostPasteExpansion' (global int)
0:? 'foo27' (global float)
0:? 'foo155' (uniform float)
0:? 'foo719' (global float)
0:? 'barfoo' (uniform float)
0:? 'argless' (global float)
0:? 'dc1' (global float)
0:? 'dc2' (global float)
0:? 'foo875' (uniform float)
0:? 'ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345' (global float)
0:? 'a' (global int)
0:? 'aop' (const int)
0:? 10 (const int)
0:? 'bop' (const int)
0:? 4 (const int)
0:? 'cop' (global int)
0:? 'dop' (global bool)
0:? 'gl_VertexID' (gl_VertexId int VertexId)
0:? 'gl_InstanceID' (gl_InstanceId int InstanceId)
Linked vertex stage:
ERROR: Linking vertex stage: Missing entry point: Each stage requires one entry point
Shader version: 450
ERROR: node is still EOpNull!
0:52 Sequence
0:52 move second child to first child (temp int)
0:52 'a' (global int)
0:52 Constant:
0:52 11 (const int)
0:58 Sequence
0:58 move second child to first child (temp int)
0:58 'cop' (global int)
0:58 Constant:
0:58 160 (const int)
0:59 Sequence
0:59 move second child to first child (temp bool)
0:59 'dop' (global bool)
0:59 Constant:
0:59 true (const bool)
0:? Linker Objects
0:? 'SecondExpansion' (global int)
0:? 'PostPasteExpansion' (global int)
0:? 'foo27' (global float)
0:? 'foo155' (uniform float)
0:? 'foo719' (global float)
0:? 'barfoo' (uniform float)
0:? 'argless' (global float)
0:? 'dc1' (global float)
0:? 'dc2' (global float)
0:? 'foo875' (uniform float)
0:? 'ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345' (global float)
0:? 'a' (global int)
0:? 'aop' (const int)
0:? 10 (const int)
0:? 'bop' (const int)
0:? 4 (const int)
0:? 'cop' (global int)
0:? 'dop' (global bool)
0:? 'gl_VertexID' (gl_VertexId int VertexId)
0:? 'gl_InstanceID' (gl_InstanceId int InstanceId)

View File

@ -12,7 +12,7 @@ float4 main() : SV_Target0
{
// HLSL allows this as an identifier as well.
// However, this is not true of other qualifier keywords such as "linear".
int sample = 3;
float4 sample = float4(3,4,5,6);
return float4(0,0,0,0);
return sample.rgba; // 'sample' can participate in an expression.
}

View File

@ -0,0 +1,17 @@
#version 450
#extension GL_NV_geometry_shader_passthrough : require
layout(triangles) in;
layout(passthrough) in gl_PerVertex {
vec4 gl_Position;
};
layout(passthrough) in Inputs {
vec2 texcoord;
vec4 baseColor;
};
void main()
{
}

View File

@ -0,0 +1,7 @@
#version 450
#extension GL_NV_sample_mask_override_coverage : enable
in vec4 color;
layout(override_coverage) out int gl_SampleMask[];
void main() {
gl_SampleMask[0] = int(0xFFFFFFFF);
}

70
3rdparty/glslang/Test/tokenPaste.vert vendored Normal file
View File

@ -0,0 +1,70 @@
#version 450
// side test verifies multiple rounds of argument expansion
#define bear SecondExpansion
#define mmmB bear
#define mmmA(a) a
int mmmA(mmmB); // mmmB -> bear, and then in mmmA(), bear -> SecondExpansion
// pasting skips the first round of expansion
#define mmcatmmdog PostPasteExpansion
#define mmcat cat
#define mmdog dog
#define mmp(a,b) a## b
int mmp(mmcat, mmdog); // mmcat/mmdog not expanded, mmcatmmdog -> PostPasteExpansion
// multi-token pre
#define mmtokpastepre(a) a##27
mmtokpastepre(float foo); // should declare "float foo27;"
// multi-token post
#define mmtokpastepost(a) uni ##a
mmtokpastepost(form float foo155); // should declare "uniform float foo155;"
// non-first argument
#define foo ShouldntExpandToThis
#define semi ;
#define bothpaste(a,b) a##b
float bothpaste(foo, 719); // should declare "float foo719;"
#define secpaste(a,b) a bar ## b
secpaste(uniform float, foo semi) // should declare "uniform float barfoo;"
// no args
#define noArg fl##oat
noArg argless;
// bad location
#define bad1 ## float
bad1 dc1;
#define bad2 float ##
bad2 dc2;
// multiple ##
#define multiPaste(a, b, c) a##or##b flo##at foo##c
multiPaste(unif, m, 875);
// too long
#define simplePaste(a,b) a##b
// 1020 + 5 characters
float simplePaste(ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345, 12345);
// non-identifiers
int a = simplePaste(11,12);
// operators
#define MAKE_OP(L, R) L ## R
const int aop = 10;
const int bop = 4;
int cop = aop MAKE_OP(<, <) bop;
bool dop = aop MAKE_OP(!,=) bop;
#define MAKE_OP3(L, M, R) L ## M ## R
void foo()
{
int e = 16;
e MAKE_OP3(>,>,=) 2;
// recovery from bad op
bool f = e MAKE_OP(>,!) 5;
}

View File

@ -599,6 +599,9 @@ public:
layoutFormat = ElfNone;
layoutPushConstant = false;
#ifdef NV_EXTENSIONS
layoutPassthrough = false;
#endif
}
bool hasLayout() const
{
@ -652,6 +655,10 @@ public:
bool layoutPushConstant;
#ifdef NV_EXTENSIONS
bool layoutPassthrough;
#endif
bool hasUniformLayout() const
{
return hasMatrix() ||
@ -920,6 +927,10 @@ struct TShaderQualifiers {
TLayoutDepth layoutDepth;
bool blendEquation; // true if any blend equation was specified
#ifdef NV_EXTENSIONS
bool layoutOverrideCoverage; // true if layout override_coverage set
#endif
void init()
{
geometry = ElgNone;
@ -939,6 +950,9 @@ struct TShaderQualifiers {
earlyFragmentTests = false;
layoutDepth = EldNone;
blendEquation = false;
#ifdef NV_EXTENSIONS
layoutOverrideCoverage = false;
#endif
}
// Merge in characteristics from the 'src' qualifier. They can override when
@ -975,6 +989,10 @@ struct TShaderQualifiers {
layoutDepth = src.layoutDepth;
if (src.blendEquation)
blendEquation = src.blendEquation;
#ifdef NV_EXTENSIONS
if (src.layoutOverrideCoverage)
layoutOverrideCoverage = src.layoutOverrideCoverage;
#endif
}
};
@ -1525,6 +1543,13 @@ public:
p += snprintf(p, end - p, "constant_id=%d ", qualifier.layoutSpecConstantId);
if (qualifier.layoutPushConstant)
p += snprintf(p, end - p, "push_constant ");
#ifdef NV_EXTENSIONS
if (qualifier.layoutPassthrough)
p += snprintf(p, end - p, "passthrough ");
#endif
p += snprintf(p, end - p, ") ");
}
}

View File

@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "Overload400-PrecQual.1695"
#define GLSLANG_DATE "16-Dec-2016"
#define GLSLANG_REVISION "Overload400-PrecQual.1721"
#define GLSLANG_DATE "21-Dec-2016"

View File

@ -604,7 +604,11 @@ void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type)
void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
{
if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
if (type.getQualifier().isArrayedIo(language))
if (type.getQualifier().isArrayedIo(language)
#ifdef NV_EXTENSIONS
&& !type.getQualifier().layoutPassthrough
#endif
)
error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
}
}
@ -3304,6 +3308,9 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
identifier == "gl_BackSecondaryColor" ||
identifier == "gl_SecondaryColor" ||
(identifier == "gl_Color" && language == EShLangFragment) ||
#ifdef NV_EXTENSIONS
identifier == "gl_SampleMask" ||
#endif
identifier == "gl_TexCoord") {
// Find the existing symbol, if any.
@ -3381,8 +3388,16 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
if (! intermediate.setDepth(publicType.layoutDepth))
error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
}
}
#ifdef NV_EXTENSIONS
else if (identifier == "gl_SampleMask") {
if (!publicType.layoutOverrideCoverage) {
error(loc, "redeclaration only allowed for override_coverage layout", "redeclaration", symbol->getName().c_str());
}
intermediate.setLayoutOverrideCoverage();
}
#endif
// TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
return symbol;
@ -3448,6 +3463,20 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
// - remove unused members
// - ensure remaining qualifiers/types match
TType& type = block->getWritableType();
#ifdef NV_EXTENSIONS
// if gl_PerVertex is redeclared for the purpose of passing through "gl_Position"
// for passthrough purpose, the redclared block should have the same qualifers as
// the current one
if (currentBlockQualifier.layoutPassthrough)
{
type.getQualifier().layoutPassthrough = currentBlockQualifier.layoutPassthrough;
type.getQualifier().storage = currentBlockQualifier.storage;
type.getQualifier().layoutStream = currentBlockQualifier.layoutStream;
type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
}
#endif
TTypeList::iterator member = type.getWritableStruct()->begin();
size_t numOriginalMembersFound = 0;
while (member != type.getStruct()->end()) {
@ -3917,6 +3946,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
publicType.shaderQualifiers.geometry = ElgTriangleStrip;
return;
}
#ifdef NV_EXTENSIONS
if (id == "passthrough") {
requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough");
publicType.qualifier.layoutPassthrough = true;
intermediate.setGeoPassthroughEXT();
return;
}
#endif
} else {
assert(language == EShLangTessEvaluation);
@ -4005,6 +4042,13 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "unknown blend equation", "blend_support", "");
return;
}
#ifdef NV_EXTENSIONS
if (id == "override_coverage") {
requireExtensions(loc, 1, &E_GL_NV_sample_mask_override_coverage, "sample mask override coverage");
publicType.shaderQualifiers.layoutOverrideCoverage = true;
return;
}
#endif
}
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
}
@ -4310,6 +4354,11 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
if (src.layoutPushConstant)
dst.layoutPushConstant = true;
#ifdef NV_EXTENSIONS
if (src.layoutPassthrough)
dst.layoutPassthrough = true;
#endif
}
}

View File

@ -49,8 +49,7 @@
#include "SymbolTable.h"
#include "localintermediate.h"
#include "Scan.h"
#include <functional>
#include <cstdarg>
#include <functional>
namespace glslang {
@ -238,23 +237,23 @@ public:
bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); };
void setPrecisionDefaults();
void setLimits(const TBuiltInResource&);
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false);
void setLimits(const TBuiltInResource&) override;
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
void parserError(const char* s); // for bison's yyerror
void reservedErrorCheck(const TSourceLoc&, const TString&);
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op);
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment);
bool lineDirectiveShouldSetNextLine() const;
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override;
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override;
bool lineDirectiveShouldSetNextLine() const override;
bool builtInName(const TString&);
void handlePragma(const TSourceLoc&, const TVector<TString>&);
void handlePragma(const TSourceLoc&, const TVector<TString>&) override;
TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
void checkIndex(const TSourceLoc&, const TType&, int& index);
void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
void makeEditable(TSymbol*&);
void makeEditable(TSymbol*&) override;
bool isIoResizeArray(const TType&) const;
void fixIoArraySize(const TSourceLoc&, TType&);
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);

View File

@ -638,13 +638,14 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
do {
parserToken = &token;
TPpToken ppToken;
tokenText = pp->tokenize(&ppToken);
if (tokenText == nullptr || tokenText[0] == 0)
int token = pp->tokenize(ppToken);
if (token == EndOfInput)
return 0;
tokenText = ppToken.name;
loc = ppToken.loc;
parserToken->sType.lex.loc = loc;
switch (ppToken.token) {
switch (token) {
case ';': afterType = false; return SEMICOLON;
case ',': afterType = false; return COMMA;
case ':': return COLON;
@ -673,11 +674,11 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
parseContext.error(loc, "illegal use of escape character", "\\", "");
break;
case PpAtomAdd: return ADD_ASSIGN;
case PpAtomSub: return SUB_ASSIGN;
case PpAtomMul: return MUL_ASSIGN;
case PpAtomDiv: return DIV_ASSIGN;
case PpAtomMod: return MOD_ASSIGN;
case PPAtomAddAssign: return ADD_ASSIGN;
case PPAtomSubAssign: return SUB_ASSIGN;
case PPAtomMulAssign: return MUL_ASSIGN;
case PPAtomDivAssign: return DIV_ASSIGN;
case PPAtomModAssign: return MOD_ASSIGN;
case PpAtomRight: return RIGHT_OP;
case PpAtomLeft: return LEFT_OP;
@ -720,7 +721,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
default:
char buf[2];
buf[0] = (char)ppToken.token;
buf[0] = token;
buf[1] = 0;
parseContext.error(loc, "unexpected token", buf, "");
break;

View File

@ -868,7 +868,7 @@ struct DoPreprocessing {
// This is a list of tokens that do not require a space before or after.
static const std::string unNeededSpaceTokens = ";()[]";
static const std::string noSpaceBeforeTokens = ",";
glslang::TPpToken token;
glslang::TPpToken ppToken;
parseContext.setScanner(&input);
ppContext.setInput(input, versionWillBeError);
@ -931,29 +931,33 @@ struct DoPreprocessing {
});
int lastToken = EndOfInput; // lastToken records the last token processed.
while (const char* tok = ppContext.tokenize(&token)) {
do {
int token = ppContext.tokenize(ppToken);
if (token == EndOfInput)
break;
bool isNewString = lineSync.syncToMostRecentString();
bool isNewLine = lineSync.syncToLine(token.loc.line);
bool isNewLine = lineSync.syncToLine(ppToken.loc.line);
if (isNewLine) {
// Don't emit whitespace onto empty lines.
// Copy any whitespace characters at the start of a line
// from the input to the output.
outputStream << std::string(token.loc.column - 1, ' ');
outputStream << std::string(ppToken.loc.column - 1, ' ');
}
// Output a space in between tokens, but not at the start of a line,
// and also not around special tokens. This helps with readability
// and consistency.
if (!isNewString && !isNewLine && lastToken != EndOfInput &&
(unNeededSpaceTokens.find((char)token.token) == std::string::npos) &&
(unNeededSpaceTokens.find((char)token) == std::string::npos) &&
(unNeededSpaceTokens.find((char)lastToken) == std::string::npos) &&
(noSpaceBeforeTokens.find((char)token.token) == std::string::npos)) {
(noSpaceBeforeTokens.find((char)token) == std::string::npos)) {
outputStream << " ";
}
lastToken = token.token;
outputStream << tok;
}
lastToken = token;
outputStream << ppToken.name;
} while (true);
outputStream << std::endl;
*outputString = outputStream.str();

View File

@ -195,6 +195,11 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_AMD_gpu_shader_half_float] = EBhDisable;
#endif
#ifdef NV_EXTENSIONS
extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable;
extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable;
#endif
// AEP
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable;
extensionBehavior[E_GL_KHR_blend_equation_advanced] = EBhDisable;
@ -302,6 +307,11 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_AMD_gcn_shader 1\n"
"#define GL_AMD_gpu_shader_half_float 1\n"
#endif
#ifdef NV_EXTENSIONS
"#define GL_NV_sample_mask_override_coverage 1\n"
"#define GL_NV_geometry_shader_passthrough 1\n"
#endif
;
}

View File

@ -142,6 +142,10 @@ const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader
const char* const E_GL_AMD_gcn_shader = "GL_AMD_gcn_shader";
const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_shader_half_float";
#endif
#ifdef NV_EXTENSIONS
const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough";
#endif
// AEP
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";

View File

@ -469,9 +469,17 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
case EShLangGeometry:
if (inputPrimitive == ElgNone)
error(infoSink, "At least one shader must specify an input layout primitive");
if (outputPrimitive == ElgNone)
if (outputPrimitive == ElgNone
#ifdef NV_EXTENSIONS
&& !getGeoPassthroughEXT()
#endif
)
error(infoSink, "At least one shader must specify an output layout primitive");
if (vertices == TQualifier::layoutNotSet)
if (vertices == TQualifier::layoutNotSet
#ifdef NV_EXTENSIONS
&& !getGeoPassthroughEXT()
#endif
)
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
break;
case EShLangFragment:

View File

@ -151,6 +151,10 @@ public:
shiftUboBinding(0),
autoMapBindings(false),
flattenUniformArrays(false),
#ifdef NV_EXTENSIONS
layoutOverrideCoverage(false),
geoPassthroughEXT(false),
#endif
useUnknownFormat(false)
{
localSize[0] = 1;
@ -387,6 +391,13 @@ public:
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
bool promote(TIntermOperator*);
#ifdef NV_EXTENSIONS
void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
#endif
protected:
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
void error(TInfoSink& infoSink, const char*);
@ -447,6 +458,11 @@ protected:
bool xfbMode;
bool multiStream;
#ifdef NV_EXTENSIONS
bool layoutOverrideCoverage;
bool geoPassthroughEXT;
#endif
typedef std::list<TCall> TGraph;
TGraph callGraph;

View File

@ -75,9 +75,6 @@ NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
//
// cpp.c
//
#define _CRT_SECURE_NO_WARNINGS
@ -91,20 +88,12 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace glslang {
int TPpContext::InitCPP()
{
pool = mem_CreatePool(0, 0);
return 1;
}
// Handle #define
int TPpContext::CPPdefine(TPpToken* ppToken)
{
MacroSymbol mac;
Symbol *symb;
// get macro name
// get the macro name
int token = scanToken(ppToken);
if (token != PpAtomIdentifier) {
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", "");
@ -115,38 +104,36 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#define");
}
// save the original atom
const int defAtom = ppToken->atom;
// save the macro name
const int defAtom = atomStrings.getAddAtom(ppToken->name);
// gather parameters to the macro, between (...)
token = scanToken(ppToken);
if (token == '(' && ! ppToken->space) {
int argc = 0;
int args[maxMacroArgs];
mac.emptyArgs = 1;
do {
token = scanToken(ppToken);
if (argc == 0 && token == ')')
if (mac.args.size() == 0 && token == ')')
break;
if (token != PpAtomIdentifier) {
parseContext.ppError(ppToken->loc, "bad argument", "#define", "");
return token;
}
mac.emptyArgs = 0;
const int argAtom = atomStrings.getAddAtom(ppToken->name);
// check for duplication of parameter name
bool duplicate = false;
for (int a = 0; a < argc; ++a) {
if (args[a] == ppToken->atom) {
for (size_t a = 0; a < mac.args.size(); ++a) {
if (mac.args[a] == argAtom) {
parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", "");
duplicate = true;
break;
}
}
if (! duplicate) {
if (argc < maxMacroArgs)
args[argc++] = ppToken->atom;
else
parseContext.ppError(ppToken->loc, "too many macro parameters", "#define", "");
}
if (! duplicate)
mac.args.push_back(argAtom);
token = scanToken(ppToken);
} while (token == ',');
if (token != ')') {
@ -154,15 +141,12 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
return token;
}
mac.argc = argc;
mac.args = (int*)mem_Alloc(pool, argc * sizeof(int));
memcpy(mac.args, args, argc * sizeof(int));
token = scanToken(ppToken);
}
// record the definition of the macro
TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors
mac.body = new TokenStream;
while (token != '\n' && token != EndOfInput) {
RecordToken(mac.body, token, ppToken);
token = scanToken(ppToken);
@ -171,40 +155,36 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
}
// check for duplicate definition
symb = LookUpSymbol(defAtom);
if (symb) {
if (! symb->mac.undef) {
MacroSymbol* existing = lookupMacroDef(defAtom);
if (existing != nullptr) {
if (! existing->undef) {
// Already defined -- need to make sure they are identical:
// "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
// ordering, spelling, and white-space separation, where all white-space separations are considered identical."
if (symb->mac.argc != mac.argc)
parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", GetAtomString(defAtom));
if (existing->args.size() != mac.args.size() || existing->emptyArgs != mac.emptyArgs)
parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
else {
for (int argc = 0; argc < mac.argc; argc++) {
if (symb->mac.args[argc] != mac.args[argc])
parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", GetAtomString(defAtom));
}
RewindTokenStream(symb->mac.body);
if (existing->args != mac.args)
parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom));
RewindTokenStream(existing->body);
RewindTokenStream(mac.body);
int newToken;
do {
int oldToken;
TPpToken oldPpToken;
TPpToken newPpToken;
oldToken = ReadToken(symb->mac.body, &oldPpToken);
oldToken = ReadToken(existing->body, &oldPpToken);
newToken = ReadToken(mac.body, &newPpToken);
if (oldToken != newToken || oldPpToken != newPpToken) {
parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", GetAtomString(defAtom));
parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom));
break;
}
} while (newToken > 0);
}
}
*existing = mac;
} else
symb = AddSymbol(defAtom);
delete symb->mac.body;
symb->mac = mac;
addMacroDef(defAtom, mac);
return '\n';
}
@ -213,7 +193,6 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
int TPpContext::CPPundef(TPpToken* ppToken)
{
int token = scanToken(ppToken);
Symbol *symb;
if (token != PpAtomIdentifier) {
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", "");
@ -222,10 +201,9 @@ int TPpContext::CPPundef(TPpToken* ppToken)
parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#undef");
symb = LookUpSymbol(ppToken->atom);
if (symb) {
symb->mac.undef = 1;
}
MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
if (macro != nullptr)
macro->undef = 1;
token = scanToken(ppToken);
if (token != '\n')
parseContext.ppError(ppToken->loc, "can only be followed by a single macro name", "#undef", "");
@ -240,7 +218,6 @@ int TPpContext::CPPundef(TPpToken* ppToken)
*/
int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
{
int atom;
int depth = 0;
int token = scanToken(ppToken);
@ -259,13 +236,13 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
if ((token = scanToken(ppToken)) != PpAtomIdentifier)
continue;
atom = ppToken->atom;
if (atom == PpAtomIf || atom == PpAtomIfdef || atom == PpAtomIfndef) {
int nextAtom = atomStrings.getAtom(ppToken->name);
if (nextAtom == PpAtomIf || nextAtom == PpAtomIfdef || nextAtom == PpAtomIfndef) {
depth++;
ifdepth++;
elsetracker++;
} else if (atom == PpAtomEndif) {
token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
} else if (nextAtom == PpAtomEndif) {
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
elseSeen[elsetracker] = false;
--elsetracker;
if (depth == 0) {
@ -277,12 +254,12 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
--depth;
--ifdepth;
} else if (matchelse && depth == 0) {
if (atom == PpAtomElse) {
if (nextAtom == PpAtomElse) {
elseSeen[elsetracker] = true;
token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
// found the #else we are looking for
break;
} else if (atom == PpAtomElif) {
} else if (nextAtom == PpAtomElif) {
if (elseSeen[elsetracker])
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
/* we decrement ifdepth here, because CPPif will increment
@ -295,13 +272,13 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
return CPPif(ppToken);
}
} else if (atom == PpAtomElse) {
} else if (nextAtom == PpAtomElse) {
if (elseSeen[elsetracker])
parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
else
elseSeen[elsetracker] = true;
token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
} else if (atom == PpAtomElif) {
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
} else if (nextAtom == PpAtomElif) {
if (elseSeen[elsetracker])
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
}
@ -311,21 +288,21 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
}
// Call when there should be no more tokens left on a line.
int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
int TPpContext::extraTokenCheck(int contextAtom, TPpToken* ppToken, int token)
{
if (token != '\n' && token != EndOfInput) {
static const char* message = "unexpected tokens following directive";
const char* label;
if (atom == PpAtomElse)
if (contextAtom == PpAtomElse)
label = "#else";
else if (atom == PpAtomElif)
else if (contextAtom == PpAtomElif)
label = "#elif";
else if (atom == PpAtomEndif)
else if (contextAtom == PpAtomEndif)
label = "#endif";
else if (atom == PpAtomIf)
else if (contextAtom == PpAtomIf)
label = "#if";
else if (atom == PpAtomLine)
else if (contextAtom == PpAtomLine)
label = "#line";
else
label = "";
@ -413,7 +390,7 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
{
TSourceLoc loc = ppToken->loc; // because we sometimes read the newline before reporting the error
if (token == PpAtomIdentifier) {
if (ppToken->atom == PpAtomDefined) {
if (strcmp("defined", ppToken->name) == 0) {
bool needclose = 0;
token = scanToken(ppToken);
if (token == '(') {
@ -427,8 +404,9 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
return token;
}
Symbol* s = LookUpSymbol(ppToken->atom);
res = s ? ! s->mac.undef : 0;
MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
res = macro != nullptr ? !macro->undef : 0;
token = scanToken(ppToken);
if (needclose) {
if (token != ')') {
@ -520,8 +498,8 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
// Expand macros, skipping empty expansions, to get to the first real token in those expansions.
int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken* ppToken)
{
while (token == PpAtomIdentifier && ppToken->atom != PpAtomDefined) {
int macroReturn = MacroExpand(ppToken->atom, ppToken, true, false);
while (token == PpAtomIdentifier && strcmp("defined", ppToken->name) != 0) {
int macroReturn = MacroExpand(ppToken, true, false);
if (macroReturn == 0) {
parseContext.ppError(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
err = true;
@ -568,7 +546,6 @@ int TPpContext::CPPif(TPpToken* ppToken)
int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
{
int token = scanToken(ppToken);
int name = ppToken->atom;
if (++ifdepth > maxIfNesting) {
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
return 0;
@ -580,14 +557,14 @@ int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
else
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", "");
} else {
Symbol *s = LookUpSymbol(name);
MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
token = scanToken(ppToken);
if (token != '\n') {
parseContext.ppError(ppToken->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", "");
while (token != '\n' && token != EndOfInput)
token = scanToken(ppToken);
}
if (((s && !s->mac.undef) ? 1 : 0) != defined)
if (((macro != nullptr && !macro->undef) ? 1 : 0) != defined)
token = CPPelse(1, ppToken);
}
@ -674,7 +651,7 @@ int TPpContext::CPPline(TPpToken* ppToken)
// We need to save a copy of the string instead of pointing
// to the name field of the token since the name field
// will likely be overwritten by the next token scan.
sourceName = GetAtomString(LookUpAddString(ppToken->name));
sourceName = atomStrings.getString(atomStrings.getAddAtom(ppToken->name));
parseContext.setCurrentSourceName(sourceName);
hasFile = true;
token = scanToken(ppToken);
@ -713,7 +690,7 @@ int TPpContext::CPPerror(TPpToken* ppToken)
} else if (token == PpAtomIdentifier || token == PpAtomConstString) {
message.append(ppToken->name);
} else {
message.append(GetAtomString(token));
message.append(atomStrings.getString(token));
}
message.append(" ");
token = scanToken(ppToken);
@ -790,9 +767,10 @@ int TPpContext::CPPversion(TPpToken* ppToken)
parseContext.notifyVersion(line, versionNumber, nullptr);
return token;
} else {
if (ppToken->atom != PpAtomCore &&
ppToken->atom != PpAtomCompatibility &&
ppToken->atom != PpAtomEs)
int profileAtom = atomStrings.getAtom(ppToken->name);
if (profileAtom != PpAtomCore &&
profileAtom != PpAtomCompatibility &&
profileAtom != PpAtomEs)
parseContext.ppError(ppToken->loc, "bad profile name; use es, core, or compatibility", "#version", "");
parseContext.notifyVersion(line, versionNumber, ppToken->name);
token = scanToken(ppToken);
@ -853,7 +831,7 @@ int TPpContext::readCPPline(TPpToken* ppToken)
int token = scanToken(ppToken);
if (token == PpAtomIdentifier) {
switch (ppToken->atom) {
switch (atomStrings.getAtom(ppToken->name)) {
case PpAtomDefine:
token = CPPdefine(ppToken);
break;
@ -933,36 +911,42 @@ int TPpContext::readCPPline(TPpToken* ppToken)
return token;
}
TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream* a, TPpToken* ppToken, bool newLineOkay)
// Macro-expand a macro argument 'arg' to create 'expandedArg'.
// Does not replace 'arg'.
// Returns nullptr if no expanded argument is created.
TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* ppToken, bool newLineOkay)
{
// pre-check, to see if anything in the argument needs to be expanded,
// to see if we can kick out early
int token;
TokenStream *n;
RewindTokenStream(a);
RewindTokenStream(arg);
do {
token = ReadToken(a, ppToken);
if (token == PpAtomIdentifier && LookUpSymbol(ppToken->atom))
token = ReadToken(arg, ppToken);
if (token == PpAtomIdentifier && lookupMacroDef(atomStrings.getAtom(ppToken->name)) != nullptr)
break;
} while (token != EndOfInput);
// if nothing needs to be expanded, kick out early
if (token == EndOfInput)
return a;
return nullptr;
n = new TokenStream;
// expand the argument
TokenStream* expandedArg = new TokenStream;
pushInput(new tMarkerInput(this));
pushTokenStreamInput(a);
pushTokenStreamInput(arg);
while ((token = scanToken(ppToken)) != tMarkerInput::marker) {
if (token == PpAtomIdentifier && MacroExpand(ppToken->atom, ppToken, false, newLineOkay) != 0)
if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0)
continue;
RecordToken(n, token, ppToken);
RecordToken(*expandedArg, token, ppToken);
}
popInput();
delete a;
return n;
return expandedArg;
}
//
// Return the next token for a macro expansion, handling macro args.
// Return the next token for a macro expansion, handling macro arguments,
// whose semantics are dependent on being adjacent to ##.
//
int TPpContext::tMacroInput::scan(TPpToken* ppToken)
{
@ -971,14 +955,50 @@ int TPpContext::tMacroInput::scan(TPpToken* ppToken)
token = pp->ReadToken(mac->body, ppToken);
} while (token == ' '); // handle white space in macro
// Hash operators basically turn off a round of macro substitution
// (the round done on the argument before the round done on the RHS of the
// macro definition):
//
// "A parameter in the replacement list, unless preceded by a # or ##
// preprocessing token or followed by a ## preprocessing token (see below),
// is replaced by the corresponding argument after all macros contained
// therein have been expanded."
//
// "If, in the replacement list, a parameter is immediately preceded or
// followed by a ## preprocessing token, the parameter is replaced by the
// corresponding argument's preprocessing token sequence."
bool pasting = false;
if (postpaste) {
// don't expand next token
pasting = true;
postpaste = false;
}
if (prepaste) {
// already know we should be on a ##, verify
assert(token == PpAtomPaste);
prepaste = false;
postpaste = true;
}
// see if are preceding a ##
if (peekMacPasting()) {
prepaste = true;
pasting = true;
}
// TODO: preprocessor: properly handle whitespace (or lack of it) between tokens when expanding
if (token == PpAtomIdentifier) {
int i;
for (i = mac->argc - 1; i >= 0; i--)
if (mac->args[i] == ppToken->atom)
for (i = mac->args.size() - 1; i >= 0; i--)
if (strcmp(pp->atomStrings.getString(mac->args[i]), ppToken->name) == 0)
break;
if (i >= 0) {
pp->pushTokenStreamInput(args[i]);
TokenStream* arg = expandedArgs[i];
if (arg == nullptr || pasting)
arg = args[i];
pp->pushTokenStreamInput(*arg, prepaste);
return pp->scanToken(ppToken);
}
@ -990,6 +1010,31 @@ int TPpContext::tMacroInput::scan(TPpToken* ppToken)
return token;
}
// See if the next non-white-space token in the macro is ##
bool TPpContext::tMacroInput::peekMacPasting()
{
// don't return early, have to restore this
size_t savePos = mac->body.current;
// skip white-space
int ltoken;
do {
ltoken = pp->lReadByte(mac->body);
} while (ltoken == ' ');
// check for ##
bool pasting = false;
if (ltoken == '#') {
ltoken = pp->lReadByte(mac->body);
if (ltoken == '#')
pasting = true;
}
mac->body.current = savePos;
return pasting;
}
// return a textual zero, for scanning a macro that was never defined
int TPpContext::tZeroInput::scan(TPpToken* ppToken)
{
@ -1005,17 +1050,18 @@ int TPpContext::tZeroInput::scan(TPpToken* ppToken)
}
//
// Check an identifier (atom) to see if it is a macro that should be expanded.
// Check a token to see if it is a macro that should be expanded.
// If it is, and defined, push a tInput that will produce the appropriate expansion
// and return 1.
// If it is, but undefined, and expandUndef is requested, push a tInput that will
// expand to 0 and return -1.
// Otherwise, return 0 to indicate no expansion, which is not necessarily an error.
//
int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool newLineOkay)
int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay)
{
ppToken->space = false;
switch (atom) {
int macroAtom = atomStrings.getAtom(ppToken->name);
switch (macroAtom) {
case PpAtomLineMacro:
ppToken->ival = parseContext.getCurrentLoc().line;
snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
@ -1041,20 +1087,20 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
break;
}
Symbol *sym = LookUpSymbol(atom);
MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom);
int token;
int depth = 0;
// no recursive expansions
if (sym && sym->mac.busy)
if (macro != nullptr && macro->busy)
return 0;
// not expanding undefined macros
if ((! sym || sym->mac.undef) && ! expandUndef)
if ((macro == nullptr || macro->undef) && ! expandUndef)
return 0;
// 0 is the value of an undefined macro
if ((! sym || sym->mac.undef) && expandUndef) {
if ((macro == nullptr || macro->undef) && expandUndef) {
pushInput(new tZeroInput(this));
return -1;
}
@ -1062,49 +1108,50 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
tMacroInput *in = new tMacroInput(this);
TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error
in->mac = &sym->mac;
if (sym->mac.args) {
in->mac = macro;
if (macro->args.size() > 0 || macro->emptyArgs) {
token = scanToken(ppToken);
if (newLineOkay) {
while (token == '\n')
token = scanToken(ppToken);
}
if (token != '(') {
parseContext.ppError(loc, "expected '(' following", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "expected '(' following", "macro expansion", atomStrings.getString(macroAtom));
UngetToken(token, ppToken);
ppToken->atom = atom;
delete in;
return 0;
}
in->args.resize(in->mac->argc);
for (int i = 0; i < in->mac->argc; i++)
in->args.resize(in->mac->args.size());
for (size_t i = 0; i < in->mac->args.size(); i++)
in->args[i] = new TokenStream;
int arg = 0;
in->expandedArgs.resize(in->mac->args.size());
for (size_t i = 0; i < in->mac->args.size(); i++)
in->expandedArgs[i] = nullptr;
size_t arg = 0;
bool tokenRecorded = false;
do {
depth = 0;
while (1) {
token = scanToken(ppToken);
if (token == EndOfInput) {
parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
delete in;
return 0;
}
if (token == '\n') {
if (! newLineOkay) {
parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", atomStrings.getString(macroAtom));
delete in;
return 0;
}
continue;
}
if (token == '#') {
parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", GetAtomString(atom));
parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", atomStrings.getString(macroAtom));
delete in;
return 0;
}
if (in->mac->argc == 0 && token != ')')
if (in->mac->args.size() == 0 && token != ')')
break;
if (depth == 0 && (token == ',' || token == ')'))
break;
@ -1112,20 +1159,20 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
depth++;
if (token == ')')
depth--;
RecordToken(in->args[arg], token, ppToken);
RecordToken(*in->args[arg], token, ppToken);
tokenRecorded = true;
}
if (token == ')') {
if (in->mac->argc == 1 && tokenRecorded == 0)
if (in->mac->args.size() == 1 && tokenRecorded == 0)
break;
arg++;
break;
}
arg++;
} while (arg < in->mac->argc);
} while (arg < in->mac->args.size());
if (arg < in->mac->argc)
parseContext.ppError(loc, "Too few args in Macro", "macro expansion", GetAtomString(atom));
if (arg < in->mac->args.size())
parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom));
else if (token != ')') {
depth=0;
while (token != EndOfInput && (depth > 0 || token != ')')) {
@ -1137,19 +1184,22 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
}
if (token == EndOfInput) {
parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
delete in;
return 0;
}
parseContext.ppError(loc, "Too many args in macro", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "Too many args in macro", "macro expansion", atomStrings.getString(macroAtom));
}
for (int i = 0; i < in->mac->argc; i++)
in->args[i] = PrescanMacroArg(in->args[i], ppToken, newLineOkay);
// We need both expanded and non-expanded forms of the argument, for whether or
// not token pasting is in play.
for (size_t i = 0; i < in->mac->args.size(); i++)
in->expandedArgs[i] = PrescanMacroArg(*in->args[i], ppToken, newLineOkay);
}
pushInput(in);
sym->mac.busy = 1;
RewindTokenStream(sym->mac.body);
macro->busy = 1;
RewindTokenStream(macro->body);
return 1;
}

View File

@ -76,10 +76,6 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
//
// atom.c
//
#define _CRT_SECURE_NO_WARNINGS
#include <cassert>
@ -98,11 +94,12 @@ const struct {
const char* str;
} tokens[] = {
{ PpAtomAdd, "+=" },
{ PpAtomSub, "-=" },
{ PpAtomMul, "*=" },
{ PpAtomDiv, "/=" },
{ PpAtomMod, "%=" },
{ PPAtomAddAssign, "+=" },
{ PPAtomSubAssign, "-=" },
{ PPAtomMulAssign, "*=" },
{ PPAtomDivAssign, "/=" },
{ PPAtomModAssign, "%=" },
{ PpAtomRight, ">>" },
{ PpAtomLeft, "<<" },
{ PpAtomAnd, "&&" },
@ -124,7 +121,6 @@ const struct {
{ PpAtomIncrement, "++" },
{ PpAtomDefine, "define" },
{ PpAtomDefined, "defined" },
{ PpAtomUndef, "undef" },
{ PpAtomIf, "if" },
{ PpAtomElif, "elif" },
@ -153,48 +149,13 @@ const struct {
namespace glslang {
//
// Map a new or existing string to an atom, inventing a new atom if necessary.
//
int TPpContext::LookUpAddString(const char* s)
{
auto it = atomMap.find(s);
if (it == atomMap.end()) {
AddAtomFixed(s, nextAtom);
return nextAtom++;
} else
return it->second;
}
//
// Map an already created atom to its string.
//
const char* TPpContext::GetAtomString(int atom)
{
if ((size_t)atom >= stringMap.size())
return "<bad token>";
const TString* atomString = stringMap[atom];
return atomString ? atomString->c_str() : "<bad token>";
}
//
// Add forced mapping of string to atom.
//
void TPpContext::AddAtomFixed(const char* s, int atom)
{
auto it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
if (stringMap.size() < (size_t)atom + 1)
stringMap.resize(atom + 100, 0);
stringMap[atom] = &it->first;
}
//
// Initialize the atom table.
//
void TPpContext::InitAtomTable()
TStringAtomMap::TStringAtomMap()
{
badToken.assign("<bad token>");
// Add single character tokens to the atom table:
const char* s = "~!%^&*()-+=|,.<>/?;:[]{}#\\";
char t[2];
@ -202,13 +163,13 @@ void TPpContext::InitAtomTable()
t[1] = '\0';
while (*s) {
t[0] = *s;
AddAtomFixed(t, s[0]);
addAtomFixed(t, s[0]);
s++;
}
// Add multiple character scanner tokens :
for (size_t ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
AddAtomFixed(tokens[ii].str, tokens[ii].val);
addAtomFixed(tokens[ii].str, tokens[ii].val);
nextAtom = PpAtomLast;
}

View File

@ -83,13 +83,10 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace glslang {
TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
preamble(0), strings(0), parseContext(pc), includer(inclr), inComment(false),
preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
rootFileName(rootFileName),
currentSourceFile(rootFileName)
{
InitAtomTable();
InitScanner();
ifdepth = 0;
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
elseSeen[elsetracker] = false;
@ -98,9 +95,6 @@ TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, T
TPpContext::~TPpContext()
{
for (TSymbolMap::iterator it = symbols.begin(); it != symbols.end(); ++it)
delete it->second->mac.body;
mem_FreePool(pool);
delete [] preamble;
// free up the inputStack

View File

@ -92,30 +92,85 @@ namespace glslang {
class TPpToken {
public:
TPpToken() : token(0), space(false), ival(0), dval(0.0), atom(0)
TPpToken() : space(false), ival(0), dval(0.0), i64val(0)
{
loc.init();
name[0] = 0;
}
// This is used for comparing macro definitions, so checks what is relevant for that.
bool operator==(const TPpToken& right)
{
return token == right.token && atom == right.atom &&
ival == right.ival && dval == right.dval &&
strcmp(name, right.name) == 0;
return space == right.space &&
ival == right.ival && dval == right.dval && i64val == right.i64val &&
strncmp(name, right.name, MaxTokenLength) == 0;
}
bool operator!=(const TPpToken& right) { return ! operator==(right); }
TSourceLoc loc;
int token;
bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned
int ival;
double dval;
long long i64val;
int atom;
char name[MaxTokenLength + 1];
};
class TStringAtomMap {
//
// Implementation is in PpAtom.cpp
//
// Maintain a bi-directional mapping between relevant preprocessor strings and
// "atoms" which a unique integers (small, contiguous, not hash-like) per string.
//
public:
TStringAtomMap();
// Map string -> atom.
// Return 0 if no existing string.
int getAtom(const char* s) const
{
auto it = atomMap.find(s);
return it == atomMap.end() ? 0 : it->second;
}
// Map a new or existing string -> atom, inventing a new atom if necessary.
int getAddAtom(const char* s)
{
int atom = getAtom(s);
if (atom == 0) {
atom = nextAtom++;
addAtomFixed(s, atom);
}
return atom;
}
// Map atom -> string.
const char* getString(int atom) const { return stringMap[atom]->c_str(); }
protected:
TStringAtomMap(TStringAtomMap&);
TStringAtomMap& operator=(TStringAtomMap&);
TUnorderedMap<TString, int> atomMap;
TVector<const TString*> stringMap; // these point into the TString in atomMap
int nextAtom;
// Bad source characters can lead to bad atoms, so gracefully handle those by
// pre-filling the table with them (to avoid if tests later).
TString badToken;
// Add bi-directional mappings:
// - string -> atom
// - atom -> string
void addAtomFixed(const char* s, int atom)
{
auto it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
if (stringMap.size() < (size_t)atom + 1)
stringMap.resize(atom + 100, &badToken);
stringMap[atom] = &it->first;
}
};
class TInputScanner;
// This class is the result of turning a huge pile of C code communicating through globals
@ -128,7 +183,8 @@ public:
void setPreamble(const char* preamble, size_t length);
const char* tokenize(TPpToken* ppToken);
int tokenize(TPpToken& ppToken);
int tokenPaste(int token, TPpToken&);
class tInput {
public:
@ -138,6 +194,8 @@ public:
virtual int scan(TPpToken*) = 0;
virtual int getch() = 0;
virtual void ungetch() = 0;
virtual bool peekPasting() { return false; } // true when about to see ##
virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
// Will be called when we start reading tokens from this instance
virtual void notifyActivated() {}
@ -168,44 +226,33 @@ public:
size_t current;
};
struct MemoryPool {
struct chunk *next;
uintptr_t free, end;
size_t chunksize;
uintptr_t alignmask;
};
//
// From Pp.cpp
//
struct MacroSymbol {
MacroSymbol() : argc(0), args(0), body(0), busy(0), undef(0) { }
int argc;
int *args;
TokenStream *body;
unsigned busy:1;
unsigned undef:1;
MacroSymbol() : emptyArgs(0), busy(0), undef(0) { }
TVector<int> args;
TokenStream body;
unsigned emptyArgs : 1;
unsigned busy : 1;
unsigned undef : 1;
};
struct Symbol {
int atom;
MacroSymbol mac;
};
struct SymbolList {
struct SymbolList_Rec *next;
Symbol *symb;
};
MemoryPool *pool;
typedef TMap<int, Symbol*> TSymbolMap;
TSymbolMap symbols; // this has light use... just defined macros
typedef TMap<int, MacroSymbol> TSymbolMap;
TSymbolMap macroDefs; // map atoms to macro definitions
MacroSymbol* lookupMacroDef(int atom)
{
auto existingMacroIt = macroDefs.find(atom);
return (existingMacroIt == macroDefs.end()) ? nullptr : &(existingMacroIt->second);
}
void addMacroDef(int atom, MacroSymbol& macroDef) { macroDefs[atom] = macroDef; }
protected:
TPpContext(TPpContext&);
TPpContext& operator=(TPpContext&);
TStringAtomMap atomStrings;
char* preamble; // string to parse, all before line 1 of string 0, it is 0 if no preamble
int preambleLength;
char** strings; // official strings of shader, starting a string 0 line 1
@ -235,8 +282,9 @@ protected:
}
int getChar() { return inputStack.back()->getch(); }
void ungetChar() { inputStack.back()->ungetch(); }
bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
static const int maxMacroArgs = 64;
static const int maxIfNesting = 64;
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
@ -245,24 +293,35 @@ protected:
class tMacroInput : public tInput {
public:
tMacroInput(TPpContext* pp) : tInput(pp) { }
tMacroInput(TPpContext* pp) : tInput(pp), prepaste(false), postpaste(false) { }
virtual ~tMacroInput()
{
for (size_t i = 0; i < args.size(); ++i)
delete args[i];
for (size_t i = 0; i < expandedArgs.size(); ++i)
delete expandedArgs[i];
}
virtual int scan(TPpToken*);
virtual int getch() { assert(0); return EndOfInput; }
virtual void ungetch() { assert(0); }
virtual int scan(TPpToken*) override;
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
bool peekPasting() override { return prepaste; }
bool endOfReplacementList() override { return mac->body.current >= mac->body.data.size(); }
MacroSymbol *mac;
TVector<TokenStream*> args;
TVector<TokenStream*> expandedArgs;
protected:
bool peekMacPasting();
bool prepaste; // true if we are just before ##
bool postpaste; // true if we are right after ##
};
class tMarkerInput : public tInput {
public:
tMarkerInput(TPpContext* pp) : tInput(pp) { }
virtual int scan(TPpToken*)
virtual int scan(TPpToken*) override
{
if (done)
return EndOfInput;
@ -270,17 +329,17 @@ protected:
return marker;
}
virtual int getch() { assert(0); return EndOfInput; }
virtual void ungetch() { assert(0); }
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
static const int marker = -3;
};
class tZeroInput : public tInput {
public:
tZeroInput(TPpContext* pp) : tInput(pp) { }
virtual int scan(TPpToken*);
virtual int getch() { assert(0); return EndOfInput; }
virtual void ungetch() { assert(0); }
virtual int scan(TPpToken*) override;
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
};
std::vector<tInput*> inputStack;
@ -294,7 +353,6 @@ protected:
// Used to obtain #include content.
TShader::Includer& includer;
int InitCPP();
int CPPdefine(TPpToken * ppToken);
int CPPundef(TPpToken * ppToken);
int CPPelse(int matchelse, TPpToken * ppToken);
@ -310,44 +368,39 @@ protected:
int CPPversion(TPpToken * ppToken);
int CPPextension(TPpToken * ppToken);
int readCPPline(TPpToken * ppToken);
TokenStream* PrescanMacroArg(TokenStream *a, TPpToken * ppToken, bool newLineOkay);
int MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool newLineOkay);
//
// from PpSymbols.cpp
//
Symbol *NewSymbol(int name);
Symbol *AddSymbol(int atom);
Symbol *LookUpSymbol(int atom);
TokenStream* PrescanMacroArg(TokenStream&, TPpToken*, bool newLineOkay);
int MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay);
//
// From PpTokens.cpp
//
void lAddByte(TokenStream *fTok, unsigned char fVal);
int lReadByte(TokenStream *pTok);
void lUnreadByte(TokenStream *pTok);
void RecordToken(TokenStream* pTok, int token, TPpToken* ppToken);
void RewindTokenStream(TokenStream *pTok);
int ReadToken(TokenStream* pTok, TPpToken* ppToken);
void pushTokenStreamInput(TokenStream *ts);
void UngetToken(int token, TPpToken* ppToken);
void lAddByte(TokenStream&, unsigned char fVal);
int lReadByte(TokenStream&);
void lUnreadByte(TokenStream&);
void RecordToken(TokenStream&, int token, TPpToken* ppToken);
void RewindTokenStream(TokenStream&);
int ReadToken(TokenStream&, TPpToken*);
void pushTokenStreamInput(TokenStream&, bool pasting = false);
void UngetToken(int token, TPpToken*);
class tTokenInput : public tInput {
public:
tTokenInput(TPpContext* pp, TokenStream* t) : tInput(pp), tokens(t) { }
virtual int scan(TPpToken *);
virtual int getch() { assert(0); return EndOfInput; }
virtual void ungetch() { assert(0); }
tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : tInput(pp), tokens(t), lastTokenPastes(prepasting) { }
virtual int scan(TPpToken *) override;
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
virtual bool peekPasting() override;
protected:
TokenStream *tokens;
TokenStream* tokens;
bool lastTokenPastes; // true if the last token in the input is to be pasted, rather than consumed as a token
};
class tUngotTokenInput : public tInput {
public:
tUngotTokenInput(TPpContext* pp, int t, TPpToken* p) : tInput(pp), token(t), lval(*p) { }
virtual int scan(TPpToken *);
virtual int getch() { assert(0); return EndOfInput; }
virtual void ungetch() { assert(0); }
virtual int scan(TPpToken *) override;
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
protected:
int token;
TPpToken lval;
@ -359,12 +412,12 @@ protected:
class tStringInput : public tInput {
public:
tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { }
virtual int scan(TPpToken*);
virtual int scan(TPpToken*) override;
// Scanner used to get source stream characters.
// - Escaped newlines are handled here, invisibly to the caller.
// - All forms of newline are handled, and turned into just a '\n'.
int getch()
int getch() override
{
int ch = input->get();
@ -402,7 +455,7 @@ protected:
// handled here, invisibly to the caller, meaning have to undo exactly
// what getch() above does (e.g., don't leave things in the middle of a
// sequence of escaped newlines).
void ungetch()
void ungetch() override
{
input->unget();
@ -516,7 +569,6 @@ protected:
tStringInput stringInput;
};
int InitScanner();
int ScanFromString(char* s);
void missingEndifCheck();
int lFloatConst(int len, int ch, TPpToken* ppToken);
@ -540,31 +592,9 @@ protected:
}
bool inComment;
//
// From PpAtom.cpp
//
typedef TUnorderedMap<TString, int> TAtomMap;
typedef TVector<const TString*> TStringMap;
TAtomMap atomMap;
TStringMap stringMap;
std::string rootFileName;
std::stack<TShader::Includer::IncludeResult*> includeStack;
std::string currentSourceFile;
std::string rootFileName;
int nextAtom;
void InitAtomTable();
void AddAtomFixed(const char* s, int atom);
int LookUpAddString(const char* s);
const char* GetAtomString(int atom);
//
// From PpMemory.cpp
//
MemoryPool *mem_CreatePool(size_t chunksize, unsigned align);
void mem_FreePool(MemoryPool*);
void *mem_Alloc(MemoryPool* p, size_t size);
int mem_AddCleanup(MemoryPool* p, void (*fn)(void *, void*), void* arg1, void* arg2);
};
} // end namespace glslang

View File

@ -76,86 +76,6 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include "PpContext.h"
// default alignment and chunksize, if called with 0 arguments
#define CHUNKSIZE (64*1024)
#define ALIGN 8
namespace glslang {
struct chunk {
struct chunk *next;
};
TPpContext::MemoryPool* TPpContext::mem_CreatePool(size_t chunksize, unsigned int align)
{
if (align == 0)
align = ALIGN;
if (chunksize == 0)
chunksize = CHUNKSIZE;
if (align & (align - 1))
return nullptr;
if (chunksize < sizeof(MemoryPool))
return nullptr;
if (chunksize & (align - 1))
return nullptr;
MemoryPool *pool = (MemoryPool*)malloc(chunksize);
if (! pool)
return nullptr;
pool->next = 0;
pool->chunksize = chunksize;
pool->alignmask = (uintptr_t)(align) - 1;
pool->free = ((uintptr_t)(pool + 1) + pool->alignmask) & ~pool->alignmask;
pool->end = (uintptr_t)pool + chunksize;
return pool;
}
void TPpContext::mem_FreePool(MemoryPool *pool)
{
struct chunk *p, *next;
for (p = (struct chunk *)pool; p; p = next) {
next = p->next;
free(p);
}
}
void* TPpContext::mem_Alloc(MemoryPool *pool, size_t size)
{
struct chunk *ch;
void *rv = (void *)pool->free;
size = (size + pool->alignmask) & ~pool->alignmask;
if (size <= 0) size = pool->alignmask;
pool->free += size;
if (pool->free > pool->end || pool->free < (uintptr_t)rv) {
size_t minreq = (size + sizeof(struct chunk) + pool->alignmask) & ~pool->alignmask;
pool->free = (uintptr_t)rv;
if (minreq >= pool->chunksize) {
// request size is too big for the chunksize, so allocate it as
// a single chunk of the right size
ch = (struct chunk*)malloc(minreq);
if (! ch)
return nullptr;
} else {
ch = (struct chunk*)malloc(pool->chunksize);
if (! ch)
return nullptr;
pool->free = (uintptr_t)ch + minreq;
pool->end = (uintptr_t)ch + pool->chunksize;
}
ch->next = pool->next;
pool->next = ch;
rv = (void *)(((uintptr_t)(ch+1) + pool->alignmask) & ~pool->alignmask);
}
return rv;
}
} // end namespace glslang

View File

@ -75,9 +75,6 @@ NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
//
// scanner.c
//
#define _CRT_SECURE_NO_WARNINGS
@ -90,17 +87,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace glslang {
int TPpContext::InitScanner()
{
// Add various atoms needed by the CPP line scanner:
if (!InitCPP())
return 0;
previous_token = '\n';
return 1;
}
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Floating point constants: /////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
@ -261,7 +247,6 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
//
int TPpContext::tStringInput::scan(TPpToken* ppToken)
{
char* tokenText = ppToken->name;
int AlreadyComplained = 0;
int len = 0;
int ch = 0;
@ -300,7 +285,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
case 'z':
do {
if (len < MaxTokenLength) {
tokenText[len++] = (char)ch;
ppToken->name[len++] = (char)ch;
ch = getch();
} else {
if (! AlreadyComplained) {
@ -318,9 +303,8 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
if (len == 0)
continue;
tokenText[len] = '\0';
ppToken->name[len] = '\0';
ungetch();
ppToken->atom = pp->LookUpAddString(tokenText);
return PpAtomIdentifier;
case '0':
ppToken->name[len++] = (char)ch;
@ -545,7 +529,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
if (ch == '-') {
return PpAtomDecrement;
} else if (ch == '=') {
return PpAtomSub;
return PPAtomSubAssign;
} else {
ungetch();
return '-';
@ -555,7 +539,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
if (ch == '+') {
return PpAtomIncrement;
} else if (ch == '=') {
return PpAtomAdd;
return PPAtomAddAssign;
} else {
ungetch();
return '+';
@ -563,7 +547,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
case '*':
ch = getch();
if (ch == '=') {
return PpAtomMul;
return PPAtomMulAssign;
} else {
ungetch();
return '*';
@ -571,7 +555,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
case '%':
ch = getch();
if (ch == '=') {
return PpAtomMod;
return PPAtomModAssign;
} else {
ungetch();
return '%';
@ -697,7 +681,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
// loop again to get the next token...
break;
} else if (ch == '=') {
return PpAtomDiv;
return PPAtomDivAssign;
} else {
ungetch();
return '/';
@ -707,13 +691,13 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ch = getch();
while (ch != '"' && ch != '\n' && ch != EndOfInput) {
if (len < MaxTokenLength) {
tokenText[len] = (char)ch;
ppToken->name[len] = (char)ch;
len++;
ch = getch();
} else
break;
};
tokenText[len] = '\0';
ppToken->name[len] = '\0';
if (ch != '"') {
ungetch();
pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", "");
@ -729,31 +713,31 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
// The main functional entry point into the preprocessor, which will
// scan the source strings to figure out and return the next processing token.
//
// Return string pointer to next token.
// Return 0 when no more tokens.
// Return the token, or EndOfInput when no more tokens.
//
const char* TPpContext::tokenize(TPpToken* ppToken)
int TPpContext::tokenize(TPpToken& ppToken)
{
int token = '\n';
for(;;) {
token = scanToken(ppToken);
ppToken->token = token;
int token = scanToken(&ppToken);
// Handle token-pasting logic
token = tokenPaste(token, ppToken);
if (token == EndOfInput) {
missingEndifCheck();
return nullptr;
return EndOfInput;
}
if (token == '#') {
if (previous_token == '\n') {
token = readCPPline(ppToken);
token = readCPPline(&ppToken);
if (token == EndOfInput) {
missingEndifCheck();
return nullptr;
return EndOfInput;
}
continue;
} else {
parseContext.ppError(ppToken->loc, "preprocessor directive cannot be preceded by another token", "#", "");
return nullptr;
parseContext.ppError(ppToken.loc, "preprocessor directive cannot be preceded by another token", "#", "");
return EndOfInput;
}
}
previous_token = token;
@ -762,10 +746,9 @@ const char* TPpContext::tokenize(TPpToken* ppToken)
continue;
// expand macros
if (token == PpAtomIdentifier && MacroExpand(ppToken->atom, ppToken, false, true) != 0)
if (token == PpAtomIdentifier && MacroExpand(&ppToken, false, true) != 0)
continue;
const char* tokenString = nullptr;
switch (token) {
case PpAtomIdentifier:
case PpAtomConstInt:
@ -777,29 +760,110 @@ const char* TPpContext::tokenize(TPpToken* ppToken)
#ifdef AMD_EXTENSIONS
case PpAtomConstFloat16:
#endif
tokenString = ppToken->name;
if (ppToken.name[0] == '\0')
continue;
break;
case PpAtomConstString:
if (parseContext.intermediate.getSource() == EShSourceHlsl) {
if (parseContext.intermediate.getSource() != EShSourceHlsl) {
// HLSL allows string literals.
tokenString = ppToken->name;
} else {
parseContext.ppError(ppToken->loc, "string literals not supported", "\"\"", "");
parseContext.ppError(ppToken.loc, "string literals not supported", "\"\"", "");
continue;
}
break;
case '\'':
parseContext.ppError(ppToken->loc, "character literals not supported", "\'", "");
break;
parseContext.ppError(ppToken.loc, "character literals not supported", "\'", "");
continue;
default:
tokenString = GetAtomString(token);
strcpy(ppToken.name, atomStrings.getString(token));
break;
}
if (tokenString)
return tokenString;
return token;
}
}
//
// Do all token-pasting related combining of two pasted tokens when getting a
// stream of tokens from a replacement list. Degenerates to no processing if a
// replacement list is not the source of the token stream.
//
int TPpContext::tokenPaste(int token, TPpToken& ppToken)
{
// starting with ## is illegal, skip to next token
if (token == PpAtomPaste) {
parseContext.ppError(ppToken.loc, "unexpected location", "##", "");
return scanToken(&ppToken);
}
int resultToken = token; // "foo" pasted with "35" is an identifier, not a number
// ## can be chained, process all in the chain at once
while (peekPasting()) {
TPpToken pastedPpToken;
// next token has to be ##
token = scanToken(&pastedPpToken);
assert(token == PpAtomPaste);
if (endOfReplacementList()) {
parseContext.ppError(ppToken.loc, "unexpected location; end of replacement list", "##", "");
break;
}
// get the token after the ##
token = scanToken(&pastedPpToken);
// get the token text
switch (resultToken) {
case PpAtomIdentifier:
// already have the correct text in token.names
break;
case '=':
case '!':
case '-':
case '~':
case '+':
case '*':
case '/':
case '%':
case '<':
case '>':
case '|':
case '^':
case '&':
case PpAtomRight:
case PpAtomLeft:
case PpAtomAnd:
case PpAtomOr:
case PpAtomXor:
strcpy(ppToken.name, atomStrings.getString(resultToken));
strcpy(pastedPpToken.name, atomStrings.getString(token));
break;
default:
parseContext.ppError(ppToken.loc, "not supported for these tokens", "##", "");
return resultToken;
}
// combine the tokens
if (strlen(ppToken.name) + strlen(pastedPpToken.name) > MaxTokenLength) {
parseContext.ppError(ppToken.loc, "combined tokens are too long", "##", "");
return resultToken;
}
strncat(ppToken.name, pastedPpToken.name, MaxTokenLength - strlen(ppToken.name));
// correct the kind of token we are making, if needed (identifiers stay identifiers)
if (resultToken != PpAtomIdentifier) {
int newToken = atomStrings.getAtom(ppToken.name);
if (newToken > 0)
resultToken = newToken;
else
parseContext.ppError(ppToken.loc, "combined token is invalid", "##", "");
}
}
return resultToken;
}
// Checks if we've seen balanced #if...#endif
void TPpContext::missingEndifCheck()
{

View File

@ -75,60 +75,3 @@ NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
//
// symbols.c
//
#include <cassert>
#include <cstdlib>
#include <cstring>
#include "PpContext.h"
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
namespace glslang {
/*
* Allocate a new symbol node;
*
*/
TPpContext::Symbol* TPpContext::NewSymbol(int atom)
{
Symbol* lSymb;
char* pch;
size_t ii;
lSymb = (Symbol *) mem_Alloc(pool, sizeof(Symbol));
lSymb->atom = atom;
// Clear macro
pch = (char*) &lSymb->mac;
for (ii = 0; ii < sizeof(lSymb->mac); ii++)
*pch++ = 0;
return lSymb;
}
TPpContext::Symbol* TPpContext::AddSymbol(int atom)
{
Symbol *lSymb;
lSymb = NewSymbol(atom);
symbols[lSymb->atom] = lSymb;
return lSymb;
}
TPpContext::Symbol* TPpContext::LookUpSymbol(int atom)
{
TSymbolMap::iterator it = symbols.find(atom);
if (it == symbols.end())
return nullptr;
else
return it->second;
}
} // end namespace glslang

View File

@ -95,32 +95,32 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace glslang {
void TPpContext::lAddByte(TokenStream *fTok, unsigned char fVal)
void TPpContext::lAddByte(TokenStream& fTok, unsigned char fVal)
{
fTok->data.push_back(fVal);
fTok.data.push_back(fVal);
}
/*
* Get the next byte from a stream.
*/
int TPpContext::lReadByte(TokenStream *pTok)
int TPpContext::lReadByte(TokenStream& pTok)
{
if (pTok->current < pTok->data.size())
return pTok->data[pTok->current++];
if (pTok.current < pTok.data.size())
return pTok.data[pTok.current++];
else
return EndOfInput;
}
void TPpContext::lUnreadByte(TokenStream *pTok)
void TPpContext::lUnreadByte(TokenStream& pTok)
{
if (pTok->current > 0)
--pTok->current;
if (pTok.current > 0)
--pTok.current;
}
/*
* Add a token to the end of a list for later playback.
*/
void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken* ppToken)
void TPpContext::RecordToken(TokenStream& pTok, int token, TPpToken* ppToken)
{
const char* s;
char* str = NULL;
@ -160,19 +160,18 @@ void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken* ppToken)
}
/*
* Reset a token stream in preperation for reading.
* Reset a token stream in preparation for reading.
*/
void TPpContext::RewindTokenStream(TokenStream *pTok)
void TPpContext::RewindTokenStream(TokenStream& pTok)
{
pTok->current = 0;
pTok.current = 0;
}
/*
* Read the next token from a token stream (not the source stream, but stream used to hold a tokenized macro).
*/
int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
int TPpContext::ReadToken(TokenStream& pTok, TPpToken *ppToken)
{
char* tokenText = ppToken->name;
int ltoken, len;
int ch;
@ -183,13 +182,11 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
switch (ltoken) {
case '#':
// Check for ##, unless the current # is the last character
if (pTok->current < pTok->data.size()) {
if (pTok.current < pTok.data.size()) {
if (lReadByte(pTok) == '#') {
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
parseContext.error(ppToken->loc, "token pasting not implemented (internal error)", "##", "");
//return PpAtomPaste;
return ReadToken(pTok, ppToken);
ltoken = PpAtomPaste;
} else
lUnreadByte(pTok);
}
@ -209,7 +206,7 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
ch = lReadByte(pTok);
while (ch != 0 && ch != EndOfInput) {
if (len < MaxTokenLength) {
tokenText[len] = (char)ch;
ppToken->name[len] = (char)ch;
len++;
ch = lReadByte(pTok);
} else {
@ -217,11 +214,10 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
break;
}
}
tokenText[len] = 0;
ppToken->name[len] = 0;
switch (ltoken) {
case PpAtomIdentifier:
ppToken->atom = LookUpAddString(tokenText);
break;
case PpAtomConstString:
break;
@ -233,8 +229,8 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
ppToken->dval = atof(ppToken->name);
break;
case PpAtomConstInt:
if (len > 0 && tokenText[0] == '0') {
if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
if (len > 0 && ppToken->name[0] == '0') {
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->ival = (int)strtol(ppToken->name, 0, 16);
else
ppToken->ival = (int)strtol(ppToken->name, 0, 8);
@ -242,8 +238,8 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
ppToken->ival = atoi(ppToken->name);
break;
case PpAtomConstUint:
if (len > 0 && tokenText[0] == '0') {
if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
if (len > 0 && ppToken->name[0] == '0') {
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->ival = (int)strtoul(ppToken->name, 0, 16);
else
ppToken->ival = (int)strtoul(ppToken->name, 0, 8);
@ -251,8 +247,8 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
ppToken->ival = (int)strtoul(ppToken->name, 0, 10);
break;
case PpAtomConstInt64:
if (len > 0 && tokenText[0] == '0') {
if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
if (len > 0 && ppToken->name[0] == '0') {
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->i64val = strtoll(ppToken->name, nullptr, 16);
else
ppToken->i64val = strtoll(ppToken->name, nullptr, 8);
@ -260,8 +256,8 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
ppToken->i64val = atoll(ppToken->name);
break;
case PpAtomConstUint64:
if (len > 0 && tokenText[0] == '0') {
if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
if (len > 0 && ppToken->name[0] == '0') {
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 16);
else
ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 8);
@ -276,12 +272,37 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
int TPpContext::tTokenInput::scan(TPpToken* ppToken)
{
return pp->ReadToken(tokens, ppToken);
return pp->ReadToken(*tokens, ppToken);
}
void TPpContext::pushTokenStreamInput(TokenStream* ts)
// We are pasting if the entire macro is preceding a pasting operator
// (lastTokenPastes) and we are also on the last token.
bool TPpContext::tTokenInput::peekPasting()
{
pushInput(new tTokenInput(this, ts));
if (! lastTokenPastes)
return false;
// Getting here means the last token will be pasted.
// Are we at the last non-whitespace token?
size_t savePos = tokens->current;
bool moreTokens = false;
do {
int byte = pp->lReadByte(*tokens);
if (byte == EndOfInput)
break;
if (byte != ' ') {
moreTokens = true;
break;
}
} while (true);
tokens->current = savePos;
return !moreTokens;
}
void TPpContext::pushTokenStreamInput(TokenStream& ts, bool prepasting)
{
pushInput(new tTokenInput(this, &ts, prepasting));
RewindTokenStream(ts);
}

View File

@ -86,11 +86,11 @@ enum EFixedAtoms {
// Operators
PpAtomAdd,
PpAtomSub,
PpAtomMul,
PpAtomDiv,
PpAtomMod,
PPAtomAddAssign,
PPAtomSubAssign,
PPAtomMulAssign,
PPAtomDivAssign,
PPAtomModAssign,
PpAtomRight,
PpAtomLeft,
@ -134,7 +134,6 @@ enum EFixedAtoms {
// preprocessor "keywords"
PpAtomDefine,
PpAtomDefined,
PpAtomUndef,
PpAtomIf,

View File

@ -178,6 +178,7 @@ INSTANTIATE_TEST_CASE_P(
"syntaxError.frag",
"test.frag",
"texture.frag",
"tokenPaste.vert",
"types.frag",
"uniformArray.frag",
"variableArrayIndex.frag",

View File

@ -216,6 +216,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.forwardFun.frag",
"spv.functionCall.frag",
"spv.functionSemantics.frag",
"spv.GeometryShaderPassthrough.geom",
"spv.interpOps.frag",
"spv.int64.frag",
"spv.layoutNested.vert",
@ -240,6 +241,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.precision.frag",
"spv.prepost.frag",
"spv.qualifiers.vert",
"spv.sampleMaskOverrideCoverage.frag",
"spv.shaderBallot.comp",
"spv.shaderDrawParams.vert",
"spv.shaderGroupVote.comp",

View File

@ -90,10 +90,11 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
// as "linear" or "centroid" NOT valid identifiers. This code special cases "sample",
// so e.g, "int sample;" is accepted.
if (peekTokenClass(EHTokSample)) {
idToken.string = NewPoolTString("sample");
idToken.tokenClass = EHTokIdentifier;
idToken.symbol = nullptr;
idToken.loc = token.loc;
token.string = NewPoolTString("sample");
token.tokenClass = EHTokIdentifier;
token.symbol = nullptr;
idToken = token;
advanceToken();
return true;
}
@ -475,8 +476,15 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type)
TSourceLoc loc = token.loc;
// type_specifier
if (! acceptType(type))
if (! acceptType(type)) {
// If this is not a type, we may have inadvertently gone down a wrong path
// py parsing "sample", which can be treated like either an identifier or a
// qualifier. Back it out, if we did.
if (qualifier.sample)
recedeToken();
return false;
}
if (type.getBasicType() == EbtBlock) {
// the type was a block, which set some parts of the qualifier
parseContext.mergeQualifiers(type.getQualifier(), qualifier);
@ -2203,7 +2211,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
} else if (acceptIdentifier(idToken)) {
// identifier or function_call name
if (! peekTokenClass(EHTokLeftParen)) {
node = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
node = parseContext.handleVariable(idToken.loc, idToken.symbol, idToken.string);
} else if (acceptFunctionCall(idToken, node)) {
// function_call (nothing else to do yet)
} else {

View File

@ -50,18 +50,18 @@ public:
const TString sourceEntryPointName,
bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
virtual ~HlslParseContext();
void initializeExtensionBehavior();
void initializeExtensionBehavior() override;
void setLimits(const TBuiltInResource&);
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false);
virtual const char* getGlobalUniformBlockName() { return "$Global"; }
void setLimits(const TBuiltInResource&) override;
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
virtual const char* getGlobalUniformBlockName() override { return "$Global"; }
void reservedPpErrorCheck(const TSourceLoc&, const char* /*name*/, const char* /*op*/) { }
bool lineContinuationCheck(const TSourceLoc&, bool /*endOfComment*/) { return true; }
bool lineDirectiveShouldSetNextLine() const { return true; }
void reservedPpErrorCheck(const TSourceLoc&, const char* /*name*/, const char* /*op*/) override { }
bool lineContinuationCheck(const TSourceLoc&, bool /*endOfComment*/) override { return true; }
bool lineDirectiveShouldSetNextLine() const override { return true; }
bool builtInName(const TString&);
void handlePragma(const TSourceLoc&, const TVector<TString>&);
void handlePragma(const TSourceLoc&, const TVector<TString>&) override;
TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
TIntermTyped* handleBracketOperator(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
@ -134,7 +134,7 @@ public:
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
void declareBlock(const TSourceLoc&, TType&, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
void finalizeGlobalUniformBlockLayout(TVariable& block);
void finalizeGlobalUniformBlockLayout(TVariable& block) override;
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
void fixBlockXfbOffsets(TQualifier&, TTypeList&);
void fixBlockUniformOffsets(const TQualifier&, TTypeList&);

View File

@ -394,13 +394,14 @@ EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
do {
parserToken = &token;
TPpToken ppToken;
tokenText = ppContext.tokenize(&ppToken);
if (tokenText == nullptr)
int token = ppContext.tokenize(ppToken);
if (token == EndOfInput)
return EHTokNone;
tokenText = ppToken.name;
loc = ppToken.loc;
parserToken->loc = loc;
switch (ppToken.token) {
switch (token) {
case ';': return EHTokSemicolon;
case ',': return EHTokComma;
case ':': return EHTokColon;
@ -429,11 +430,11 @@ EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
parseContext.error(loc, "illegal use of escape character", "\\", "");
break;
case PpAtomAdd: return EHTokAddAssign;
case PpAtomSub: return EHTokSubAssign;
case PpAtomMul: return EHTokMulAssign;
case PpAtomDiv: return EHTokDivAssign;
case PpAtomMod: return EHTokModAssign;
case PPAtomAddAssign: return EHTokAddAssign;
case PPAtomSubAssign: return EHTokSubAssign;
case PPAtomMulAssign: return EHTokMulAssign;
case PPAtomDivAssign: return EHTokDivAssign;
case PPAtomModAssign: return EHTokModAssign;
case PpAtomRight: return EHTokRightOp;
case PpAtomLeft: return EHTokLeftOp;
@ -467,7 +468,7 @@ EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
}
case PpAtomConstString: {
parserToken->string = NewPoolTString(ppToken.name);
parserToken->string = NewPoolTString(tokenText);
return EHTokStringConstant;
}
@ -475,7 +476,7 @@ EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
default:
char buf[2];
buf[0] = (char)ppToken.token;
buf[0] = (char)token;
buf[1] = 0;
parseContext.error(loc, "unexpected token", buf, "");
break;