mirror of https://github.com/bkaradzic/bgfx
Updated glslang.
This commit is contained in:
parent
535dcee5f7
commit
7fc0b67b34
|
@ -101,7 +101,7 @@ private:
|
|||
//
|
||||
class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
|
||||
public:
|
||||
TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger);
|
||||
TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger, glslang::SpvOptions& options);
|
||||
virtual ~TGlslangToSpvTraverser() { }
|
||||
|
||||
bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*);
|
||||
|
@ -179,6 +179,7 @@ protected:
|
|||
spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right);
|
||||
spv::Id getExtBuiltins(const char* name);
|
||||
|
||||
glslang::SpvOptions& options;
|
||||
spv::Function* shaderEntry;
|
||||
spv::Function* currentFunction;
|
||||
spv::Instruction* entryPoint;
|
||||
|
@ -851,8 +852,11 @@ bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifie
|
|||
// Implement the TGlslangToSpvTraverser class.
|
||||
//
|
||||
|
||||
TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate, spv::SpvBuildLogger* buildLogger)
|
||||
: TIntermTraverser(true, false, true), shaderEntry(nullptr), currentFunction(nullptr),
|
||||
TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate,
|
||||
spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options)
|
||||
: TIntermTraverser(true, false, true),
|
||||
options(options),
|
||||
shaderEntry(nullptr), currentFunction(nullptr),
|
||||
sequenceDepth(0), logger(buildLogger),
|
||||
builder((glslang::GetKhronosToolId() << 16) | GeneratorVersion, logger),
|
||||
inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
|
||||
|
@ -862,6 +866,11 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
|
|||
|
||||
builder.clearAccessChain();
|
||||
builder.setSource(TranslateSourceLanguage(glslangIntermediate->getSource(), glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
|
||||
if (options.generateDebugInfo) {
|
||||
builder.setSourceFile(glslangIntermediate->getSourceFile());
|
||||
builder.setSourceText(glslangIntermediate->getSourceText());
|
||||
builder.setEmitOpLines();
|
||||
}
|
||||
stdBuiltins = builder.import("GLSL.std.450");
|
||||
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
|
||||
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
||||
|
@ -1069,6 +1078,8 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
|
|||
|
||||
bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
|
||||
{
|
||||
builder.setLine(node->getLoc().line);
|
||||
|
||||
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
|
||||
if (node->getType().getQualifier().isSpecConstant())
|
||||
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
|
||||
|
@ -1256,6 +1267,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||
|
||||
bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node)
|
||||
{
|
||||
builder.setLine(node->getLoc().line);
|
||||
|
||||
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
|
||||
if (node->getType().getQualifier().isSpecConstant())
|
||||
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
|
||||
|
@ -1499,6 +1512,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
return false;
|
||||
case glslang::EOpFunctionCall:
|
||||
{
|
||||
builder.setLine(node->getLoc().line);
|
||||
if (node->isUserDefined())
|
||||
result = handleUserFunctionCall(node);
|
||||
// assert(result); // this can happen for bad shaders because the call graph completeness checking is not yet done
|
||||
|
@ -1605,6 +1619,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
case glslang::EOpConstructStruct:
|
||||
case glslang::EOpConstructTextureSampler:
|
||||
{
|
||||
builder.setLine(node->getLoc().line);
|
||||
std::vector<spv::Id> arguments;
|
||||
translateArguments(*node, arguments);
|
||||
spv::Id constructed;
|
||||
|
@ -1715,6 +1730,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
right->traverse(this);
|
||||
spv::Id rightId = accessChainLoad(right->getType());
|
||||
|
||||
builder.setLine(node->getLoc().line);
|
||||
result = createBinaryOperation(binOp, precision, TranslateNoContractionDecoration(node->getType().getQualifier()),
|
||||
resultType(), leftId, rightId,
|
||||
left->getType().getBasicType(), reduceComparison);
|
||||
|
@ -1787,10 +1803,13 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
glslangOperands[arg]->traverse(this);
|
||||
if (lvalue)
|
||||
operands.push_back(builder.accessChainGetLValue());
|
||||
else
|
||||
else {
|
||||
builder.setLine(node->getLoc().line);
|
||||
operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
|
||||
}
|
||||
}
|
||||
|
||||
builder.setLine(node->getLoc().line);
|
||||
if (atomic) {
|
||||
// Handle all atomics
|
||||
result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
|
||||
|
@ -1872,6 +1891,8 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
|||
node->getFalseBlock()->traverse(this);
|
||||
spv::Id falseValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
|
||||
|
||||
builder.setLine(node->getLoc().line);
|
||||
|
||||
// smear condition to vector, if necessary (AST is always scalar)
|
||||
if (builder.isVector(trueValue))
|
||||
condition = builder.smearScalar(spv::NoPrecision, condition,
|
||||
|
@ -2014,6 +2035,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
|
|||
// by a block-ending branch. But we don't want to put any other body/test
|
||||
// instructions in it, since the body/test may have arbitrary instructions,
|
||||
// including merges of its own.
|
||||
builder.setLine(node->getLoc().line);
|
||||
builder.setBuildPoint(&blocks.head);
|
||||
builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control);
|
||||
if (node->testFirst() && node->getTest()) {
|
||||
|
@ -2022,8 +2044,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
|
|||
|
||||
builder.setBuildPoint(&test);
|
||||
node->getTest()->traverse(this);
|
||||
spv::Id condition =
|
||||
accessChainLoad(node->getTest()->getType());
|
||||
spv::Id condition = accessChainLoad(node->getTest()->getType());
|
||||
builder.createConditionalBranch(condition, &blocks.body, &blocks.merge);
|
||||
|
||||
builder.setBuildPoint(&blocks.body);
|
||||
|
@ -2038,6 +2059,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
|
|||
node->getTerminal()->traverse(this);
|
||||
builder.createBranch(&blocks.head);
|
||||
} else {
|
||||
builder.setLine(node->getLoc().line);
|
||||
builder.createBranch(&blocks.body);
|
||||
|
||||
breakForLoop.push(true);
|
||||
|
@ -2072,6 +2094,8 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
|
|||
if (node->getExpression())
|
||||
node->getExpression()->traverse(this);
|
||||
|
||||
builder.setLine(node->getLoc().line);
|
||||
|
||||
switch (node->getFlowOp()) {
|
||||
case glslang::EOpKill:
|
||||
builder.makeDiscard();
|
||||
|
@ -3049,9 +3073,11 @@ void TGlslangToSpvTraverser::translateArguments(glslang::TIntermUnary& node, std
|
|||
|
||||
spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node)
|
||||
{
|
||||
if (! node->isImage() && ! node->isTexture()) {
|
||||
if (! node->isImage() && ! node->isTexture())
|
||||
return spv::NoResult;
|
||||
}
|
||||
|
||||
builder.setLine(node->getLoc().line);
|
||||
|
||||
auto resultType = [&node,this]{ return convertGlslangToSpvType(node->getType()); };
|
||||
|
||||
// Process a GLSL texturing op (will be SPV image)
|
||||
|
@ -5561,22 +5587,27 @@ void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName,
|
|||
//
|
||||
// Set up the glslang traversal
|
||||
//
|
||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv)
|
||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, SpvOptions* options)
|
||||
{
|
||||
spv::SpvBuildLogger logger;
|
||||
GlslangToSpv(intermediate, spirv, &logger);
|
||||
GlslangToSpv(intermediate, spirv, &logger, options);
|
||||
}
|
||||
|
||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger)
|
||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger* logger, SpvOptions* options)
|
||||
{
|
||||
TIntermNode* root = intermediate.getTreeRoot();
|
||||
|
||||
if (root == 0)
|
||||
return;
|
||||
|
||||
glslang::SpvOptions defaultOptions;
|
||||
if (options == nullptr)
|
||||
options = &defaultOptions;
|
||||
|
||||
glslang::GetThreadPoolAllocator().push();
|
||||
|
||||
TGlslangToSpvTraverser it(&intermediate, logger);
|
||||
TGlslangToSpvTraverser it(&intermediate, logger, *options);
|
||||
root->traverse(&it);
|
||||
it.finishSpv();
|
||||
it.dumpSpv(spirv);
|
||||
|
|
|
@ -47,9 +47,16 @@
|
|||
|
||||
namespace glslang {
|
||||
|
||||
struct SpvOptions {
|
||||
SpvOptions() : generateDebugInfo(false) { }
|
||||
bool generateDebugInfo;
|
||||
};
|
||||
|
||||
void GetSpirvVersion(std::string&);
|
||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv);
|
||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger);
|
||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
SpvOptions* options = nullptr);
|
||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
|
||||
void OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
|
||||
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ namespace spv {
|
|||
Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
|
||||
source(SourceLanguageUnknown),
|
||||
sourceVersion(0),
|
||||
sourceFileStringId(NoResult),
|
||||
currentLine(0),
|
||||
emitOpLines(false),
|
||||
addressModel(AddressingModelLogical),
|
||||
memoryModel(MemoryModelGLSL450),
|
||||
builderNumber(magicNumber),
|
||||
|
@ -84,6 +87,26 @@ Id Builder::import(const char* name)
|
|||
return import->getResultId();
|
||||
}
|
||||
|
||||
// Emit an OpLine if we've been asked to emit OpLines and the line number
|
||||
// has changed since the last time, and is a valid line number.
|
||||
void Builder::setLine(int lineNum)
|
||||
{
|
||||
if (lineNum != 0 && lineNum != currentLine) {
|
||||
currentLine = lineNum;
|
||||
if (emitOpLines)
|
||||
addLine(sourceFileStringId, currentLine, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Builder::addLine(Id fileName, int lineNum, int column)
|
||||
{
|
||||
Instruction* line = new Instruction(OpLine);
|
||||
line->addIdOperand(fileName);
|
||||
line->addImmediateOperand(lineNum);
|
||||
line->addImmediateOperand(column);
|
||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(line));
|
||||
}
|
||||
|
||||
// For creating new groupedTypes (will return old type if the requested one was already made).
|
||||
Id Builder::makeVoidType()
|
||||
{
|
||||
|
@ -928,17 +951,6 @@ void Builder::addMemberName(Id id, int memberNumber, const char* string)
|
|||
names.push_back(std::unique_ptr<Instruction>(name));
|
||||
}
|
||||
|
||||
void Builder::addLine(Id target, Id fileName, int lineNum, int column)
|
||||
{
|
||||
Instruction* line = new Instruction(OpLine);
|
||||
line->addIdOperand(target);
|
||||
line->addIdOperand(fileName);
|
||||
line->addImmediateOperand(lineNum);
|
||||
line->addImmediateOperand(column);
|
||||
|
||||
lines.push_back(std::unique_ptr<Instruction>(line));
|
||||
}
|
||||
|
||||
void Builder::addDecoration(Id id, Decoration decoration, int num)
|
||||
{
|
||||
if (decoration == spv::DecorationMax)
|
||||
|
@ -2411,12 +2423,8 @@ void Builder::dump(std::vector<unsigned int>& out) const
|
|||
dumpInstructions(out, executionModes);
|
||||
|
||||
// Debug instructions
|
||||
if (source != SourceLanguageUnknown) {
|
||||
Instruction sourceInst(0, 0, OpSource);
|
||||
sourceInst.addImmediateOperand(source);
|
||||
sourceInst.addImmediateOperand(sourceVersion);
|
||||
sourceInst.dump(out);
|
||||
}
|
||||
dumpInstructions(out, strings);
|
||||
dumpSourceInstructions(out);
|
||||
for (int e = 0; e < (int)sourceExtensions.size(); ++e) {
|
||||
Instruction sourceExtInst(0, 0, OpSourceExtension);
|
||||
sourceExtInst.addStringOperand(sourceExtensions[e]);
|
||||
|
@ -2574,6 +2582,48 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
|
|||
elseBlock->addPredecessor(buildPoint);
|
||||
}
|
||||
|
||||
// OpSource
|
||||
// [OpSourceContinued]
|
||||
// ...
|
||||
void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
|
||||
{
|
||||
const int maxWordCount = 0xFFFF;
|
||||
const int opSourceWordCount = 4;
|
||||
const int nonNullBytesPerInstruction = 4 * (maxWordCount - opSourceWordCount) - 1;
|
||||
|
||||
if (source != SourceLanguageUnknown) {
|
||||
// OpSource Language Version File Source
|
||||
Instruction sourceInst(NoResult, NoType, OpSource);
|
||||
sourceInst.addImmediateOperand(source);
|
||||
sourceInst.addImmediateOperand(sourceVersion);
|
||||
// File operand
|
||||
if (sourceFileStringId != NoResult) {
|
||||
sourceInst.addIdOperand(sourceFileStringId);
|
||||
// Source operand
|
||||
if (sourceText.size() > 0) {
|
||||
int nextByte = 0;
|
||||
std::string subString;
|
||||
while ((int)sourceText.size() - nextByte > 0) {
|
||||
subString = sourceText.substr(nextByte, nonNullBytesPerInstruction);
|
||||
if (nextByte == 0) {
|
||||
// OpSource
|
||||
sourceInst.addStringOperand(subString.c_str());
|
||||
sourceInst.dump(out);
|
||||
} else {
|
||||
// OpSourcContinued
|
||||
Instruction sourceContinuedInst(OpSourceContinued);
|
||||
sourceContinuedInst.addStringOperand(subString.c_str());
|
||||
sourceContinuedInst.dump(out);
|
||||
}
|
||||
nextByte += nonNullBytesPerInstruction;
|
||||
}
|
||||
} else
|
||||
sourceInst.dump(out);
|
||||
} else
|
||||
sourceInst.dump(out);
|
||||
}
|
||||
}
|
||||
|
||||
void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector<std::unique_ptr<Instruction> >& instructions) const
|
||||
{
|
||||
for (int i = 0; i < (int)instructions.size(); ++i) {
|
||||
|
|
|
@ -70,7 +70,16 @@ public:
|
|||
source = lang;
|
||||
sourceVersion = version;
|
||||
}
|
||||
void setSourceFile(const std::string& file)
|
||||
{
|
||||
Instruction* fileString = new Instruction(getUniqueId(), NoType, OpString);
|
||||
fileString->addStringOperand(file.c_str());
|
||||
sourceFileStringId = fileString->getResultId();
|
||||
strings.push_back(std::unique_ptr<Instruction>(fileString));
|
||||
}
|
||||
void setSourceText(const std::string& text) { sourceText = text; }
|
||||
void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
|
||||
void setEmitOpLines() { emitOpLines = true; }
|
||||
void addExtension(const char* ext) { extensions.insert(ext); }
|
||||
Id import(const char*);
|
||||
void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
|
||||
|
@ -92,6 +101,12 @@ public:
|
|||
return id;
|
||||
}
|
||||
|
||||
// Log the current line, and if different than the last one,
|
||||
// issue a new OpLine, using the current file name.
|
||||
void setLine(int line);
|
||||
// Low-level OpLine. See setLine() for a layered helper.
|
||||
void addLine(Id fileName, int line, int column);
|
||||
|
||||
// For creating new types (will return old type if the requested one was already made).
|
||||
Id makeVoidType();
|
||||
Id makeBoolType();
|
||||
|
@ -213,7 +228,6 @@ public:
|
|||
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
|
||||
void addName(Id, const char* name);
|
||||
void addMemberName(Id, int member, const char* name);
|
||||
void addLine(Id target, Id fileName, int line, int column);
|
||||
void addDecoration(Id, Decoration, int num = -1);
|
||||
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
||||
|
||||
|
@ -561,10 +575,15 @@ public:
|
|||
void simplifyAccessChainSwizzle();
|
||||
void createAndSetNoPredecessorBlock(const char*);
|
||||
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
||||
void dumpSourceInstructions(std::vector<unsigned int>&) const;
|
||||
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||
|
||||
SourceLanguage source;
|
||||
int sourceVersion;
|
||||
spv::Id sourceFileStringId;
|
||||
std::string sourceText;
|
||||
int currentLine;
|
||||
bool emitOpLines;
|
||||
std::set<std::string> extensions;
|
||||
std::vector<const char*> sourceExtensions;
|
||||
AddressingModel addressModel;
|
||||
|
@ -579,6 +598,7 @@ public:
|
|||
AccessChain accessChain;
|
||||
|
||||
// special blocks of instructions for output
|
||||
std::vector<std::unique_ptr<Instruction> > strings;
|
||||
std::vector<std::unique_ptr<Instruction> > imports;
|
||||
std::vector<std::unique_ptr<Instruction> > entryPoints;
|
||||
std::vector<std::unique_ptr<Instruction> > executionModes;
|
||||
|
@ -599,7 +619,7 @@ public:
|
|||
// Our loop stack.
|
||||
std::stack<LoopBlocks> loops;
|
||||
|
||||
// The stream for outputing warnings and errors.
|
||||
// The stream for outputting warnings and errors.
|
||||
SpvBuildLogger* logger;
|
||||
}; // end Builder class
|
||||
|
||||
|
|
|
@ -87,7 +87,6 @@ public:
|
|||
void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
|
||||
void addStringOperand(const char* str)
|
||||
{
|
||||
originalString = str;
|
||||
unsigned int word;
|
||||
char* wordString = (char*)&word;
|
||||
char* wordPtr = wordString;
|
||||
|
@ -120,7 +119,6 @@ public:
|
|||
Id getTypeId() const { return typeId; }
|
||||
Id getIdOperand(int op) const { return operands[op]; }
|
||||
unsigned int getImmediateOperand(int op) const { return operands[op]; }
|
||||
const char* getStringOperand() const { return originalString.c_str(); }
|
||||
|
||||
// Write out the binary form.
|
||||
void dump(std::vector<unsigned int>& out) const
|
||||
|
@ -151,7 +149,6 @@ protected:
|
|||
Id typeId;
|
||||
Op opCode;
|
||||
std::vector<Id> operands;
|
||||
std::string originalString; // could be optimized away; convenience for getting string operand
|
||||
Block* block;
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ target_include_directories(glslang-default-resource-limits
|
|||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PUBLIC ${PROJECT_SOURCE_DIR})
|
||||
|
||||
set(SOURCES StandAlone.cpp)
|
||||
set(SOURCES StandAlone.cpp DirStackFileIncluder.h)
|
||||
set(REMAPPER_SOURCES spirv-remap.cpp)
|
||||
|
||||
add_executable(glslangValidator ${SOURCES})
|
||||
|
@ -22,7 +22,6 @@ set(LIBRARIES
|
|||
SPVRemapper
|
||||
glslang-default-resource-limits)
|
||||
|
||||
|
||||
if(WIN32)
|
||||
set(LIBRARIES ${LIBRARIES} psapi)
|
||||
elseif(UNIX)
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// Copyright (C) 2017 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "./../glslang/Public/ShaderLang.h"
|
||||
|
||||
// Default include class for normal include convention of search backward
|
||||
// through the stack of active include paths (for nested includes).
|
||||
// Can be overridden to customize.
|
||||
class DirStackFileIncluder : public glslang::TShader::Includer {
|
||||
public:
|
||||
virtual IncludeResult* includeLocal(const char* headerName,
|
||||
const char* includerName,
|
||||
size_t inclusionDepth) override
|
||||
{
|
||||
return readLocalPath(headerName, includerName, inclusionDepth);
|
||||
}
|
||||
|
||||
virtual IncludeResult* includeSystem(const char* headerName,
|
||||
const char* /*includerName*/,
|
||||
size_t /*inclusionDepth*/) override
|
||||
{
|
||||
return readSystemPath(headerName);
|
||||
}
|
||||
|
||||
virtual void releaseInclude(IncludeResult* result) override
|
||||
{
|
||||
if (result != nullptr) {
|
||||
delete [] static_cast<tUserDataElement*>(result->userData);
|
||||
delete result;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~DirStackFileIncluder() override { }
|
||||
|
||||
protected:
|
||||
typedef char tUserDataElement;
|
||||
std::vector<std::string> directoryStack;
|
||||
|
||||
// Search for a valid "local" path based on combining the stack of include
|
||||
// directories and the nominal name of the header.
|
||||
virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth)
|
||||
{
|
||||
// Discard popped include directories, and if first level, initialize.
|
||||
directoryStack.resize(depth);
|
||||
if (depth == 1)
|
||||
directoryStack.front() = getDirectory(includerName);
|
||||
|
||||
// find a directory that works, reverse search of include stack
|
||||
for (auto it = directoryStack.rbegin(); it != directoryStack.rend(); ++it) {
|
||||
std::string path = *it + '/' + headerName;
|
||||
std::replace(path.begin(), path.end(), '\\', '/');
|
||||
std::ifstream file(path, std::ios_base::binary | std::ios_base::ate);
|
||||
if (file) {
|
||||
directoryStack.push_back(getDirectory(path));
|
||||
return newIncludeResult(path, file, (int)file.tellg());
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Search for a valid <system> path.
|
||||
// Not implemented yet; returning nullptr signals failure to find.
|
||||
virtual IncludeResult* readSystemPath(const char* /*headerName*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Do actual reading of the file, filling in a new include result.
|
||||
virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const
|
||||
{
|
||||
char* content = new tUserDataElement [length];
|
||||
file.seekg(0, file.beg);
|
||||
file.read(content, length);
|
||||
return new IncludeResult(path, content, length, content);
|
||||
}
|
||||
|
||||
// If no path markers, return current working directory.
|
||||
// Otherwise, strip file name and return path leading up to it.
|
||||
virtual std::string getDirectory(const std::string path) const
|
||||
{
|
||||
size_t last = path.find_last_of("/\\");
|
||||
return last == std::string::npos ? "." : path.substr(0, last);
|
||||
}
|
||||
};
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "ResourceLimits.h"
|
||||
#include "Worklist.h"
|
||||
#include "DirStackFileIncluder.h"
|
||||
#include "./../glslang/Include/ShHandle.h"
|
||||
#include "./../glslang/Include/revision.h"
|
||||
#include "./../glslang/Public/ShaderLang.h"
|
||||
|
@ -48,6 +49,7 @@
|
|||
#include "../SPIRV/GLSL.std.450.h"
|
||||
#include "../SPIRV/doc.h"
|
||||
#include "../SPIRV/disassemble.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
|
@ -91,6 +93,7 @@ enum TOptions {
|
|||
EOptionHlslOffsets = (1 << 23),
|
||||
EOptionHlslIoMapping = (1 << 24),
|
||||
EOptionAutoMapLocations = (1 << 25),
|
||||
EOptionDebug = (1 << 26),
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -448,6 +451,9 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||
} else
|
||||
Error("no <entry-point> provided for -e");
|
||||
break;
|
||||
case 'g':
|
||||
Options |= EOptionDebug;
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
break;
|
||||
|
@ -539,6 +545,8 @@ void SetMessageOptions(EShMessages& messages)
|
|||
messages = (EShMessages)(messages | EShMsgKeepUncalled);
|
||||
if (Options & EOptionHlslOffsets)
|
||||
messages = (EShMessages)(messages | EShMsgHlslOffsets);
|
||||
if (Options & EOptionDebug)
|
||||
messages = (EShMessages)(messages | EShMsgDebugInfo);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -659,9 +667,9 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
|
||||
const int defaultVersion = Options & EOptionDefaultDesktop? 110: 100;
|
||||
|
||||
DirStackFileIncluder includer;
|
||||
if (Options & EOptionOutputPreprocessed) {
|
||||
std::string str;
|
||||
glslang::TShader::ForbidIncluder includer;
|
||||
if (shader->preprocess(&Resources, defaultVersion, ENoProfile, false, false,
|
||||
messages, &str, includer)) {
|
||||
PutsIfNonEmpty(str.c_str());
|
||||
|
@ -672,7 +680,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
StderrIfNonEmpty(shader->getInfoDebugLog());
|
||||
continue;
|
||||
}
|
||||
if (! shader->parse(&Resources, defaultVersion, false, messages))
|
||||
if (! shader->parse(&Resources, defaultVersion, false, messages, includer))
|
||||
CompileFailed = true;
|
||||
|
||||
program.addShader(shader);
|
||||
|
@ -722,7 +730,10 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
std::vector<unsigned int> spirv;
|
||||
std::string warningsErrors;
|
||||
spv::SpvBuildLogger logger;
|
||||
glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger);
|
||||
glslang::SpvOptions spvOptions;
|
||||
if (Options & EOptionDebug)
|
||||
spvOptions.generateDebugInfo = true;
|
||||
glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger, &spvOptions);
|
||||
|
||||
// Dump the spv to a file or stdout, etc., but only if not doing
|
||||
// memory/perf testing, as it's not internal to programmatic use.
|
||||
|
@ -1031,6 +1042,7 @@ void usage()
|
|||
" (default is ES version 100)\n"
|
||||
" -D input is HLSL\n"
|
||||
" -e specify entry-point name\n"
|
||||
" -g generate debug information\n"
|
||||
" -h print this usage message\n"
|
||||
" -i intermediate tree (glslang AST) is printed out\n"
|
||||
" -l link all input files together to form a single module\n"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
float4 i1;
|
|
@ -0,0 +1,174 @@
|
|||
hlsl.aliasOpaque.frag
|
||||
Shader version: 500
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:12 Function Definition: osCall(struct-OS-p1-f1-t211; ( temp 4-component vector of float)
|
||||
0:12 Function Parameters:
|
||||
0:? 'ss' ( in sampler)
|
||||
0:? 'a' ( in float)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:? Sequence
|
||||
0:13 Branch: Return with expression
|
||||
0:13 vector-scale ( temp 4-component vector of float)
|
||||
0:? 'a' ( in float)
|
||||
0:13 texture ( temp 4-component vector of float)
|
||||
0:13 Construct combined texture-sampler ( temp sampler2D)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:? 'ss' ( in sampler)
|
||||
0:? Constant:
|
||||
0:? 0.200000
|
||||
0:? 0.300000
|
||||
0:17 Function Definition: @main( ( temp 4-component vector of float)
|
||||
0:17 Function Parameters:
|
||||
0:? Sequence
|
||||
0:19 'gss2' ( uniform sampler)
|
||||
0:20 'gss' ( uniform sampler)
|
||||
0:21 'gtex' ( uniform texture2D)
|
||||
0:22 move second child to first child ( temp float)
|
||||
0:? 'a' ( temp float)
|
||||
0:22 Constant:
|
||||
0:22 3.000000
|
||||
0:28 Branch: Return with expression
|
||||
0:28 Function Call: osCall(struct-OS-p1-f1-t211; ( temp 4-component vector of float)
|
||||
0:? 'gss' ( uniform sampler)
|
||||
0:? 'a' ( temp float)
|
||||
0:? 'gtex' ( uniform texture2D)
|
||||
0:17 Function Definition: main( ( temp void)
|
||||
0:17 Function Parameters:
|
||||
0:? 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:17 Function Call: @main( ( temp 4-component vector of float)
|
||||
0:? Linker Objects
|
||||
0:? 'gss' ( uniform sampler)
|
||||
0:? 'gss2' ( uniform sampler)
|
||||
0:? 'gtex' ( uniform texture2D)
|
||||
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||
|
||||
|
||||
Linked fragment stage:
|
||||
|
||||
|
||||
Shader version: 500
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:12 Function Definition: osCall(struct-OS-p1-f1-t211; ( temp 4-component vector of float)
|
||||
0:12 Function Parameters:
|
||||
0:? 'ss' ( in sampler)
|
||||
0:? 'a' ( in float)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:? Sequence
|
||||
0:13 Branch: Return with expression
|
||||
0:13 vector-scale ( temp 4-component vector of float)
|
||||
0:? 'a' ( in float)
|
||||
0:13 texture ( temp 4-component vector of float)
|
||||
0:13 Construct combined texture-sampler ( temp sampler2D)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:? 'ss' ( in sampler)
|
||||
0:? Constant:
|
||||
0:? 0.200000
|
||||
0:? 0.300000
|
||||
0:17 Function Definition: @main( ( temp 4-component vector of float)
|
||||
0:17 Function Parameters:
|
||||
0:? Sequence
|
||||
0:19 'gss2' ( uniform sampler)
|
||||
0:20 'gss' ( uniform sampler)
|
||||
0:21 'gtex' ( uniform texture2D)
|
||||
0:22 move second child to first child ( temp float)
|
||||
0:? 'a' ( temp float)
|
||||
0:22 Constant:
|
||||
0:22 3.000000
|
||||
0:28 Branch: Return with expression
|
||||
0:28 Function Call: osCall(struct-OS-p1-f1-t211; ( temp 4-component vector of float)
|
||||
0:? 'gss' ( uniform sampler)
|
||||
0:? 'a' ( temp float)
|
||||
0:? 'gtex' ( uniform texture2D)
|
||||
0:17 Function Definition: main( ( temp void)
|
||||
0:17 Function Parameters:
|
||||
0:? 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:17 Function Call: @main( ( temp 4-component vector of float)
|
||||
0:? Linker Objects
|
||||
0:? 'gss' ( uniform sampler)
|
||||
0:? 'gss2' ( uniform sampler)
|
||||
0:? 'gtex' ( uniform texture2D)
|
||||
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 48
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main" 46
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Source HLSL 500
|
||||
Name 4 "main"
|
||||
Name 17 "osCall(struct-OS-p1-f1-t211;"
|
||||
Name 14 "ss"
|
||||
Name 15 "a"
|
||||
Name 16 "tex"
|
||||
Name 20 "@main("
|
||||
Name 35 "gss2"
|
||||
Name 36 "gss"
|
||||
Name 37 "gtex"
|
||||
Name 38 "a"
|
||||
Name 40 "param"
|
||||
Name 46 "@entryPointOutput"
|
||||
Decorate 35(gss2) DescriptorSet 0
|
||||
Decorate 36(gss) DescriptorSet 0
|
||||
Decorate 37(gtex) DescriptorSet 0
|
||||
Decorate 46(@entryPointOutput) Location 0
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeSampler
|
||||
7: TypePointer UniformConstant 6
|
||||
8: TypeFloat 32
|
||||
9: TypePointer Function 8(float)
|
||||
10: TypeImage 8(float) 2D sampled format:Unknown
|
||||
11: TypePointer UniformConstant 10
|
||||
12: TypeVector 8(float) 4
|
||||
13: TypeFunction 12(fvec4) 7(ptr) 9(ptr) 11(ptr)
|
||||
19: TypeFunction 12(fvec4)
|
||||
25: TypeSampledImage 10
|
||||
27: TypeVector 8(float) 2
|
||||
28: 8(float) Constant 1045220557
|
||||
29: 8(float) Constant 1050253722
|
||||
30: 27(fvec2) ConstantComposite 28 29
|
||||
35(gss2): 7(ptr) Variable UniformConstant
|
||||
36(gss): 7(ptr) Variable UniformConstant
|
||||
37(gtex): 11(ptr) Variable UniformConstant
|
||||
39: 8(float) Constant 1077936128
|
||||
45: TypePointer Output 12(fvec4)
|
||||
46(@entryPointOutput): 45(ptr) Variable Output
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
47: 12(fvec4) FunctionCall 20(@main()
|
||||
Store 46(@entryPointOutput) 47
|
||||
Return
|
||||
FunctionEnd
|
||||
17(osCall(struct-OS-p1-f1-t211;): 12(fvec4) Function None 13
|
||||
14(ss): 7(ptr) FunctionParameter
|
||||
15(a): 9(ptr) FunctionParameter
|
||||
16(tex): 11(ptr) FunctionParameter
|
||||
18: Label
|
||||
22: 8(float) Load 15(a)
|
||||
23: 10 Load 16(tex)
|
||||
24: 6 Load 14(ss)
|
||||
26: 25 SampledImage 23 24
|
||||
31: 12(fvec4) ImageSampleImplicitLod 26 30
|
||||
32: 12(fvec4) VectorTimesScalar 31 22
|
||||
ReturnValue 32
|
||||
FunctionEnd
|
||||
20(@main(): 12(fvec4) Function None 19
|
||||
21: Label
|
||||
38(a): 9(ptr) Variable Function
|
||||
40(param): 9(ptr) Variable Function
|
||||
Store 38(a) 39
|
||||
41: 8(float) Load 38(a)
|
||||
Store 40(param) 41
|
||||
42: 12(fvec4) FunctionCall 17(osCall(struct-OS-p1-f1-t211;) 36(gss) 40(param) 37(gtex)
|
||||
ReturnValue 42
|
||||
FunctionEnd
|
|
@ -0,0 +1,297 @@
|
|||
hlsl.flattenOpaque.frag
|
||||
Shader version: 500
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:15 Function Definition: osCall1(struct-os-p11; ( temp 4-component vector of float)
|
||||
0:15 Function Parameters:
|
||||
0:? 's2D' ( in sampler)
|
||||
0:? Sequence
|
||||
0:16 Branch: Return with expression
|
||||
0:16 texture ( temp 4-component vector of float)
|
||||
0:16 Construct combined texture-sampler ( temp sampler2D)
|
||||
0:16 'tex' ( uniform texture2D)
|
||||
0:? 's2D' ( in sampler)
|
||||
0:? Constant:
|
||||
0:? 0.200000
|
||||
0:? 0.300000
|
||||
0:20 Function Definition: osCall2(struct-os-p11;vf2; ( temp 4-component vector of float)
|
||||
0:20 Function Parameters:
|
||||
0:? 's2D' ( in sampler)
|
||||
0:20 'f2' ( in 2-component vector of float)
|
||||
0:? Sequence
|
||||
0:21 Branch: Return with expression
|
||||
0:21 texture ( temp 4-component vector of float)
|
||||
0:21 Construct combined texture-sampler ( temp sampler2D)
|
||||
0:21 'tex' ( uniform texture2D)
|
||||
0:? 's2D' ( in sampler)
|
||||
0:21 'f2' ( in 2-component vector of float)
|
||||
0:25 Function Definition: os2Call1(struct-os2-p1-t211; ( temp 4-component vector of float)
|
||||
0:25 Function Parameters:
|
||||
0:? 's2D' ( in sampler)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:? Sequence
|
||||
0:26 Branch: Return with expression
|
||||
0:26 texture ( temp 4-component vector of float)
|
||||
0:26 Construct combined texture-sampler ( temp sampler2D)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:? 's2D' ( in sampler)
|
||||
0:? Constant:
|
||||
0:? 0.200000
|
||||
0:? 0.300000
|
||||
0:30 Function Definition: os2Call2(struct-os2-p1-t211;vf2; ( temp 4-component vector of float)
|
||||
0:30 Function Parameters:
|
||||
0:? 's2D' ( in sampler)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:30 'f2' ( in 2-component vector of float)
|
||||
0:? Sequence
|
||||
0:31 Branch: Return with expression
|
||||
0:31 texture ( temp 4-component vector of float)
|
||||
0:31 Construct combined texture-sampler ( temp sampler2D)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:? 's2D' ( in sampler)
|
||||
0:31 'f2' ( in 2-component vector of float)
|
||||
0:35 Function Definition: @main( ( temp 4-component vector of float)
|
||||
0:35 Function Parameters:
|
||||
0:? Sequence
|
||||
0:39 Branch: Return with expression
|
||||
0:38 add ( temp 4-component vector of float)
|
||||
0:37 add ( temp 4-component vector of float)
|
||||
0:36 add ( temp 4-component vector of float)
|
||||
0:36 Function Call: osCall1(struct-os-p11; ( temp 4-component vector of float)
|
||||
0:? 's2D' ( uniform sampler)
|
||||
0:37 Function Call: osCall2(struct-os-p11;vf2; ( temp 4-component vector of float)
|
||||
0:? 's2D' ( uniform sampler)
|
||||
0:? Constant:
|
||||
0:? 0.200000
|
||||
0:? 0.300000
|
||||
0:38 Function Call: os2Call1(struct-os2-p1-t211; ( temp 4-component vector of float)
|
||||
0:? 's2D' ( uniform sampler)
|
||||
0:? 'tex' ( uniform texture2D)
|
||||
0:39 Function Call: os2Call2(struct-os2-p1-t211;vf2; ( temp 4-component vector of float)
|
||||
0:? 's2D' ( uniform sampler)
|
||||
0:? 'tex' ( uniform texture2D)
|
||||
0:? Constant:
|
||||
0:? 0.200000
|
||||
0:? 0.300000
|
||||
0:35 Function Definition: main( ( temp void)
|
||||
0:35 Function Parameters:
|
||||
0:? Sequence
|
||||
0:35 move second child to first child ( temp 4-component vector of float)
|
||||
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||
0:35 Function Call: @main( ( temp 4-component vector of float)
|
||||
0:? Linker Objects
|
||||
0:? 'tex' ( uniform texture2D)
|
||||
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||
|
||||
|
||||
Linked fragment stage:
|
||||
|
||||
|
||||
Shader version: 500
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:15 Function Definition: osCall1(struct-os-p11; ( temp 4-component vector of float)
|
||||
0:15 Function Parameters:
|
||||
0:? 's2D' ( in sampler)
|
||||
0:? Sequence
|
||||
0:16 Branch: Return with expression
|
||||
0:16 texture ( temp 4-component vector of float)
|
||||
0:16 Construct combined texture-sampler ( temp sampler2D)
|
||||
0:16 'tex' ( uniform texture2D)
|
||||
0:? 's2D' ( in sampler)
|
||||
0:? Constant:
|
||||
0:? 0.200000
|
||||
0:? 0.300000
|
||||
0:20 Function Definition: osCall2(struct-os-p11;vf2; ( temp 4-component vector of float)
|
||||
0:20 Function Parameters:
|
||||
0:? 's2D' ( in sampler)
|
||||
0:20 'f2' ( in 2-component vector of float)
|
||||
0:? Sequence
|
||||
0:21 Branch: Return with expression
|
||||
0:21 texture ( temp 4-component vector of float)
|
||||
0:21 Construct combined texture-sampler ( temp sampler2D)
|
||||
0:21 'tex' ( uniform texture2D)
|
||||
0:? 's2D' ( in sampler)
|
||||
0:21 'f2' ( in 2-component vector of float)
|
||||
0:25 Function Definition: os2Call1(struct-os2-p1-t211; ( temp 4-component vector of float)
|
||||
0:25 Function Parameters:
|
||||
0:? 's2D' ( in sampler)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:? Sequence
|
||||
0:26 Branch: Return with expression
|
||||
0:26 texture ( temp 4-component vector of float)
|
||||
0:26 Construct combined texture-sampler ( temp sampler2D)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:? 's2D' ( in sampler)
|
||||
0:? Constant:
|
||||
0:? 0.200000
|
||||
0:? 0.300000
|
||||
0:30 Function Definition: os2Call2(struct-os2-p1-t211;vf2; ( temp 4-component vector of float)
|
||||
0:30 Function Parameters:
|
||||
0:? 's2D' ( in sampler)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:30 'f2' ( in 2-component vector of float)
|
||||
0:? Sequence
|
||||
0:31 Branch: Return with expression
|
||||
0:31 texture ( temp 4-component vector of float)
|
||||
0:31 Construct combined texture-sampler ( temp sampler2D)
|
||||
0:? 'tex' ( in texture2D)
|
||||
0:? 's2D' ( in sampler)
|
||||
0:31 'f2' ( in 2-component vector of float)
|
||||
0:35 Function Definition: @main( ( temp 4-component vector of float)
|
||||
0:35 Function Parameters:
|
||||
0:? Sequence
|
||||
0:39 Branch: Return with expression
|
||||
0:38 add ( temp 4-component vector of float)
|
||||
0:37 add ( temp 4-component vector of float)
|
||||
0:36 add ( temp 4-component vector of float)
|
||||
0:36 Function Call: osCall1(struct-os-p11; ( temp 4-component vector of float)
|
||||
0:? 's2D' ( uniform sampler)
|
||||
0:37 Function Call: osCall2(struct-os-p11;vf2; ( temp 4-component vector of float)
|
||||
0:? 's2D' ( uniform sampler)
|
||||
0:? Constant:
|
||||
0:? 0.200000
|
||||
0:? 0.300000
|
||||
0:38 Function Call: os2Call1(struct-os2-p1-t211; ( temp 4-component vector of float)
|
||||
0:? 's2D' ( uniform sampler)
|
||||
0:? 'tex' ( uniform texture2D)
|
||||
0:39 Function Call: os2Call2(struct-os2-p1-t211;vf2; ( temp 4-component vector of float)
|
||||
0:? 's2D' ( uniform sampler)
|
||||
0:? 'tex' ( uniform texture2D)
|
||||
0:? Constant:
|
||||
0:? 0.200000
|
||||
0:? 0.300000
|
||||
0:35 Function Definition: main( ( temp void)
|
||||
0:35 Function Parameters:
|
||||
0:? Sequence
|
||||
0:35 move second child to first child ( temp 4-component vector of float)
|
||||
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||
0:35 Function Call: @main( ( temp 4-component vector of float)
|
||||
0:? Linker Objects
|
||||
0:? 'tex' ( uniform texture2D)
|
||||
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 85
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main" 83
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Source HLSL 500
|
||||
Name 4 "main"
|
||||
Name 12 "osCall1(struct-os-p11;"
|
||||
Name 11 "s2D"
|
||||
Name 19 "osCall2(struct-os-p11;vf2;"
|
||||
Name 17 "s2D"
|
||||
Name 18 "f2"
|
||||
Name 26 "os2Call1(struct-os2-p1-t211;"
|
||||
Name 24 "s2D"
|
||||
Name 25 "tex"
|
||||
Name 32 "os2Call2(struct-os2-p1-t211;vf2;"
|
||||
Name 29 "s2D"
|
||||
Name 30 "tex"
|
||||
Name 31 "f2"
|
||||
Name 35 "@main("
|
||||
Name 37 "tex"
|
||||
Name 68 "s2D"
|
||||
Name 70 "param"
|
||||
Name 73 "s2D"
|
||||
Name 74 "tex"
|
||||
Name 77 "param"
|
||||
Name 83 "@entryPointOutput"
|
||||
Decorate 37(tex) DescriptorSet 0
|
||||
Decorate 68(s2D) DescriptorSet 0
|
||||
Decorate 73(s2D) DescriptorSet 0
|
||||
Decorate 74(tex) DescriptorSet 0
|
||||
Decorate 83(@entryPointOutput) Location 0
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeSampler
|
||||
7: TypePointer UniformConstant 6
|
||||
8: TypeFloat 32
|
||||
9: TypeVector 8(float) 4
|
||||
10: TypeFunction 9(fvec4) 7(ptr)
|
||||
14: TypeVector 8(float) 2
|
||||
15: TypePointer Function 14(fvec2)
|
||||
16: TypeFunction 9(fvec4) 7(ptr) 15(ptr)
|
||||
21: TypeImage 8(float) 2D sampled format:Unknown
|
||||
22: TypePointer UniformConstant 21
|
||||
23: TypeFunction 9(fvec4) 7(ptr) 22(ptr)
|
||||
28: TypeFunction 9(fvec4) 7(ptr) 22(ptr) 15(ptr)
|
||||
34: TypeFunction 9(fvec4)
|
||||
37(tex): 22(ptr) Variable UniformConstant
|
||||
40: TypeSampledImage 21
|
||||
42: 8(float) Constant 1045220557
|
||||
43: 8(float) Constant 1050253722
|
||||
44: 14(fvec2) ConstantComposite 42 43
|
||||
68(s2D): 7(ptr) Variable UniformConstant
|
||||
73(s2D): 7(ptr) Variable UniformConstant
|
||||
74(tex): 22(ptr) Variable UniformConstant
|
||||
82: TypePointer Output 9(fvec4)
|
||||
83(@entryPointOutput): 82(ptr) Variable Output
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
84: 9(fvec4) FunctionCall 35(@main()
|
||||
Store 83(@entryPointOutput) 84
|
||||
Return
|
||||
FunctionEnd
|
||||
12(osCall1(struct-os-p11;): 9(fvec4) Function None 10
|
||||
11(s2D): 7(ptr) FunctionParameter
|
||||
13: Label
|
||||
38: 21 Load 37(tex)
|
||||
39: 6 Load 11(s2D)
|
||||
41: 40 SampledImage 38 39
|
||||
45: 9(fvec4) ImageSampleImplicitLod 41 44
|
||||
ReturnValue 45
|
||||
FunctionEnd
|
||||
19(osCall2(struct-os-p11;vf2;): 9(fvec4) Function None 16
|
||||
17(s2D): 7(ptr) FunctionParameter
|
||||
18(f2): 15(ptr) FunctionParameter
|
||||
20: Label
|
||||
48: 21 Load 37(tex)
|
||||
49: 6 Load 17(s2D)
|
||||
50: 40 SampledImage 48 49
|
||||
51: 14(fvec2) Load 18(f2)
|
||||
52: 9(fvec4) ImageSampleImplicitLod 50 51
|
||||
ReturnValue 52
|
||||
FunctionEnd
|
||||
26(os2Call1(struct-os2-p1-t211;): 9(fvec4) Function None 23
|
||||
24(s2D): 7(ptr) FunctionParameter
|
||||
25(tex): 22(ptr) FunctionParameter
|
||||
27: Label
|
||||
55: 21 Load 25(tex)
|
||||
56: 6 Load 24(s2D)
|
||||
57: 40 SampledImage 55 56
|
||||
58: 9(fvec4) ImageSampleImplicitLod 57 44
|
||||
ReturnValue 58
|
||||
FunctionEnd
|
||||
32(os2Call2(struct-os2-p1-t211;vf2;): 9(fvec4) Function None 28
|
||||
29(s2D): 7(ptr) FunctionParameter
|
||||
30(tex): 22(ptr) FunctionParameter
|
||||
31(f2): 15(ptr) FunctionParameter
|
||||
33: Label
|
||||
61: 21 Load 30(tex)
|
||||
62: 6 Load 29(s2D)
|
||||
63: 40 SampledImage 61 62
|
||||
64: 14(fvec2) Load 31(f2)
|
||||
65: 9(fvec4) ImageSampleImplicitLod 63 64
|
||||
ReturnValue 65
|
||||
FunctionEnd
|
||||
35(@main(): 9(fvec4) Function None 34
|
||||
36: Label
|
||||
70(param): 15(ptr) Variable Function
|
||||
77(param): 15(ptr) Variable Function
|
||||
69: 9(fvec4) FunctionCall 12(osCall1(struct-os-p11;) 68(s2D)
|
||||
Store 70(param) 44
|
||||
71: 9(fvec4) FunctionCall 19(osCall2(struct-os-p11;vf2;) 68(s2D) 70(param)
|
||||
72: 9(fvec4) FAdd 69 71
|
||||
75: 9(fvec4) FunctionCall 26(os2Call1(struct-os2-p1-t211;) 73(s2D) 74(tex)
|
||||
76: 9(fvec4) FAdd 72 75
|
||||
Store 77(param) 44
|
||||
78: 9(fvec4) FunctionCall 32(os2Call2(struct-os2-p1-t211;vf2;) 73(s2D) 74(tex) 77(param)
|
||||
79: 9(fvec4) FAdd 76 78
|
||||
ReturnValue 79
|
||||
FunctionEnd
|
|
@ -0,0 +1,75 @@
|
|||
../Test/hlsl.include.vert
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 44
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Vertex 4 "main" 42
|
||||
Source HLSL 500
|
||||
Name 4 "main"
|
||||
Name 9 "@main("
|
||||
Name 11 "$Global"
|
||||
MemberName 11($Global) 0 "i1"
|
||||
MemberName 11($Global) 1 "i2"
|
||||
MemberName 11($Global) 2 "i4"
|
||||
MemberName 11($Global) 3 "i3"
|
||||
MemberName 11($Global) 4 "i6"
|
||||
MemberName 11($Global) 5 "i5"
|
||||
Name 13 ""
|
||||
Name 42 "@entryPointOutput"
|
||||
MemberDecorate 11($Global) 0 Offset 0
|
||||
MemberDecorate 11($Global) 1 Offset 16
|
||||
MemberDecorate 11($Global) 2 Offset 32
|
||||
MemberDecorate 11($Global) 3 Offset 48
|
||||
MemberDecorate 11($Global) 4 Offset 64
|
||||
MemberDecorate 11($Global) 5 Offset 80
|
||||
Decorate 11($Global) Block
|
||||
Decorate 13 DescriptorSet 0
|
||||
Decorate 42(@entryPointOutput) BuiltIn Position
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeFloat 32
|
||||
7: TypeVector 6(float) 4
|
||||
8: TypeFunction 7(fvec4)
|
||||
11($Global): TypeStruct 7(fvec4) 7(fvec4) 7(fvec4) 7(fvec4) 7(fvec4) 7(fvec4)
|
||||
12: TypePointer Uniform 11($Global)
|
||||
13: 12(ptr) Variable Uniform
|
||||
14: TypeInt 32 1
|
||||
15: 14(int) Constant 0
|
||||
16: TypePointer Uniform 7(fvec4)
|
||||
19: 14(int) Constant 1
|
||||
23: 14(int) Constant 3
|
||||
27: 14(int) Constant 2
|
||||
31: 14(int) Constant 5
|
||||
35: 14(int) Constant 4
|
||||
41: TypePointer Output 7(fvec4)
|
||||
42(@entryPointOutput): 41(ptr) Variable Output
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
43: 7(fvec4) FunctionCall 9(@main()
|
||||
Store 42(@entryPointOutput) 43
|
||||
Return
|
||||
FunctionEnd
|
||||
9(@main(): 7(fvec4) Function None 8
|
||||
10: Label
|
||||
17: 16(ptr) AccessChain 13 15
|
||||
18: 7(fvec4) Load 17
|
||||
20: 16(ptr) AccessChain 13 19
|
||||
21: 7(fvec4) Load 20
|
||||
22: 7(fvec4) FAdd 18 21
|
||||
24: 16(ptr) AccessChain 13 23
|
||||
25: 7(fvec4) Load 24
|
||||
26: 7(fvec4) FAdd 22 25
|
||||
28: 16(ptr) AccessChain 13 27
|
||||
29: 7(fvec4) Load 28
|
||||
30: 7(fvec4) FAdd 26 29
|
||||
32: 16(ptr) AccessChain 13 31
|
||||
33: 7(fvec4) Load 32
|
||||
34: 7(fvec4) FAdd 30 33
|
||||
36: 16(ptr) AccessChain 13 35
|
||||
37: 7(fvec4) Load 36
|
||||
38: 7(fvec4) FAdd 34 37
|
||||
ReturnValue 38
|
||||
FunctionEnd
|
|
@ -0,0 +1,10 @@
|
|||
hlsl.includeNegative.vert
|
||||
ERROR: ./foo.h:1: '#error' : should not be included
|
||||
ERROR: ./inc2/../foo.h:1: '#error' : should not be included
|
||||
ERROR: ./parentBad:3: '#error' : bad parent
|
||||
ERROR: hlsl.includeNegative.vert:7: '#error' : in main
|
||||
hlsl.includeNegative.vert(8): error at column 0, HLSL parsing failed.
|
||||
ERROR: 5 compilation errors. No code generated.
|
||||
|
||||
|
||||
SPIR-V is not generated for failed compile or link
|
|
@ -0,0 +1,69 @@
|
|||
include.vert
|
||||
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
|
||||
|
||||
Shader version: 450
|
||||
Requested GL_GOOGLE_cpp_style_line_directive
|
||||
Requested GL_GOOGLE_include_directive
|
||||
0:? Sequence
|
||||
0:13 Function Definition: main( ( global void)
|
||||
0:13 Function Parameters:
|
||||
0:15 Sequence
|
||||
0:15 move second child to first child ( temp 4-component vector of float)
|
||||
0:15 'color' ( smooth out 4-component vector of float)
|
||||
0:15 add ( temp 4-component vector of float)
|
||||
0:15 add ( temp 4-component vector of float)
|
||||
0:15 add ( temp 4-component vector of float)
|
||||
0:15 add ( temp 4-component vector of float)
|
||||
0:15 add ( temp 4-component vector of float)
|
||||
0:15 'i1' ( global 4-component vector of float)
|
||||
0:15 'i2' ( global 4-component vector of float)
|
||||
0:15 'i3' ( global 4-component vector of float)
|
||||
0:15 'i4' ( global 4-component vector of float)
|
||||
0:15 'i5' ( global 4-component vector of float)
|
||||
0:15 'i6' ( global 4-component vector of float)
|
||||
0:? Linker Objects
|
||||
0:? 'i1' ( global 4-component vector of float)
|
||||
0:? 'i2' ( global 4-component vector of float)
|
||||
0:? 'i4' ( global 4-component vector of float)
|
||||
0:? 'i3' ( global 4-component vector of float)
|
||||
0:? 'i6' ( global 4-component vector of float)
|
||||
0:? 'i5' ( global 4-component vector of float)
|
||||
0:? 'color' ( smooth out 4-component vector of float)
|
||||
0:? 'gl_VertexID' ( gl_VertexId int VertexId)
|
||||
0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId)
|
||||
|
||||
|
||||
Linked vertex stage:
|
||||
|
||||
|
||||
Shader version: 450
|
||||
Requested GL_GOOGLE_cpp_style_line_directive
|
||||
Requested GL_GOOGLE_include_directive
|
||||
0:? Sequence
|
||||
0:13 Function Definition: main( ( global void)
|
||||
0:13 Function Parameters:
|
||||
0:15 Sequence
|
||||
0:15 move second child to first child ( temp 4-component vector of float)
|
||||
0:15 'color' ( smooth out 4-component vector of float)
|
||||
0:15 add ( temp 4-component vector of float)
|
||||
0:15 add ( temp 4-component vector of float)
|
||||
0:15 add ( temp 4-component vector of float)
|
||||
0:15 add ( temp 4-component vector of float)
|
||||
0:15 add ( temp 4-component vector of float)
|
||||
0:15 'i1' ( global 4-component vector of float)
|
||||
0:15 'i2' ( global 4-component vector of float)
|
||||
0:15 'i3' ( global 4-component vector of float)
|
||||
0:15 'i4' ( global 4-component vector of float)
|
||||
0:15 'i5' ( global 4-component vector of float)
|
||||
0:15 'i6' ( global 4-component vector of float)
|
||||
0:? Linker Objects
|
||||
0:? 'i1' ( global 4-component vector of float)
|
||||
0:? 'i2' ( global 4-component vector of float)
|
||||
0:? 'i4' ( global 4-component vector of float)
|
||||
0:? 'i3' ( global 4-component vector of float)
|
||||
0:? 'i6' ( global 4-component vector of float)
|
||||
0:? 'i5' ( global 4-component vector of float)
|
||||
0:? 'color' ( smooth out 4-component vector of float)
|
||||
0:? 'gl_VertexID' ( gl_VertexId int VertexId)
|
||||
0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId)
|
||||
|
|
@ -0,0 +1,272 @@
|
|||
spv.debugInfo.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 126
|
||||
|
||||
Capability Shader
|
||||
2: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 5 "main" 24 52
|
||||
ExecutionMode 5 OriginUpperLeft
|
||||
1: String "spv.debugInfo.frag"
|
||||
Source GLSL 450 1 "#version 450
|
||||
|
||||
struct S {
|
||||
int a;
|
||||
};
|
||||
|
||||
uniform ubuf {
|
||||
S s;
|
||||
};
|
||||
|
||||
uniform sampler2D s2d;
|
||||
|
||||
layout(location = 0) in vec4 inv;
|
||||
layout(location = 0) out vec4 outv;
|
||||
|
||||
vec4 foo(S s)
|
||||
{
|
||||
vec4 r = s.a * inv;
|
||||
++r;
|
||||
if (r.x > 3.0)
|
||||
--r;
|
||||
else
|
||||
r *= 2;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
outv = foo(s);
|
||||
outv += texture(s2d, vec2(0.5));
|
||||
|
||||
switch (s.a) {
|
||||
case 10:
|
||||
++outv;
|
||||
break;
|
||||
case 20:
|
||||
outv = 2 * outv;
|
||||
++outv;
|
||||
break;
|
||||
default:
|
||||
--outv;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
outv *= 3.0;
|
||||
|
||||
outv.x < 10.0 ?
|
||||
outv = sin(outv) :
|
||||
outv = cos(outv);
|
||||
}"
|
||||
Name 5 "main"
|
||||
Name 8 "S"
|
||||
MemberName 8(S) 0 "a"
|
||||
Name 14 "foo(struct-S-i11;"
|
||||
Name 13 "s"
|
||||
Name 17 "r"
|
||||
Name 24 "inv"
|
||||
Name 52 "outv"
|
||||
Name 53 "S"
|
||||
MemberName 53(S) 0 "a"
|
||||
Name 54 "ubuf"
|
||||
MemberName 54(ubuf) 0 "s"
|
||||
Name 56 ""
|
||||
Name 57 "S"
|
||||
MemberName 57(S) 0 "a"
|
||||
Name 59 "param"
|
||||
Name 69 "s2d"
|
||||
Name 99 "i"
|
||||
Decorate 24(inv) Location 0
|
||||
Decorate 52(outv) Location 0
|
||||
MemberDecorate 53(S) 0 Offset 0
|
||||
MemberDecorate 54(ubuf) 0 Offset 0
|
||||
Decorate 54(ubuf) Block
|
||||
Decorate 56 DescriptorSet 0
|
||||
Decorate 69(s2d) DescriptorSet 0
|
||||
3: TypeVoid
|
||||
4: TypeFunction 3
|
||||
7: TypeInt 32 1
|
||||
8(S): TypeStruct 7(int)
|
||||
9: TypePointer Function 8(S)
|
||||
10: TypeFloat 32
|
||||
11: TypeVector 10(float) 4
|
||||
12: TypeFunction 11(fvec4) 9(ptr)
|
||||
16: TypePointer Function 11(fvec4)
|
||||
18: 7(int) Constant 0
|
||||
19: TypePointer Function 7(int)
|
||||
23: TypePointer Input 11(fvec4)
|
||||
24(inv): 23(ptr) Variable Input
|
||||
28: 10(float) Constant 1065353216
|
||||
31: TypeInt 32 0
|
||||
32: 31(int) Constant 0
|
||||
33: TypePointer Function 10(float)
|
||||
36: 10(float) Constant 1077936128
|
||||
37: TypeBool
|
||||
45: 10(float) Constant 1073741824
|
||||
51: TypePointer Output 11(fvec4)
|
||||
52(outv): 51(ptr) Variable Output
|
||||
53(S): TypeStruct 7(int)
|
||||
54(ubuf): TypeStruct 53(S)
|
||||
55: TypePointer Uniform 54(ubuf)
|
||||
56: 55(ptr) Variable Uniform
|
||||
57(S): TypeStruct 7(int)
|
||||
58: TypePointer Function 57(S)
|
||||
60: TypePointer Uniform 53(S)
|
||||
66: TypeImage 10(float) 2D sampled format:Unknown
|
||||
67: TypeSampledImage 66
|
||||
68: TypePointer UniformConstant 67
|
||||
69(s2d): 68(ptr) Variable UniformConstant
|
||||
71: TypeVector 10(float) 2
|
||||
72: 10(float) Constant 1056964608
|
||||
73: 71(fvec2) ConstantComposite 72 72
|
||||
77: TypePointer Uniform 7(int)
|
||||
106: 7(int) Constant 10
|
||||
111: 7(int) Constant 1
|
||||
114: TypePointer Output 10(float)
|
||||
117: 10(float) Constant 1092616192
|
||||
5(main): 3 Function None 4
|
||||
6: Label
|
||||
59(param): 58(ptr) Variable Function
|
||||
99(i): 19(ptr) Variable Function
|
||||
113: 16(ptr) Variable Function
|
||||
Line 1 30 0
|
||||
61: 60(ptr) AccessChain 56 18
|
||||
62: 53(S) Load 61
|
||||
63: 7(int) CompositeExtract 62 0
|
||||
64: 19(ptr) AccessChain 59(param) 18
|
||||
Store 64 63
|
||||
65: 11(fvec4) FunctionCall 14(foo(struct-S-i11;) 59(param)
|
||||
Store 52(outv) 65
|
||||
Line 1 31 0
|
||||
70: 67 Load 69(s2d)
|
||||
74: 11(fvec4) ImageSampleImplicitLod 70 73
|
||||
75: 11(fvec4) Load 52(outv)
|
||||
76: 11(fvec4) FAdd 75 74
|
||||
Store 52(outv) 76
|
||||
Line 1 33 0
|
||||
78: 77(ptr) AccessChain 56 18 18
|
||||
79: 7(int) Load 78
|
||||
SelectionMerge 83 None
|
||||
Switch 79 82
|
||||
case 10: 80
|
||||
case 20: 81
|
||||
82: Label
|
||||
Line 1 42 0
|
||||
94: 11(fvec4) Load 52(outv)
|
||||
95: 11(fvec4) CompositeConstruct 28 28 28 28
|
||||
96: 11(fvec4) FSub 94 95
|
||||
Store 52(outv) 96
|
||||
Line 1 43 0
|
||||
Branch 83
|
||||
80: Label
|
||||
Line 1 35 0
|
||||
84: 11(fvec4) Load 52(outv)
|
||||
85: 11(fvec4) CompositeConstruct 28 28 28 28
|
||||
86: 11(fvec4) FAdd 84 85
|
||||
Store 52(outv) 86
|
||||
Line 1 36 0
|
||||
Branch 83
|
||||
81: Label
|
||||
Line 1 38 0
|
||||
88: 11(fvec4) Load 52(outv)
|
||||
89: 11(fvec4) VectorTimesScalar 88 45
|
||||
Store 52(outv) 89
|
||||
Line 1 39 0
|
||||
90: 11(fvec4) Load 52(outv)
|
||||
91: 11(fvec4) CompositeConstruct 28 28 28 28
|
||||
92: 11(fvec4) FAdd 90 91
|
||||
Store 52(outv) 92
|
||||
Line 1 40 0
|
||||
Branch 83
|
||||
83: Label
|
||||
Line 1 46 0
|
||||
Store 99(i) 18
|
||||
Branch 100
|
||||
100: Label
|
||||
LoopMerge 102 103 None
|
||||
Branch 104
|
||||
104: Label
|
||||
105: 7(int) Load 99(i)
|
||||
107: 37(bool) SLessThan 105 106
|
||||
BranchConditional 107 101 102
|
||||
101: Label
|
||||
Line 1 47 0
|
||||
108: 11(fvec4) Load 52(outv)
|
||||
109: 11(fvec4) VectorTimesScalar 108 36
|
||||
Store 52(outv) 109
|
||||
Branch 103
|
||||
103: Label
|
||||
Line 1 46 0
|
||||
110: 7(int) Load 99(i)
|
||||
112: 7(int) IAdd 110 111
|
||||
Store 99(i) 112
|
||||
Branch 100
|
||||
102: Label
|
||||
Line 1 49 0
|
||||
115: 114(ptr) AccessChain 52(outv) 32
|
||||
116: 10(float) Load 115
|
||||
118: 37(bool) FOrdLessThan 116 117
|
||||
SelectionMerge 120 None
|
||||
BranchConditional 118 119 123
|
||||
119: Label
|
||||
Line 1 50 0
|
||||
121: 11(fvec4) Load 52(outv)
|
||||
122: 11(fvec4) ExtInst 2(GLSL.std.450) 13(Sin) 121
|
||||
Store 52(outv) 122
|
||||
Store 113 122
|
||||
Branch 120
|
||||
123: Label
|
||||
Line 1 51 0
|
||||
124: 11(fvec4) Load 52(outv)
|
||||
125: 11(fvec4) ExtInst 2(GLSL.std.450) 14(Cos) 124
|
||||
Store 52(outv) 125
|
||||
Store 113 125
|
||||
Branch 120
|
||||
120: Label
|
||||
Return
|
||||
FunctionEnd
|
||||
14(foo(struct-S-i11;): 11(fvec4) Function None 12
|
||||
13(s): 9(ptr) FunctionParameter
|
||||
15: Label
|
||||
17(r): 16(ptr) Variable Function
|
||||
Line 1 18 0
|
||||
20: 19(ptr) AccessChain 13(s) 18
|
||||
21: 7(int) Load 20
|
||||
22: 10(float) ConvertSToF 21
|
||||
25: 11(fvec4) Load 24(inv)
|
||||
26: 11(fvec4) VectorTimesScalar 25 22
|
||||
Store 17(r) 26
|
||||
Line 1 19 0
|
||||
27: 11(fvec4) Load 17(r)
|
||||
29: 11(fvec4) CompositeConstruct 28 28 28 28
|
||||
30: 11(fvec4) FAdd 27 29
|
||||
Store 17(r) 30
|
||||
Line 1 20 0
|
||||
34: 33(ptr) AccessChain 17(r) 32
|
||||
35: 10(float) Load 34
|
||||
38: 37(bool) FOrdGreaterThan 35 36
|
||||
SelectionMerge 40 None
|
||||
BranchConditional 38 39 44
|
||||
39: Label
|
||||
Line 1 21 0
|
||||
41: 11(fvec4) Load 17(r)
|
||||
42: 11(fvec4) CompositeConstruct 28 28 28 28
|
||||
43: 11(fvec4) FSub 41 42
|
||||
Store 17(r) 43
|
||||
Branch 40
|
||||
44: Label
|
||||
Line 1 23 0
|
||||
46: 11(fvec4) Load 17(r)
|
||||
47: 11(fvec4) VectorTimesScalar 46 45
|
||||
Store 17(r) 47
|
||||
Branch 40
|
||||
40: Label
|
||||
Line 1 25 0
|
||||
48: 11(fvec4) Load 17(r)
|
||||
ReturnValue 48
|
||||
FunctionEnd
|
|
@ -0,0 +1,88 @@
|
|||
spv.ssboAlias.frag
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 46
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main" 43
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Source HLSL 500
|
||||
Name 4 "main"
|
||||
Name 9 "@main("
|
||||
Name 13 "Buf1"
|
||||
MemberName 13(Buf1) 0 "@data"
|
||||
Name 15 "Buf1"
|
||||
Name 18 "Buf1@count"
|
||||
MemberName 18(Buf1@count) 0 "@count"
|
||||
Name 20 "Buf1@count"
|
||||
Name 30 "Buf2"
|
||||
Name 31 "Buf2@count"
|
||||
Name 43 "@entryPointOutput"
|
||||
Name 45 "Buf3"
|
||||
Decorate 12 ArrayStride 4
|
||||
MemberDecorate 13(Buf1) 0 Offset 0
|
||||
Decorate 13(Buf1) BufferBlock
|
||||
Decorate 15(Buf1) DescriptorSet 0
|
||||
Decorate 15(Buf1) Binding 84
|
||||
MemberDecorate 18(Buf1@count) 0 Offset 0
|
||||
Decorate 18(Buf1@count) BufferBlock
|
||||
Decorate 20(Buf1@count) DescriptorSet 0
|
||||
Decorate 20(Buf1@count) Binding 83
|
||||
Decorate 30(Buf2) DescriptorSet 0
|
||||
Decorate 30(Buf2) Binding 85
|
||||
Decorate 31(Buf2@count) DescriptorSet 0
|
||||
Decorate 31(Buf2@count) Binding 86
|
||||
Decorate 43(@entryPointOutput) Location 0
|
||||
Decorate 45(Buf3) DescriptorSet 0
|
||||
Decorate 45(Buf3) Binding 84
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeFloat 32
|
||||
7: TypeVector 6(float) 4
|
||||
8: TypeFunction 7(fvec4)
|
||||
11: TypeInt 32 0
|
||||
12: TypeRuntimeArray 11(int)
|
||||
13(Buf1): TypeStruct 12
|
||||
14: TypePointer Uniform 13(Buf1)
|
||||
15(Buf1): 14(ptr) Variable Uniform
|
||||
16: TypeInt 32 1
|
||||
17: 16(int) Constant 0
|
||||
18(Buf1@count): TypeStruct 16(int)
|
||||
19: TypePointer Uniform 18(Buf1@count)
|
||||
20(Buf1@count): 19(ptr) Variable Uniform
|
||||
21: TypePointer Uniform 16(int)
|
||||
23: 16(int) Constant 1
|
||||
24: 11(int) Constant 1
|
||||
25: 11(int) Constant 0
|
||||
27: 11(int) Constant 10
|
||||
28: TypePointer Uniform 11(int)
|
||||
30(Buf2): 14(ptr) Variable Uniform
|
||||
31(Buf2@count): 19(ptr) Variable Uniform
|
||||
34: 11(int) Constant 20
|
||||
36: 6(float) Constant 1065353216
|
||||
37: 6(float) Constant 1077936128
|
||||
38: 6(float) Constant 1084227584
|
||||
39: 7(fvec4) ConstantComposite 36 37 38 36
|
||||
42: TypePointer Output 7(fvec4)
|
||||
43(@entryPointOutput): 42(ptr) Variable Output
|
||||
45(Buf3): 14(ptr) Variable Uniform
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
44: 7(fvec4) FunctionCall 9(@main()
|
||||
Store 43(@entryPointOutput) 44
|
||||
Return
|
||||
FunctionEnd
|
||||
9(@main(): 7(fvec4) Function None 8
|
||||
10: Label
|
||||
22: 21(ptr) AccessChain 20(Buf1@count) 17
|
||||
26: 11(int) AtomicIAdd 22 24 25 23
|
||||
29: 28(ptr) AccessChain 15(Buf1) 17 26
|
||||
Store 29 27
|
||||
32: 21(ptr) AccessChain 31(Buf2@count) 17
|
||||
33: 11(int) AtomicIAdd 32 24 25 23
|
||||
35: 28(ptr) AccessChain 30(Buf2) 17 33
|
||||
Store 35 34
|
||||
ReturnValue 39
|
||||
FunctionEnd
|
|
@ -0,0 +1,38 @@
|
|||
spv.texture.sampler.transform.frag
|
||||
Warning, version 440 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 19
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main" 9 16
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Source GLSL 440
|
||||
Name 4 "main"
|
||||
Name 9 "color"
|
||||
Name 12 "tex"
|
||||
Name 16 "coord"
|
||||
Decorate 12(tex) DescriptorSet 0
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeFloat 32
|
||||
7: TypeVector 6(float) 4
|
||||
8: TypePointer Output 7(fvec4)
|
||||
9(color): 8(ptr) Variable Output
|
||||
10: TypeImage 6(float) 2D sampled format:Unknown
|
||||
11: TypePointer UniformConstant 10
|
||||
12(tex): 11(ptr) Variable UniformConstant
|
||||
14: TypeVector 6(float) 2
|
||||
15: TypePointer Input 14(fvec2)
|
||||
16(coord): 15(ptr) Variable Input
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
13: 10 Load 12(tex)
|
||||
17: 14(fvec2) Load 16(coord)
|
||||
18: 7(fvec4) ImageSampleImplicitLod 13 17
|
||||
Store 9(color) 18
|
||||
Return
|
||||
FunctionEnd
|
|
@ -0,0 +1 @@
|
|||
#error should not be included
|
|
@ -0,0 +1,29 @@
|
|||
struct OS {
|
||||
SamplerState ss;
|
||||
float a;
|
||||
Texture2D tex;
|
||||
};
|
||||
|
||||
SamplerState gss;
|
||||
SamplerState gss2;
|
||||
Texture2D gtex;
|
||||
|
||||
float4 osCall(OS s)
|
||||
{
|
||||
return s.a * s.tex.Sample(s.ss, float2(0.2, 0.3));
|
||||
}
|
||||
|
||||
float4 main() : SV_TARGET0
|
||||
{
|
||||
OS os;
|
||||
os.ss = gss2;
|
||||
os.ss = gss;
|
||||
os.tex = gtex;
|
||||
os.a = 3.0;
|
||||
|
||||
// this should give an error
|
||||
//SamplerState localss;
|
||||
//localss = gss2;
|
||||
|
||||
return osCall(os);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
struct os {
|
||||
sampler2D s2D;
|
||||
};
|
||||
|
||||
struct os2 {
|
||||
sampler2D s2D;
|
||||
Texture2D tex;
|
||||
};
|
||||
|
||||
Texture2D tex;
|
||||
os s;
|
||||
os2 s2;
|
||||
|
||||
float4 osCall1(os s)
|
||||
{
|
||||
return tex.Sample(s.s2D, float2(0.2, 0.3));
|
||||
}
|
||||
|
||||
float4 osCall2(os s, float2 f2)
|
||||
{
|
||||
return tex.Sample(s.s2D, f2);
|
||||
}
|
||||
|
||||
float4 os2Call1(os2 s)
|
||||
{
|
||||
return s.tex.Sample(s.s2D, float2(0.2, 0.3));
|
||||
}
|
||||
|
||||
float4 os2Call2(os2 s, float2 f2)
|
||||
{
|
||||
return s.tex.Sample(s.s2D, f2);
|
||||
}
|
||||
|
||||
float4 main() : SV_TARGET0
|
||||
{
|
||||
return osCall1(s) +
|
||||
osCall2(s, float2(0.2, 0.3)) +
|
||||
os2Call1(s2) +
|
||||
os2Call2(s2, float2(0.2, 0.3));
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include "bar.h"
|
||||
#include "./inc1/bar.h"
|
||||
#include "inc2\bar.h"
|
||||
|
||||
float4 main() : SV_Position
|
||||
{
|
||||
return i1 + i2 + i3 + i4 + i5 + i6;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include "foo.h"
|
||||
#include "inc2/../foo.h"
|
||||
#include "inc1/badInc.h"
|
||||
|
||||
float4 main() : SV_Position
|
||||
{
|
||||
#error in main
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
#include "parentBad"
|
|
@ -0,0 +1,3 @@
|
|||
float4 i2;
|
||||
|
||||
#include "foo.h"
|
|
@ -0,0 +1,3 @@
|
|||
#include "parent.h"
|
||||
|
||||
float4 i3;
|
|
@ -0,0 +1,2 @@
|
|||
#include "foo.h"
|
||||
float4 i5;
|
|
@ -0,0 +1 @@
|
|||
float4 i6;
|
|
@ -0,0 +1,16 @@
|
|||
#version 450
|
||||
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define float4 vec4
|
||||
|
||||
#include "bar.h"
|
||||
#include "./inc1/bar.h"
|
||||
#include "inc2\bar.h"
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = i1 + i2 + i3 + i4 + i5 + i6;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
float4 i4;
|
|
@ -0,0 +1,3 @@
|
|||
int a;
|
||||
|
||||
#error bad parent
|
|
@ -90,14 +90,32 @@ diff -b $BASEDIR/hlsl.hlslOffset.vert.out $TARGETDIR/hlsl.hlslOffset.vert.out ||
|
|||
#
|
||||
echo Configuring HLSL descriptor set and binding number manually
|
||||
$EXE -V -D -e main -H hlsl.multiDescriptorSet.frag --rsb frag t0 0 0 t1 1 0 s0 0 1 s1 1 1 b0 2 0 b1 2 1 b2 2 2 > $TARGETDIR/hlsl.multiDescriptorSet.frag.out
|
||||
diff -b $BASEDIR/hlsl.multiDescriptorSet.frag.out $TARGETDIR/hlsl.multiDescriptorSet.frag.out
|
||||
diff -b $BASEDIR/hlsl.multiDescriptorSet.frag.out $TARGETDIR/hlsl.multiDescriptorSet.frag.out || HASERROR=1
|
||||
|
||||
#
|
||||
# Testing location error
|
||||
#
|
||||
echo Testing SPV no location
|
||||
$EXE -V -C spv.noLocation.vert > $TARGETDIR/spv.noLocation.vert.out
|
||||
diff -b $BASEDIR/spv.noLocation.vert.out $TARGETDIR/spv.noLocation.vert.out
|
||||
diff -b $BASEDIR/spv.noLocation.vert.out $TARGETDIR/spv.noLocation.vert.out || HASERROR=1
|
||||
|
||||
#
|
||||
# Testing debug information
|
||||
#
|
||||
echo Testing SPV Debug Information
|
||||
$EXE -g -H spv.debugInfo.frag > $TARGETDIR/spv.debugInfo.frag.out
|
||||
diff -b $BASEDIR/spv.debugInfo.frag.out $TARGETDIR/spv.debugInfo.frag.out || HASERROR=1
|
||||
|
||||
#
|
||||
# Testing Includer
|
||||
#
|
||||
echo Testing Includer
|
||||
$EXE -D -e main -H ../Test/hlsl.include.vert > $TARGETDIR/hlsl.include.vert.out
|
||||
diff -b $BASEDIR/hlsl.include.vert.out $TARGETDIR/hlsl.include.vert.out || HASERROR=1
|
||||
$EXE -D -e main -H hlsl.includeNegative.vert > $TARGETDIR/hlsl.includeNegative.vert.out
|
||||
diff -b $BASEDIR/hlsl.includeNegative.vert.out $TARGETDIR/hlsl.includeNegative.vert.out || HASERROR=1
|
||||
$EXE -l -i include.vert > $TARGETDIR/include.vert.out
|
||||
diff -b $BASEDIR/include.vert.out $TARGETDIR/include.vert.out || HASERROR=1
|
||||
|
||||
#
|
||||
# Final checking
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#version 450
|
||||
|
||||
struct S {
|
||||
int a;
|
||||
};
|
||||
|
||||
uniform ubuf {
|
||||
S s;
|
||||
};
|
||||
|
||||
uniform sampler2D s2d;
|
||||
|
||||
layout(location = 0) in vec4 inv;
|
||||
layout(location = 0) out vec4 outv;
|
||||
|
||||
vec4 foo(S s)
|
||||
{
|
||||
vec4 r = s.a * inv;
|
||||
++r;
|
||||
if (r.x > 3.0)
|
||||
--r;
|
||||
else
|
||||
r *= 2;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
outv = foo(s);
|
||||
outv += texture(s2d, vec2(0.5));
|
||||
|
||||
switch (s.a) {
|
||||
case 10:
|
||||
++outv;
|
||||
break;
|
||||
case 20:
|
||||
outv = 2 * outv;
|
||||
++outv;
|
||||
break;
|
||||
default:
|
||||
--outv;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
outv *= 3.0;
|
||||
|
||||
outv.x < 10.0 ?
|
||||
outv = sin(outv) :
|
||||
outv = cos(outv);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
AppendStructuredBuffer<uint> Buf1 : register(u1);
|
||||
AppendStructuredBuffer<uint> Buf2 : register(u2);
|
||||
AppendStructuredBuffer<uint> Buf3 : register(u1);
|
||||
|
||||
float4 main() : SV_Target
|
||||
{
|
||||
Buf1.Append(10u);
|
||||
Buf2.Append(20u);
|
||||
return float4(1.0, 3.0, 5.0, 1.0);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#version 440
|
||||
|
||||
uniform sampler smp;
|
||||
uniform texture2D tex;
|
||||
|
||||
in vec2 coord;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = texture(sampler2D(tex, smp), coord);
|
||||
}
|
|
@ -1310,6 +1310,7 @@ public:
|
|||
|
||||
virtual TBasicType getBasicType() const { return basicType; }
|
||||
virtual const TSampler& getSampler() const { return sampler; }
|
||||
virtual TSampler& getSampler() { return sampler; }
|
||||
|
||||
virtual TQualifier& getQualifier() { return qualifier; }
|
||||
virtual const TQualifier& getQualifier() const { return qualifier; }
|
||||
|
|
|
@ -1776,6 +1776,14 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
|
|||
// Propagate 'noContraction' label in backward from 'precise' variables.
|
||||
glslang::PropagateNoContraction(*this);
|
||||
|
||||
switch (textureSamplerTransformMode) {
|
||||
case EShTexSampTransKeep:
|
||||
break;
|
||||
case EShTexSampTransUpgradeTextureRemoveSampler:
|
||||
performTextureUpgradeAndSamplerRemovalTransformation(root);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2943,4 +2951,41 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt
|
|||
(node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
|
||||
}
|
||||
|
||||
struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
|
||||
bool visitAggregate(TVisit, TIntermAggregate* ag) override {
|
||||
using namespace std;
|
||||
TIntermSequence& seq = ag->getSequence();
|
||||
// remove pure sampler variables
|
||||
TIntermSequence::iterator newEnd = remove_if(seq.begin(), seq.end(), [](TIntermNode* node) {
|
||||
TIntermSymbol* symbol = node->getAsSymbolNode();
|
||||
if (!symbol)
|
||||
return false;
|
||||
|
||||
return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler());
|
||||
});
|
||||
seq.erase(newEnd, seq.end());
|
||||
// replace constructors with sampler/textures
|
||||
// update textures into sampled textures
|
||||
for_each(seq.begin(), seq.end(), [](TIntermNode*& node) {
|
||||
TIntermSymbol* symbol = node->getAsSymbolNode();
|
||||
if (!symbol) {
|
||||
TIntermAggregate *constructor = node->getAsAggregate();
|
||||
if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
|
||||
if (!constructor->getSequence().empty())
|
||||
node = constructor->getSequence()[0];
|
||||
}
|
||||
} else if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
|
||||
symbol->getWritableType().getSampler().combined = true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root)
|
||||
{
|
||||
TextureUpgradeAndSamplerRemovalTransform transform;
|
||||
root->traverse(&transform);
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
|
|
@ -2102,6 +2102,17 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
|||
case EOpConstructDMat4x2:
|
||||
case EOpConstructDMat4x3:
|
||||
case EOpConstructDMat4x4:
|
||||
#ifdef AMD_EXTENSIONS
|
||||
case EOpConstructF16Mat2x2:
|
||||
case EOpConstructF16Mat2x3:
|
||||
case EOpConstructF16Mat2x4:
|
||||
case EOpConstructF16Mat3x2:
|
||||
case EOpConstructF16Mat3x3:
|
||||
case EOpConstructF16Mat3x4:
|
||||
case EOpConstructF16Mat4x2:
|
||||
case EOpConstructF16Mat4x3:
|
||||
case EOpConstructF16Mat4x4:
|
||||
#endif
|
||||
constructingMatrix = true;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -728,6 +728,11 @@ bool ProcessDeferred(
|
|||
intermediate.setOriginUpperLeft();
|
||||
if ((messages & EShMsgHlslOffsets) || (messages & EShMsgReadHlsl))
|
||||
intermediate.setHlslOffsets();
|
||||
if (messages & EShMsgDebugInfo) {
|
||||
intermediate.setSourceFile(names[numPre]);
|
||||
for (int s = 0; s < numStrings; ++s)
|
||||
intermediate.addSourceText(strings[numPre]);
|
||||
}
|
||||
SetupBuiltinSymbolTable(version, profile, spvVersion, source);
|
||||
|
||||
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
|
||||
|
@ -1578,6 +1583,7 @@ void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslI
|
|||
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
||||
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
||||
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
|
||||
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
|
||||
|
||||
//
|
||||
// Turn the shader strings into a parse tree in the TIntermediate.
|
||||
|
@ -1601,11 +1607,6 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
|
|||
forwardCompatible, messages, *intermediate, includer, sourceEntryPointName);
|
||||
}
|
||||
|
||||
bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
|
||||
{
|
||||
return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
|
||||
}
|
||||
|
||||
// Fill in a string with the result of preprocessing ShaderStrings
|
||||
// Returns true if all extensions, pragmas and version strings were valid.
|
||||
bool TShader::preprocess(const TBuiltInResource* builtInResources,
|
||||
|
|
|
@ -374,7 +374,12 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
|||
int reserveSlot(int set, int slot)
|
||||
{
|
||||
TSlotSet::iterator at = findSlot(set, slot);
|
||||
slots[set].insert(at, slot);
|
||||
|
||||
// tolerate aliasing, by not double-recording aliases
|
||||
// (policy about appropriateness of the alias is higher up)
|
||||
if (at == slots[set].end() || *at != slot)
|
||||
slots[set].insert(at, slot);
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
|
@ -468,24 +473,6 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
|
|||
{
|
||||
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
||||
{
|
||||
if (type.getQualifier().hasBinding()) {
|
||||
const int set = getLayoutSet(type);
|
||||
|
||||
if (isImageType(type))
|
||||
return checkEmpty(set, baseImageBinding + type.getQualifier().layoutBinding);
|
||||
|
||||
if (isTextureType(type))
|
||||
return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
||||
|
||||
if (isSsboType(type))
|
||||
return checkEmpty(set, baseSsboBinding + type.getQualifier().layoutBinding);
|
||||
|
||||
if (isSamplerType(type))
|
||||
return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
||||
|
||||
if (isUboType(type))
|
||||
return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -496,7 +483,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
|
|||
if (type.getQualifier().hasBinding()) {
|
||||
if (isImageType(type))
|
||||
return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
|
||||
|
||||
|
||||
if (isTextureType(type))
|
||||
return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
||||
|
||||
|
@ -588,21 +575,6 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
|
|||
{
|
||||
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
||||
{
|
||||
if (type.getQualifier().hasBinding()) {
|
||||
const int set = getLayoutSet(type);
|
||||
|
||||
if (isUavType(type))
|
||||
return checkEmpty(set, baseUavBinding + type.getQualifier().layoutBinding);
|
||||
|
||||
if (isSrvType(type))
|
||||
return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
||||
|
||||
if (isSamplerType(type))
|
||||
return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
||||
|
||||
if (isUboType(type))
|
||||
return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,8 @@ public:
|
|||
useUnknownFormat(false),
|
||||
hlslOffsets(false),
|
||||
useStorageBuffer(false),
|
||||
hlslIoMapping(false)
|
||||
hlslIoMapping(false),
|
||||
textureSamplerTransformMode(EShTexSampTransKeep)
|
||||
{
|
||||
localSize[0] = 1;
|
||||
localSize[1] = 1;
|
||||
|
@ -233,6 +234,7 @@ public:
|
|||
bool usingStorageBuffer() const { return useStorageBuffer; }
|
||||
void setHlslIoMapping(bool b) { hlslIoMapping = b; }
|
||||
bool usingHlslIoMapping() { return hlslIoMapping; }
|
||||
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
||||
|
||||
void setVersion(int v) { version = v; }
|
||||
int getVersion() const { return version; }
|
||||
|
@ -449,6 +451,11 @@ public:
|
|||
return semanticNameSet.insert(name).first->c_str();
|
||||
}
|
||||
|
||||
void setSourceFile(const char* file) { sourceFile = file; }
|
||||
const std::string& getSourceFile() const { return sourceFile; }
|
||||
void addSourceText(const char* text) { sourceText = sourceText + text; }
|
||||
const std::string& getSourceText() const { return sourceText; }
|
||||
|
||||
const char* const implicitThisName = "@this";
|
||||
|
||||
protected:
|
||||
|
@ -472,6 +479,7 @@ protected:
|
|||
void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
|
||||
void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
|
||||
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
||||
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
||||
|
||||
const EShLanguage language; // stage, known at construction time
|
||||
EShSource source; // source language, known a bit later
|
||||
|
@ -536,6 +544,12 @@ protected:
|
|||
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
||||
std::set<TString> semanticNameSet;
|
||||
|
||||
EShTextureSamplerTransformMode textureSamplerTransformMode;
|
||||
|
||||
// source code of shader, useful as part of debug information
|
||||
std::string sourceFile;
|
||||
std::string sourceText;
|
||||
|
||||
private:
|
||||
void operator=(TIntermediate&); // prevent assignments
|
||||
};
|
||||
|
|
|
@ -613,14 +613,14 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
|
|||
TShader::Includer::IncludeResult* res = nullptr;
|
||||
if (startWithLocalSearch)
|
||||
res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
|
||||
if (! res || res->headerName.empty()) {
|
||||
if (res == nullptr || res->headerName.empty()) {
|
||||
includer.releaseInclude(res);
|
||||
res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
|
||||
}
|
||||
|
||||
// Process the results
|
||||
if (res && !res->headerName.empty()) {
|
||||
if (res->headerData && res->headerLength) {
|
||||
if (res != nullptr && !res->headerName.empty()) {
|
||||
if (res->headerData != nullptr && res->headerLength > 0) {
|
||||
// path for processing one or more tokens from an included header, hand off 'res'
|
||||
const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
|
||||
std::ostringstream prologue;
|
||||
|
@ -638,8 +638,8 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
|
|||
} else {
|
||||
// error path, clean up
|
||||
std::string message =
|
||||
res ? std::string(res->headerData, res->headerLength)
|
||||
: std::string("Could not process include directive");
|
||||
res != nullptr ? std::string(res->headerData, res->headerLength)
|
||||
: std::string("Could not process include directive");
|
||||
parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str());
|
||||
includer.releaseInclude(res);
|
||||
}
|
||||
|
|
|
@ -134,6 +134,14 @@ typedef enum {
|
|||
EShOptFull, // Optimizations that will take more time
|
||||
} EShOptimizationLevel;
|
||||
|
||||
//
|
||||
// Texture and Sampler transformation mode.
|
||||
//
|
||||
typedef enum {
|
||||
EShTexSampTransKeep, // keep textures and samplers as is (default)
|
||||
EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers
|
||||
} EShTextureSamplerTransformMode;
|
||||
|
||||
//
|
||||
// Message choices for what errors and warnings are given.
|
||||
//
|
||||
|
@ -149,6 +157,7 @@ enum EShMessages {
|
|||
EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit
|
||||
EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions
|
||||
EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules
|
||||
EShMsgDebugInfo = (1 << 10), // save debug information
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -313,6 +322,7 @@ public:
|
|||
void setHlslIoMapping(bool hlslIoMap);
|
||||
void setFlattenUniformArrays(bool flatten);
|
||||
void setNoStorageFormat(bool useUnknownFormat);
|
||||
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
|
||||
|
||||
// Interface to #include handlers.
|
||||
//
|
||||
|
@ -397,6 +407,9 @@ public:
|
|||
virtual void releaseInclude(IncludeResult*) override { }
|
||||
};
|
||||
|
||||
bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||
bool forwardCompatible, EShMessages, Includer&);
|
||||
|
||||
bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||
bool forwardCompatible, EShMessages messages)
|
||||
{
|
||||
|
@ -404,12 +417,18 @@ public:
|
|||
return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
|
||||
}
|
||||
|
||||
bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||
bool forwardCompatible, EShMessages, Includer&);
|
||||
|
||||
// Equivalent to parse() without a default profile and without forcing defaults.
|
||||
// Provided for backwards compatibility.
|
||||
bool parse(const TBuiltInResource*, int defaultVersion, bool forwardCompatible, EShMessages);
|
||||
bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
|
||||
{
|
||||
return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
|
||||
}
|
||||
|
||||
bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages,
|
||||
Includer& includer)
|
||||
{
|
||||
return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer);
|
||||
}
|
||||
|
||||
bool preprocess(const TBuiltInResource* builtInResources,
|
||||
int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||
bool forwardCompatible, EShMessages message, std::string* outputString,
|
||||
|
|
|
@ -81,6 +81,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||
ToSpirv, HlslCompileTest,
|
||||
::testing::ValuesIn(std::vector<FileNameEntryPointPair>{
|
||||
{"hlsl.amend.frag", "f1"},
|
||||
{"hlsl.aliasOpaque.frag", "main"},
|
||||
{"hlsl.array.frag", "PixelShaderFunction"},
|
||||
{"hlsl.array.implicit-size.frag", "PixelShaderFunction"},
|
||||
{"hlsl.array.multidim.frag", "main"},
|
||||
|
@ -114,6 +115,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||
{"hlsl.float1.frag", "PixelShaderFunction"},
|
||||
{"hlsl.float4.frag", "PixelShaderFunction"},
|
||||
{"hlsl.flatten.return.frag", "main"},
|
||||
{"hlsl.flattenOpaque.frag", "main"},
|
||||
{"hlsl.forLoop.frag", "PixelShaderFunction"},
|
||||
{"hlsl.gather.array.dx10.frag", "main"},
|
||||
{"hlsl.gather.basic.dx10.frag", "main"},
|
||||
|
|
|
@ -75,6 +75,7 @@ using CompileVulkanToSpirvTestAMD = GlslangTest<::testing::TestWithParam<std::st
|
|||
#ifdef NV_EXTENSIONS
|
||||
using CompileVulkanToSpirvTestNV = GlslangTest<::testing::TestWithParam<std::string>>;
|
||||
#endif
|
||||
using CompileUpgradeTextureToSampledTextureAndDropSamplersTest = GlslangTest<::testing::TestWithParam<std::string>>;
|
||||
|
||||
// Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully
|
||||
// generate SPIR-V.
|
||||
|
@ -172,6 +173,15 @@ TEST_P(CompileVulkanToSpirvTestNV, FromFile)
|
|||
}
|
||||
#endif
|
||||
|
||||
TEST_P(CompileUpgradeTextureToSampledTextureAndDropSamplersTest, FromFile)
|
||||
{
|
||||
loadCompileUpgradeTextureToSampledTextureAndDropSamplersAndCheck(GlobalTestSettings.testRoot,
|
||||
GetParam(),
|
||||
Source::GLSL,
|
||||
Semantics::Vulkan,
|
||||
Target::Spv);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Glsl, CompileVulkanToSpirvTest,
|
||||
|
@ -320,6 +330,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||
{ "spv.register.autoassign-2.frag", "main", 5, 10, 0, 15, 30, true, true },
|
||||
{ "spv.buffer.autoassign.frag", "main", 5, 10, 0, 15, 30, true, true },
|
||||
{ "spv.ssbo.autoassign.frag", "main", 5, 10, 0, 15, 30, true, true },
|
||||
{ "spv.ssboAlias.frag", "main", 0, 0, 0, 0, 83, true, false },
|
||||
{ "spv.rw.autoassign.frag", "main", 5, 10, 20, 15, 30, true, true },
|
||||
{ "spv.register.autoassign.rangetest.frag", "main",
|
||||
glslang::TQualifier::layoutBindingEnd-2,
|
||||
|
@ -407,6 +418,14 @@ INSTANTIATE_TEST_CASE_P(
|
|||
FileNameAsCustomTestSuffix
|
||||
);
|
||||
#endif
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Glsl, CompileUpgradeTextureToSampledTextureAndDropSamplersTest,
|
||||
::testing::ValuesIn(std::vector<std::string>({
|
||||
"spv.texture.sampler.transform.frag",
|
||||
})),
|
||||
FileNameAsCustomTestSuffix
|
||||
);
|
||||
// clang-format on
|
||||
|
||||
} // anonymous namespace
|
||||
|
|
|
@ -197,12 +197,14 @@ public:
|
|||
GlslangResult compileAndLink(
|
||||
const std::string shaderName, const std::string& code,
|
||||
const std::string& entryPointName, EShMessages controls,
|
||||
bool flattenUniformArrays = false)
|
||||
bool flattenUniformArrays = false,
|
||||
EShTextureSamplerTransformMode texSampTransMode = EShTexSampTransKeep)
|
||||
{
|
||||
const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
|
||||
|
||||
glslang::TShader shader(kind);
|
||||
shader.setAutoMapLocations(true);
|
||||
shader.setTextureSamplerTransformMode(texSampTransMode);
|
||||
shader.setFlattenUniformArrays(flattenUniformArrays);
|
||||
|
||||
bool success = compile(&shader, code, entryPointName, controls);
|
||||
|
@ -570,6 +572,31 @@ public:
|
|||
expectedErrorFname);
|
||||
}
|
||||
|
||||
void loadCompileUpgradeTextureToSampledTextureAndDropSamplersAndCheck(const std::string& testDir,
|
||||
const std::string& testName,
|
||||
Source source,
|
||||
Semantics semantics,
|
||||
Target target,
|
||||
const std::string& entryPointName = "")
|
||||
{
|
||||
const std::string inputFname = testDir + "/" + testName;
|
||||
const std::string expectedOutputFname = testDir + "/baseResults/" + testName + ".out";
|
||||
std::string input, expectedOutput;
|
||||
|
||||
tryLoadFile(inputFname, "input", &input);
|
||||
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
|
||||
|
||||
const EShMessages controls = DeriveOptions(source, semantics, target);
|
||||
GlslangResult result = compileAndLink(testName, input, entryPointName, controls, false, EShTexSampTransUpgradeTextureRemoveSampler);
|
||||
|
||||
// Generate the hybrid output in the way of glslangValidator.
|
||||
std::ostringstream stream;
|
||||
outputResultToStream(&stream, result, controls);
|
||||
|
||||
checkEqAndUpdateIfRequested(expectedOutput, stream.str(),
|
||||
expectedOutputFname);
|
||||
}
|
||||
|
||||
private:
|
||||
const int defaultVersion;
|
||||
const EProfile defaultProfile;
|
||||
|
|
|
@ -147,7 +147,7 @@ bool HlslParseContext::parseShaderStrings(TPpContext& ppContext, TInputScanner&
|
|||
//
|
||||
bool HlslParseContext::shouldConvertLValue(const TIntermNode* node) const
|
||||
{
|
||||
if (node == nullptr)
|
||||
if (node == nullptr || node->getAsTyped() == nullptr)
|
||||
return false;
|
||||
|
||||
const TIntermAggregate* lhsAsAggregate = node->getAsAggregate();
|
||||
|
@ -157,10 +157,14 @@ bool HlslParseContext::shouldConvertLValue(const TIntermNode* node) const
|
|||
if (lhsAsBinary != nullptr &&
|
||||
(lhsAsBinary->getOp() == EOpVectorSwizzle || lhsAsBinary->getOp() == EOpIndexDirect))
|
||||
lhsAsAggregate = lhsAsBinary->getLeft()->getAsAggregate();
|
||||
|
||||
if (lhsAsAggregate != nullptr && lhsAsAggregate->getOp() == EOpImageLoad)
|
||||
return true;
|
||||
|
||||
// If it's a syntactic write to a sampler, we will use that to establish
|
||||
// a compile-time alias.
|
||||
if (node->getAsTyped()->getBasicType() == EbtSampler)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -233,7 +237,7 @@ bool HlslParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, T
|
|||
//
|
||||
// Most things are passed through unmodified, except for error checking.
|
||||
//
|
||||
TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char* op, TIntermTyped* node)
|
||||
TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char* op, TIntermTyped*& node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return nullptr;
|
||||
|
@ -256,6 +260,10 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
|
|||
|
||||
// *** If we get here, we're going to apply some conversion to an l-value.
|
||||
|
||||
// Spin off sampler aliasing
|
||||
if (node->getAsTyped()->getBasicType() == EbtSampler)
|
||||
return handleSamplerLvalue(loc, op, node);
|
||||
|
||||
// Helper to create a load.
|
||||
const auto makeLoad = [&](TIntermSymbol* rhsTmp, TIntermTyped* object, TIntermTyped* coord, const TType& derefType) {
|
||||
TIntermAggregate* loadOp = new TIntermAggregate(EOpImageLoad);
|
||||
|
@ -500,6 +508,42 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
|
|||
return node;
|
||||
}
|
||||
|
||||
// Deal with sampler aliasing: turning assignments into aliases
|
||||
TIntermTyped* HlslParseContext::handleSamplerLvalue(const TSourceLoc& loc, const char* op, TIntermTyped*& node)
|
||||
{
|
||||
// Can only alias an assignment: "s1 = s2"
|
||||
TIntermBinary* binary = node->getAsBinaryNode();
|
||||
if (binary == nullptr || node->getAsOperator()->getOp() != EOpAssign ||
|
||||
binary->getLeft() ->getAsSymbolNode() == nullptr ||
|
||||
binary->getRight()->getAsSymbolNode() == nullptr) {
|
||||
error(loc, "can't modify sampler", op, "");
|
||||
return node;
|
||||
}
|
||||
|
||||
// Best is if we are aliasing a flattened struct member "S.s1 = s2",
|
||||
// in which case we want to update the flattening information with the alias,
|
||||
// making everything else work seamlessly.
|
||||
TIntermSymbol* left = binary->getLeft()->getAsSymbolNode();
|
||||
TIntermSymbol* right = binary->getRight()->getAsSymbolNode();
|
||||
for (auto fit = flattenMap.begin(); fit != flattenMap.end(); ++fit) {
|
||||
for (auto mit = fit->second.members.begin(); mit != fit->second.members.end(); ++mit) {
|
||||
if ((*mit)->getUniqueId() == left->getId()) {
|
||||
// found it: update with alias to the existing variable, and don't emit any code
|
||||
(*mit) = new TVariable(&right->getName(), right->getType());
|
||||
(*mit)->setUniqueId(right->getId());
|
||||
// replace node (rest of compiler expects either an error or code to generate)
|
||||
// with pointless access
|
||||
node = binary->getRight();
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
warn(loc, "could not create alias for sampler", op, "");
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void HlslParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
|
||||
{
|
||||
if (pragmaCallback)
|
||||
|
@ -774,7 +818,7 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc,
|
|||
else {
|
||||
// at least one of base and index is variable...
|
||||
|
||||
if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlattenUniform(base->getType()))) {
|
||||
if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlatten(base->getType()))) {
|
||||
if (index->getQualifier().storage != EvqConst)
|
||||
error(loc, "Invalid variable index to flattened array", base->getAsSymbolNode()->getName().c_str(), "");
|
||||
|
||||
|
@ -981,7 +1025,7 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
|
|||
}
|
||||
}
|
||||
if (fieldFound) {
|
||||
if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlattenUniform(base->getType()))) {
|
||||
if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlatten(base->getType()))) {
|
||||
result = flattenAccess(base, member);
|
||||
} else {
|
||||
// Update the base and member to access if this was a split structure.
|
||||
|
@ -1115,14 +1159,13 @@ TType& HlslParseContext::split(TType& type, TString name, const TType* outerStru
|
|||
return type;
|
||||
}
|
||||
|
||||
// Is this a uniform array which should be flattened?
|
||||
bool HlslParseContext::shouldFlattenUniform(const TType& type) const
|
||||
// Is this a uniform array or structure which should be flattened?
|
||||
bool HlslParseContext::shouldFlatten(const TType& type) const
|
||||
{
|
||||
const TStorageQualifier qualifier = type.getQualifier().storage;
|
||||
|
||||
return qualifier == EvqUniform &&
|
||||
((type.isArray() && intermediate.getFlattenUniformArrays()) || type.isStruct()) &&
|
||||
type.containsOpaque();
|
||||
return (qualifier == EvqUniform && type.isArray() && intermediate.getFlattenUniformArrays()) ||
|
||||
type.isStruct() && type.containsOpaque();
|
||||
}
|
||||
|
||||
// Top level variable flattening: construct data
|
||||
|
@ -1285,16 +1328,22 @@ bool HlslParseContext::wasSplit(const TIntermTyped* node) const
|
|||
// Turn an access into an aggregate that was flattened to instead be
|
||||
// an access to the individual variable the member was flattened to.
|
||||
// Assumes shouldFlatten() or equivalent was called first.
|
||||
// Also assumes that initFlattening() and finalizeFlattening() bracket the usage.
|
||||
TIntermTyped* HlslParseContext::flattenAccess(TIntermTyped* base, int member)
|
||||
{
|
||||
const TType dereferencedType(base->getType(), member); // dereferenced type
|
||||
|
||||
const TIntermSymbol& symbolNode = *base->getAsSymbolNode();
|
||||
|
||||
const auto flattenData = flattenMap.find(symbolNode.getId());
|
||||
TIntermTyped* flattened = flattenAccess(symbolNode.getId(), member, dereferencedType);
|
||||
|
||||
return flattened ? flattened : base;
|
||||
}
|
||||
TIntermTyped* HlslParseContext::flattenAccess(int uniqueId, int member, const TType& dereferencedType)
|
||||
{
|
||||
const auto flattenData = flattenMap.find(uniqueId);
|
||||
|
||||
if (flattenData == flattenMap.end())
|
||||
return base;
|
||||
return nullptr;
|
||||
|
||||
// Calculate new cumulative offset from the packed tree
|
||||
flattenOffset.back() = flattenData->second.offsets[flattenOffset.back() + member];
|
||||
|
@ -1307,7 +1356,7 @@ TIntermTyped* HlslParseContext::flattenAccess(TIntermTyped* base, int member)
|
|||
} else {
|
||||
// If this is not the final flattening, accumulate the position and return
|
||||
// an object of the partially dereferenced type.
|
||||
return new TIntermSymbol(symbolNode.getId(), "flattenShadow", dereferencedType);
|
||||
return new TIntermSymbol(uniqueId, "flattenShadow", dereferencedType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1663,15 +1712,32 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
|
|||
symbolTable.makeInternalVariable(*variable);
|
||||
pushImplicitThis(variable);
|
||||
}
|
||||
|
||||
// Insert the parameters with name in the symbol table.
|
||||
if (! symbolTable.insert(*variable))
|
||||
error(loc, "redefinition", variable->getName().c_str(), "");
|
||||
// Add the parameter to the AST
|
||||
paramNodes = intermediate.growAggregate(paramNodes,
|
||||
intermediate.addSymbol(*variable, loc),
|
||||
loc);
|
||||
|
||||
// Add hidden parameter for struct buffer counters, if needed.
|
||||
// Add parameters to the AST list.
|
||||
if (shouldFlatten(variable->getType())) {
|
||||
// Expand the AST parameter nodes (but not the name mangling or symbol table view)
|
||||
// for structures that need to be flattened.
|
||||
flatten(loc, *variable);
|
||||
const TTypeList* structure = variable->getType().getStruct();
|
||||
for (int mem = 0; mem < (int)structure->size(); ++mem) {
|
||||
initFlattening();
|
||||
paramNodes = intermediate.growAggregate(paramNodes,
|
||||
flattenAccess(variable->getUniqueId(), mem, *(*structure)[mem].type),
|
||||
loc);
|
||||
finalizeFlattening();
|
||||
}
|
||||
} else {
|
||||
// Add the parameter to the AST
|
||||
paramNodes = intermediate.growAggregate(paramNodes,
|
||||
intermediate.addSymbol(*variable, loc),
|
||||
loc);
|
||||
}
|
||||
|
||||
// Add hidden AST parameter for struct buffer counters, if needed.
|
||||
addStructBufferHiddenCounterParam(loc, param, paramNodes);
|
||||
} else
|
||||
paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc);
|
||||
|
@ -2265,7 +2331,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
|||
const bool flattened = isLeft ? isFlattenLeft : isFlattenRight;
|
||||
const bool split = isLeft ? isSplitLeft : isSplitRight;
|
||||
const TIntermTyped* outer = isLeft ? outerLeft : outerRight;
|
||||
const TVector<TVariable*>& flatVariables = isLeft ? *leftVariables : *rightVariables;
|
||||
const TVector<TVariable*>& flatVariables = isLeft ? *leftVariables : *rightVariables;
|
||||
|
||||
// Index operator if it's an aggregate, else EOpNull
|
||||
const TOperator op = node->getType().isArray() ? EOpIndexDirect :
|
||||
|
@ -2320,7 +2386,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
|||
const int elementsToCopy = std::min(elementsL, elementsR);
|
||||
|
||||
// array case
|
||||
for (int element=0; element < elementsToCopy; ++element) {
|
||||
for (int element = 0; element < elementsToCopy; ++element) {
|
||||
arrayElement.push_back(element);
|
||||
|
||||
// Add a new AST symbol node if we have a temp variable holding a complex RHS.
|
||||
|
@ -2511,7 +2577,7 @@ bool HlslParseContext::hasStructBuffCounter(const TType& type) const
|
|||
case EbvRWStructuredBuffer: // ...
|
||||
return true;
|
||||
default:
|
||||
return false; // the other structuredbfufer types do not have a counter.
|
||||
return false; // the other structuredbuffer types do not have a counter.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4419,14 +4485,18 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
|
|||
pushFrontArguments(intermediate.addSymbol(*getImplicitThis(thisDepth)), arguments);
|
||||
}
|
||||
|
||||
// Convert 'in' arguments
|
||||
// Convert 'in' arguments, so that types match.
|
||||
// However, skip those that need expansion, that is covered next.
|
||||
if (arguments)
|
||||
addInputArgumentConversions(*fnCandidate, arguments);
|
||||
|
||||
// If any argument is a pass-by-reference struct buffer with an associated counter
|
||||
// buffer, we have to add another hidden parameter for that counter.
|
||||
if (aggregate && !builtIn)
|
||||
addStructBuffArguments(loc, aggregate);
|
||||
// Expand arguments. Some arguments must physically expand to a different set
|
||||
// than what the shader declared and passes.
|
||||
if (arguments && !builtIn)
|
||||
expandArguments(loc, *fnCandidate, arguments);
|
||||
|
||||
// Expansion may have changed the form of arguments
|
||||
aggregate = arguments ? arguments->getAsAggregate() : nullptr;
|
||||
|
||||
op = fnCandidate->getBuiltInOp();
|
||||
if (builtIn && op != EOpNull) {
|
||||
|
@ -4464,24 +4534,35 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
|
|||
decomposeSampleMethods(loc, result, arguments); // HLSL->AST sample method decompositions
|
||||
decomposeGeometryMethods(loc, result, arguments); // HLSL->AST geometry method decompositions
|
||||
|
||||
// Create the qualifier list, carried in the AST for the call.
|
||||
// Because some arguments expand to multiple arguments, the qualifier list will
|
||||
// be longer than the formal parameter list.
|
||||
if (result == fnNode && result->getAsAggregate()) {
|
||||
TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList();
|
||||
for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
|
||||
TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage;
|
||||
if (hasStructBuffCounter(*(*fnCandidate)[i].type)) {
|
||||
// add buffer and counter buffer argument qualifier
|
||||
qualifierList.push_back(qual);
|
||||
qualifierList.push_back(qual);
|
||||
} else if (shouldFlatten(*(*fnCandidate)[i].type)) {
|
||||
// add structure member expansion
|
||||
for (int memb = 0; memb < (int)(*fnCandidate)[i].type->getStruct()->size(); ++memb)
|
||||
qualifierList.push_back(qual);
|
||||
} else {
|
||||
// Normal 1:1 case
|
||||
qualifierList.push_back(qual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert 'out' arguments. If it was a constant folded built-in, it won't be an aggregate anymore.
|
||||
// Built-ins with a single argument aren't called with an aggregate, but they also don't have an output.
|
||||
// Also, build the qualifier list for user function calls, which are always called with an aggregate.
|
||||
// We don't do this is if there has been a decomposition, which will have added its own conversions
|
||||
// for output parameters.
|
||||
if (result == fnNode && result->getAsAggregate()) {
|
||||
TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList();
|
||||
for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
|
||||
TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage;
|
||||
qualifierList.push_back(qual);
|
||||
|
||||
// add counter buffer argument qualifier
|
||||
if (hasStructBuffCounter(*(*fnCandidate)[i].type))
|
||||
qualifierList.push_back(qual);
|
||||
}
|
||||
|
||||
if (result == fnNode && result->getAsAggregate())
|
||||
result = addOutputArgumentConversions(*fnCandidate, *result->getAsOperator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4512,20 +4593,22 @@ void HlslParseContext::pushFrontArguments(TIntermTyped* front, TIntermTyped*& ar
|
|||
void HlslParseContext::addInputArgumentConversions(const TFunction& function, TIntermTyped*& arguments)
|
||||
{
|
||||
TIntermAggregate* aggregate = arguments->getAsAggregate();
|
||||
const auto setArg = [&](int argNum, TIntermTyped* arg) {
|
||||
|
||||
// Replace a single argument with a single argument.
|
||||
const auto setArg = [&](int paramNum, TIntermTyped* arg) {
|
||||
if (function.getParamCount() == 1)
|
||||
arguments = arg;
|
||||
else {
|
||||
if (aggregate)
|
||||
aggregate->getSequence()[argNum] = arg;
|
||||
else
|
||||
if (aggregate == nullptr)
|
||||
arguments = arg;
|
||||
else
|
||||
aggregate->getSequence()[paramNum] = arg;
|
||||
}
|
||||
};
|
||||
|
||||
// Process each argument's conversion
|
||||
for (int i = 0; i < function.getParamCount(); ++i) {
|
||||
if (! function[i].type->getQualifier().isParamInput())
|
||||
for (int param = 0; param < function.getParamCount(); ++param) {
|
||||
if (! function[param].type->getQualifier().isParamInput())
|
||||
continue;
|
||||
|
||||
// At this early point there is a slight ambiguity between whether an aggregate 'arguments'
|
||||
|
@ -4533,42 +4616,121 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
|
|||
// means take 'arguments' itself as the one argument.
|
||||
TIntermTyped* arg = function.getParamCount() == 1
|
||||
? arguments->getAsTyped()
|
||||
: (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped());
|
||||
if (*function[i].type != arg->getType()) {
|
||||
: (aggregate ?
|
||||
aggregate->getSequence()[param]->getAsTyped() :
|
||||
arguments->getAsTyped());
|
||||
if (*function[param].type != arg->getType()) {
|
||||
// In-qualified arguments just need an extra node added above the argument to
|
||||
// convert to the correct type.
|
||||
TIntermTyped* convArg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg);
|
||||
TIntermTyped* convArg = intermediate.addConversion(EOpFunctionCall, *function[param].type, arg);
|
||||
if (convArg != nullptr)
|
||||
convArg = intermediate.addUniShapeConversion(EOpFunctionCall, *function[i].type, convArg);
|
||||
convArg = intermediate.addUniShapeConversion(EOpFunctionCall, *function[param].type, convArg);
|
||||
if (convArg != nullptr)
|
||||
setArg(i, convArg);
|
||||
setArg(param, convArg);
|
||||
else
|
||||
error(arg->getLoc(), "cannot convert input argument, argument", "", "%d", i);
|
||||
error(arg->getLoc(), "cannot convert input argument, argument", "", "%d", param);
|
||||
} else {
|
||||
if (wasFlattened(arg) || wasSplit(arg)) {
|
||||
// Will make a two-level subtree.
|
||||
// The deepest will copy member-by-member to build the structure to pass.
|
||||
// The level above that will be a two-operand EOpComma sequence that follows the copy by the
|
||||
// object itself.
|
||||
TVariable* internalAggregate = makeInternalVariable("aggShadow", *function[i].type);
|
||||
internalAggregate->getWritableType().getQualifier().makeTemporary();
|
||||
TIntermSymbol* internalSymbolNode = new TIntermSymbol(internalAggregate->getUniqueId(),
|
||||
internalAggregate->getName(),
|
||||
internalAggregate->getType());
|
||||
internalSymbolNode->setLoc(arg->getLoc());
|
||||
// This makes the deepest level, the member-wise copy
|
||||
TIntermAggregate* assignAgg = handleAssign(arg->getLoc(), EOpAssign, internalSymbolNode, arg)->getAsAggregate();
|
||||
// If both formal and calling arg are to be flattened, leave that to argument
|
||||
// expansion, not conversion.
|
||||
if (!shouldFlatten(*function[param].type)) {
|
||||
// Will make a two-level subtree.
|
||||
// The deepest will copy member-by-member to build the structure to pass.
|
||||
// The level above that will be a two-operand EOpComma sequence that follows the copy by the
|
||||
// object itself.
|
||||
TVariable* internalAggregate = makeInternalVariable("aggShadow", *function[param].type);
|
||||
internalAggregate->getWritableType().getQualifier().makeTemporary();
|
||||
TIntermSymbol* internalSymbolNode = new TIntermSymbol(internalAggregate->getUniqueId(),
|
||||
internalAggregate->getName(),
|
||||
internalAggregate->getType());
|
||||
internalSymbolNode->setLoc(arg->getLoc());
|
||||
// This makes the deepest level, the member-wise copy
|
||||
TIntermAggregate* assignAgg = handleAssign(arg->getLoc(), EOpAssign, internalSymbolNode, arg)->getAsAggregate();
|
||||
|
||||
// Now, pair that with the resulting aggregate.
|
||||
assignAgg = intermediate.growAggregate(assignAgg, internalSymbolNode, arg->getLoc());
|
||||
assignAgg->setOperator(EOpComma);
|
||||
assignAgg->setType(internalAggregate->getType());
|
||||
setArg(i, assignAgg);
|
||||
// Now, pair that with the resulting aggregate.
|
||||
assignAgg = intermediate.growAggregate(assignAgg, internalSymbolNode, arg->getLoc());
|
||||
assignAgg->setOperator(EOpComma);
|
||||
assignAgg->setType(internalAggregate->getType());
|
||||
setArg(param, assignAgg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add any needed implicit expansion of calling arguments from what the shader listed to what's
|
||||
// internally needed for the AST (given the constraints downstream).
|
||||
//
|
||||
void HlslParseContext::expandArguments(const TSourceLoc& loc, const TFunction& function, TIntermTyped*& arguments)
|
||||
{
|
||||
TIntermAggregate* aggregate = arguments->getAsAggregate();
|
||||
int functionParamNumberOffset = 0;
|
||||
|
||||
// Replace a single argument with a single argument.
|
||||
const auto setArg = [&](int paramNum, TIntermTyped* arg) {
|
||||
if (function.getParamCount() + functionParamNumberOffset == 1)
|
||||
arguments = arg;
|
||||
else {
|
||||
if (aggregate == nullptr)
|
||||
arguments = arg;
|
||||
else
|
||||
aggregate->getSequence()[paramNum] = arg;
|
||||
}
|
||||
};
|
||||
|
||||
// Replace a single argument with a list of arguments
|
||||
const auto setArgList = [&](int paramNum, const TVector<TIntermTyped*>& args) {
|
||||
if (args.size() == 1)
|
||||
setArg(paramNum, args.front());
|
||||
else {
|
||||
if (function.getParamCount() + functionParamNumberOffset == 1) {
|
||||
arguments = intermediate.makeAggregate(args.front());
|
||||
std::for_each(args.begin() + 1, args.end(),
|
||||
[&](TIntermTyped* arg) {
|
||||
arguments = intermediate.growAggregate(arguments, arg);
|
||||
});
|
||||
} else {
|
||||
auto it = aggregate->getSequence().erase(aggregate->getSequence().begin() + paramNum);
|
||||
aggregate->getSequence().insert(it, args.begin(), args.end());
|
||||
}
|
||||
}
|
||||
functionParamNumberOffset += (args.size() - 1);
|
||||
};
|
||||
|
||||
// Process each argument's conversion
|
||||
for (int param = 0; param < function.getParamCount(); ++param) {
|
||||
// At this early point there is a slight ambiguity between whether an aggregate 'arguments'
|
||||
// is the single argument itself or its children are the arguments. Only one argument
|
||||
// means take 'arguments' itself as the one argument.
|
||||
TIntermTyped* arg = function.getParamCount() == 1
|
||||
? arguments->getAsTyped()
|
||||
: (aggregate ?
|
||||
aggregate->getSequence()[param + functionParamNumberOffset]->getAsTyped() :
|
||||
arguments->getAsTyped());
|
||||
|
||||
if (wasFlattened(arg) && shouldFlatten(*function[param].type)) {
|
||||
// Need to pass the structure members instead of the structure.
|
||||
TVector<TIntermTyped*> memberArgs;
|
||||
for (int memb = 0; memb < (int)arg->getType().getStruct()->size(); ++memb) {
|
||||
initFlattening();
|
||||
memberArgs.push_back(flattenAccess(arg, memb));
|
||||
finalizeFlattening();
|
||||
}
|
||||
setArgList(param + functionParamNumberOffset, memberArgs);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: if we need both hidden counter args (below) and struct expansion (above)
|
||||
// the two algorithms need to be merged: Each assumes the list starts out 1:1 between
|
||||
// parameters and arguments.
|
||||
|
||||
// If any argument is a pass-by-reference struct buffer with an associated counter
|
||||
// buffer, we have to add another hidden parameter for that counter.
|
||||
if (aggregate)
|
||||
addStructBuffArguments(loc, aggregate);
|
||||
}
|
||||
|
||||
//
|
||||
// Add any needed implicit output conversions for function-call arguments. This
|
||||
// can require a new tree topology, complicated further by whether the function
|
||||
|
@ -4682,7 +4844,7 @@ void HlslParseContext::addStructBuffArguments(const TSourceLoc& loc, TIntermAggr
|
|||
|
||||
TIntermSequence argsWithCounterBuffers;
|
||||
|
||||
for (int param=0; param<int(aggregate->getSequence().size()); ++param) {
|
||||
for (int param = 0; param < int(aggregate->getSequence().size()); ++param) {
|
||||
argsWithCounterBuffers.push_back(aggregate->getSequence()[param]);
|
||||
|
||||
if (hasStructBuffCounter(aggregate->getSequence()[param]->getAsTyped()->getType())) {
|
||||
|
@ -6769,7 +6931,7 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, const TStr
|
|||
|
||||
inheritGlobalDefaults(type.getQualifier());
|
||||
|
||||
const bool flattenVar = shouldFlattenUniform(type);
|
||||
const bool flattenVar = shouldFlatten(type);
|
||||
|
||||
// correct IO in the type
|
||||
switch (type.getQualifier().storage) {
|
||||
|
|
|
@ -96,6 +96,7 @@ public:
|
|||
void decomposeGeometryMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
|
||||
void pushFrontArguments(TIntermTyped* front, TIntermTyped*& arguments);
|
||||
void addInputArgumentConversions(const TFunction&, TIntermTyped*&);
|
||||
void expandArguments(const TSourceLoc&, const TFunction&, TIntermTyped*&);
|
||||
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
|
||||
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
||||
TFunction* makeConstructorCall(const TSourceLoc&, const TType&);
|
||||
|
@ -186,7 +187,8 @@ public:
|
|||
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override;
|
||||
|
||||
// Apply L-value conversions. E.g, turning a write to a RWTexture into an ImageStore.
|
||||
TIntermTyped* handleLvalue(const TSourceLoc&, const char* op, TIntermTyped* node);
|
||||
TIntermTyped* handleLvalue(const TSourceLoc&, const char* op, TIntermTyped*& node);
|
||||
TIntermTyped* handleSamplerLvalue(const TSourceLoc&, const char* op, TIntermTyped*& node);
|
||||
bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
|
||||
|
||||
TLayoutFormat getLayoutFromTxType(const TSourceLoc&, const TType&);
|
||||
|
@ -236,13 +238,14 @@ protected:
|
|||
|
||||
// Array and struct flattening
|
||||
TIntermTyped* flattenAccess(TIntermTyped* base, int member);
|
||||
bool shouldFlattenUniform(const TType&) const;
|
||||
TIntermTyped* flattenAccess(int uniqueId, int member, const TType&);
|
||||
bool shouldFlatten(const TType&) const;
|
||||
bool wasFlattened(const TIntermTyped* node) const;
|
||||
bool wasFlattened(int id) const { return flattenMap.find(id) != flattenMap.end(); }
|
||||
int addFlattenedMember(const TSourceLoc& loc, const TVariable&, const TType&, TFlattenData&, const TString& name, bool track);
|
||||
bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); }
|
||||
|
||||
// Structure splitting (splits interstage builtin types into its own struct)
|
||||
// Structure splitting (splits interstage built-in types into its own struct)
|
||||
TIntermTyped* splitAccessStruct(const TSourceLoc& loc, TIntermTyped*& base, int& member);
|
||||
void splitAccessArray(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index);
|
||||
TType& split(TType& type, TString name, const TType* outerStructType = nullptr);
|
||||
|
|
|
@ -502,7 +502,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
|||
static const EShLanguageMask EShLangAll = EShLanguageMask(EShLangCount - 1);
|
||||
|
||||
// These are the actual stage masks defined in the documentation, in case they are
|
||||
// needed for furture validation. For now, they are commented out, and set below
|
||||
// needed for future validation. For now, they are commented out, and set below
|
||||
// to EShLangAll, to allow any intrinsic to be used in any shader, which is legal
|
||||
// if it is not called.
|
||||
//
|
||||
|
|
|
@ -12,8 +12,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
|
|||
#include <ShaderLang.h>
|
||||
#include <ResourceLimits.h>
|
||||
#include <SPIRV/SPVRemapper.h>
|
||||
//#include <spirv-tools/libspirv.hpp>
|
||||
//#include <spirv-tools/optimizer.hpp>
|
||||
#include <SPIRV/GlslangToSpv.h>
|
||||
BX_PRAGMA_DIAGNOSTIC_POP()
|
||||
|
||||
namespace bgfx
|
||||
|
@ -50,12 +49,6 @@ namespace stl = tinystl;
|
|||
|
||||
#include "../../src/shader_spirv.h"
|
||||
|
||||
namespace glslang
|
||||
{
|
||||
void GlslangToSpv(const glslang::TIntermediate& _intermediate, std::vector<uint32_t>& _spirv);
|
||||
|
||||
} // namespace glslang
|
||||
|
||||
namespace bgfx { namespace spirv
|
||||
{
|
||||
const TBuiltInResource resourceLimits =
|
||||
|
|
Loading…
Reference in New Issue