Updated glslang.

This commit is contained in:
Бранимир Караџић
2020-06-18 21:45:42 -07:00
parent 6cfacd9b5b
commit 685eeed252
26 changed files with 309 additions and 255 deletions

View File

@@ -0,0 +1,110 @@
/**
This code is based on the glslang_c_interface implementation by Viktor Latypov
**/
/**
BSD 2-Clause License
Copyright (c) 2019, Viktor Latypov
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. 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.
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 HOLDER 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.
**/
#include "glslang/Include/glslang_c_interface.h"
#include "SPIRV/GlslangToSpv.h"
#include "SPIRV/Logger.h"
#include "SPIRV/SpvTools.h"
typedef struct glslang_program_s {
glslang::TProgram* program;
std::vector<unsigned int> spirv;
std::string loggerMessages;
} glslang_program_t;
static EShLanguage c_shader_stage(glslang_stage_t stage)
{
switch (stage) {
case GLSLANG_STAGE_VERTEX:
return EShLangVertex;
case GLSLANG_STAGE_TESSCONTROL:
return EShLangTessControl;
case GLSLANG_STAGE_TESSEVALUATION:
return EShLangTessEvaluation;
case GLSLANG_STAGE_GEOMETRY:
return EShLangGeometry;
case GLSLANG_STAGE_FRAGMENT:
return EShLangFragment;
case GLSLANG_STAGE_COMPUTE:
return EShLangCompute;
case GLSLANG_STAGE_RAYGEN_NV:
return EShLangRayGen;
case GLSLANG_STAGE_INTERSECT_NV:
return EShLangIntersect;
case GLSLANG_STAGE_ANYHIT_NV:
return EShLangAnyHit;
case GLSLANG_STAGE_CLOSESTHIT_NV:
return EShLangClosestHit;
case GLSLANG_STAGE_MISS_NV:
return EShLangMiss;
case GLSLANG_STAGE_CALLABLE_NV:
return EShLangCallable;
case GLSLANG_STAGE_TASK_NV:
return EShLangTaskNV;
case GLSLANG_STAGE_MESH_NV:
return EShLangMeshNV;
default:
break;
}
return EShLangCount;
}
void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage)
{
spv::SpvBuildLogger logger;
glslang::SpvOptions spvOptions;
spvOptions.validate = true;
const glslang::TIntermediate* intermediate = program->program->getIntermediate(c_shader_stage(stage));
glslang::GlslangToSpv(*intermediate, program->spirv, &logger, &spvOptions);
program->loggerMessages = logger.getAllMessages();
}
size_t glslang_program_SPIRV_get_size(glslang_program_t* program) { return program->spirv.size(); }
void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int* out)
{
memcpy(out, program->spirv.data(), program->spirv.size() * sizeof(unsigned int));
}
unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program)
{
return program->spirv.data();
}
const char* glslang_program_SPIRV_get_messages(glslang_program_t* program)
{
return program->loggerMessages.empty() ? nullptr : program->loggerMessages.c_str();
}

View File

@@ -6,7 +6,8 @@ set(SOURCES
SpvPostProcess.cpp
doc.cpp
SpvTools.cpp
disassemble.cpp)
disassemble.cpp
CInterface/spirv_c_interface.cpp)
set(SPVREMAP_SOURCES
SPVRemapper.cpp

View File

@@ -32,9 +32,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "glslang/Include/glslang_c_interface.h"
#include "SPIRV/GlslangToSpv.h"
#include "SPIRV/Logger.h"
#include "SPIRV/SpvTools.h"
#include "StandAlone/DirStackFileIncluder.h"
#include "StandAlone/ResourceLimits.h"
#include "glslang/Include/ShHandle.h"
@@ -401,36 +398,6 @@ glslang_program_t* glslang_program_create()
return p;
}
void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage)
{
spv::SpvBuildLogger logger;
glslang::SpvOptions spvOptions;
spvOptions.validate = true;
const glslang::TIntermediate* intermediate = program->program->getIntermediate(c_shader_stage(stage));
glslang::GlslangToSpv(*intermediate, program->spirv, &logger, &spvOptions);
program->loggerMessages = logger.getAllMessages();
}
size_t glslang_program_SPIRV_get_size(glslang_program_t* program) { return program->spirv.size(); }
void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int* out)
{
memcpy(out, program->spirv.data(), program->spirv.size() * sizeof(unsigned int));
}
unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program)
{
return program->spirv.data();
}
const char* glslang_program_SPIRV_get_messages(glslang_program_t* program)
{
return program->loggerMessages.empty() ? nullptr : program->loggerMessages.c_str();
}
void glslang_program_delete(glslang_program_t* program)
{
if (!program)

View File

@@ -82,11 +82,32 @@ set(HEADERS
glslang_pch(SOURCES MachineIndependent/pch.cpp)
if(ENABLE_HLSL)
list(APPEND SOURCES
HLSL/hlslAttributes.cpp
HLSL/hlslParseHelper.cpp
HLSL/hlslScanContext.cpp
HLSL/hlslOpMap.cpp
HLSL/hlslTokenStream.cpp
HLSL/hlslGrammar.cpp
HLSL/hlslParseables.cpp)
list(APPEND HEADERS
HLSL/hlslAttributes.h
HLSL/hlslParseHelper.h
HLSL/hlslTokens.h
HLSL/hlslScanContext.h
HLSL/hlslOpMap.h
HLSL/hlslTokenStream.h
HLSL/hlslGrammar.h
HLSL/hlslParseables.h)
endif(ENABLE_HLSL)
add_library(glslang ${LIB_TYPE} ${BISON_GLSLParser_OUTPUT_SOURCE} ${SOURCES} ${HEADERS})
set_property(TARGET glslang PROPERTY FOLDER glslang)
set_property(TARGET glslang PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries(glslang OGLCompiler OSDependent)
target_include_directories(glslang PUBLIC
target_include_directories(glslang PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
@@ -94,16 +115,14 @@ if(WIN32 AND BUILD_SHARED_LIBS)
set_target_properties(glslang PROPERTIES PREFIX "")
endif()
if(ENABLE_HLSL)
target_link_libraries(glslang HLSL)
endif()
if(WIN32)
source_group("Public" REGULAR_EXPRESSION "Public/*")
source_group("MachineIndependent" REGULAR_EXPRESSION "MachineIndependent/[^/]*")
source_group("Include" REGULAR_EXPRESSION "Include/[^/]*")
source_group("GenericCodeGen" REGULAR_EXPRESSION "GenericCodeGen/*")
source_group("MachineIndependent\\Preprocessor" REGULAR_EXPRESSION "MachineIndependent/preprocessor/*")
source_group("HLSL" REGULAR_EXPRESSION "HLSL/*")
source_group("CInterface" REGULAR_EXPRESSION "CInterface/*")
endif(WIN32)
if(ENABLE_GLSLANG_INSTALL)

View File

@@ -39,8 +39,8 @@
#include <unordered_map>
#include <functional>
#include "../glslang/MachineIndependent/attribute.h"
#include "../glslang/MachineIndependent/SymbolTable.h"
#include "../MachineIndependent/attribute.h"
#include "../MachineIndependent/SymbolTable.h"
#include "hlslScanContext.h"
namespace glslang {

View File

@@ -39,11 +39,11 @@
#include "hlslGrammar.h"
#include "hlslAttributes.h"
#include "../glslang/Include/Common.h"
#include "../glslang/MachineIndependent/Scan.h"
#include "../glslang/MachineIndependent/preprocessor/PpContext.h"
#include "../Include/Common.h"
#include "../MachineIndependent/Scan.h"
#include "../MachineIndependent/preprocessor/PpContext.h"
#include "../glslang/OSDependent/osinclude.h"
#include "../OSDependent/osinclude.h"
#include <algorithm>
#include <functional>
@@ -814,7 +814,7 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc,
base->getAsSymbolNode()->getName().c_str(), "");
else
error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");
} else if (base->getType().getQualifier().isFrontEndConstant() &&
} else if (base->getType().getQualifier().isFrontEndConstant() &&
index->getQualifier().isFrontEndConstant()) {
// both base and index are front-end constants
checkIndex(loc, base->getType(), indexValue);
@@ -1848,7 +1848,7 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
error(loc, "invalid partitioning", "", "");
} else {
TVertexSpacing partitioning = EvsNone;
if (partitionStr == "integer") {
partitioning = EvsEqual;
} else if (partitionStr == "fractional_even") {
@@ -2484,7 +2484,7 @@ TIntermTyped* HlslParseContext::assignPosition(const TSourceLoc& loc, TOperator
TIntermTyped* rhsElement = intermediate.addIndex(EOpIndexDirect, tempSymR, index, loc);
const TType derefType(right->getType(), 0);
lhsElement->setType(derefType);
rhsElement->setType(derefType);
@@ -2504,7 +2504,7 @@ TIntermTyped* HlslParseContext::assignPosition(const TSourceLoc& loc, TOperator
return assignList;
}
// Clip and cull distance require special handling due to a semantic mismatch. In HLSL,
// these can be float scalar, float vector, or arrays of float scalar or float vector.
// In SPIR-V, they are arrays of scalar floats in all cases. We must copy individual components
@@ -2573,7 +2573,7 @@ TIntermAggregate* HlslParseContext::assignClipCullDistance(const TSourceLoc& loc
vecItems += (*semanticNSize)[x];
arrayLoc += (*semanticNSize)[x];
}
// It can have up to 2 array dimensions (in the case of geometry shader inputs)
const TArraySizes* const internalArraySizes = internalNode->getType().getArraySizes();
@@ -2594,7 +2594,7 @@ TIntermAggregate* HlslParseContext::assignClipCullDistance(const TSourceLoc& loc
// into a float array, or vice versa. Here, we make the array the right size and type,
// which depends on the incoming data, which has several potential dimensions:
// * Semantic ID
// * vector size
// * vector size
// * array size
// Of those, semantic ID and array size cannot appear simultaneously.
//
@@ -2655,7 +2655,7 @@ TIntermAggregate* HlslParseContext::assignClipCullDistance(const TSourceLoc& loc
// Holds individual component assignments as we make them.
TIntermTyped* clipCullAssign = nullptr;
// If the types are homomorphic, use a simple assign. No need to mess about with
// If the types are homomorphic, use a simple assign. No need to mess about with
// individual components.
if (clipCullSym->getType().isArray() == internalNode->getType().isArray() &&
clipCullInnerArraySize == internalInnerArraySize &&
@@ -2766,7 +2766,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
if (binaryNode == nullptr)
return false;
return (binaryNode->getOp() == EOpIndexDirect || binaryNode->getOp() == EOpIndexIndirect) &&
return (binaryNode->getOp() == EOpIndexDirect || binaryNode->getOp() == EOpIndexIndirect) &&
wasSplit(binaryNode->getLeft());
};
@@ -2798,7 +2798,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
const bool isFlattenLeft = wasFlattened(leftSymbol);
const bool isFlattenRight = wasFlattened(rightSymbol);
// OK to do a single assign if neither side is split or flattened. Otherwise,
// OK to do a single assign if neither side is split or flattened. Otherwise,
// fall through to a member-wise copy.
if (!isFlattenLeft && !isFlattenRight && !isSplitLeft && !isSplitRight) {
// Clip and cull distance requires more processing. See comment above assignClipCullDistance.
@@ -3430,9 +3430,9 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
// Byte address buffers index in bytes (only multiples of 4 permitted... not so much a byte address
// buffer then, but that's what it calls itself.
const bool isByteAddressBuffer = (builtInType == EbvByteAddressBuffer ||
const bool isByteAddressBuffer = (builtInType == EbvByteAddressBuffer ||
builtInType == EbvRWByteAddressBuffer);
if (isByteAddressBuffer)
argIndex = intermediate.addBinaryNode(EOpRightShift, argIndex,
@@ -3447,7 +3447,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
const TType derefType(argArray->getType(), 0);
node->setType(derefType);
}
break;
case EOpMethodLoad2:
@@ -3573,8 +3573,8 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
const TType indexType(argValue->getType(), 0);
rValue->setType(indexType);
}
TIntermTyped* assign = intermediate.addAssign(EOpAssign, lValue, rValue, loc);
TIntermTyped* assign = intermediate.addAssign(EOpAssign, lValue, rValue, loc);
body = intermediate.growAggregate(body, assign);
}
@@ -3751,7 +3751,7 @@ TIntermConstantUnion* HlslParseContext::getSamplePosArray(int count)
}
TConstUnionArray* values = new TConstUnionArray(numSamples*2);
for (int pos=0; pos<count; ++pos) {
TConstUnion x, y;
x.setDConst(sampleLoc[pos].x);
@@ -3785,7 +3785,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
result->setType(TType(node->getType().getBasicType(), EvqTemporary, node->getVectorSize()));
TIntermTyped* convertedResult = nullptr;
TType retType;
getTextureReturnType(sampler, retType);
@@ -3811,7 +3811,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
for (unsigned m = 0; m < unsigned(retType.getStruct()->size()); ++m) {
const TType memberType(retType, m); // dereferenced type of the member we're about to assign.
// Check for bad struct members. This should have been caught upstream. Complain, because
// wwe don't know what to do with it. This algorithm could be generalized to handle
// other things, e.g, sub-structures, but HLSL doesn't allow them.
@@ -3819,7 +3819,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
error(loc, "expected: scalar or vector type in texture structure", "", "");
return nullptr;
}
// Index into the struct variable to find the member to assign.
TIntermTyped* structMember = intermediate.addIndex(EOpIndexDirectStruct,
intermediate.addSymbol(*structVar, loc),
@@ -3841,14 +3841,14 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
TIntermTyped* structVecComponent = intermediate.addIndex(EOpIndexDirect, structMember,
intermediate.addConstantUnion(component, loc), loc);
memberAssign = intermediate.addAssign(EOpAssign, structVecComponent, vec4Member, loc);
} else {
// Scalar member: we can assign to it directly.
memberAssign = intermediate.addAssign(EOpAssign, structMember, vec4Member, loc);
}
conversionAggregate->getSequence().push_back(memberAssign);
}
}
@@ -3887,7 +3887,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
if (arguments->getAsTyped()->getBasicType() != EbtSampler)
return;
} else {
if (argAggregate->getSequence().size() == 0 ||
if (argAggregate->getSequence().size() == 0 ||
argAggregate->getSequence()[0] == nullptr ||
argAggregate->getSequence()[0]->getAsTyped()->getBasicType() != EbtSampler)
return;
@@ -4584,13 +4584,13 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
int count = 0;
for (int val = 2; val <= 16; val *= 2)
idxtest[count++] =
intermediate.addBinaryNode(EOpEqual,
intermediate.addBinaryNode(EOpEqual,
intermediate.addSymbol(*outSampleCount, loc),
intermediate.addConstantUnion(val, loc),
loc, TType(EbtBool));
const TOperator idxOp = (argSampIdx->getQualifier().storage == EvqConst) ? EOpIndexDirect : EOpIndexIndirect;
// Create index ops into position arrays given sample index.
// TODO: should it be clamped?
TIntermTyped* index[4];
@@ -4605,13 +4605,13 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
// (sampleCount == 4) ? pos4[idx] :
// (sampleCount == 8) ? pos8[idx] :
// (sampleCount == 16) ? pos16[idx] : float2(0,0);
TIntermTyped* test =
intermediate.addSelection(idxtest[0], index[0],
intermediate.addSelection(idxtest[1], index[1],
TIntermTyped* test =
intermediate.addSelection(idxtest[0], index[0],
intermediate.addSelection(idxtest[1], index[1],
intermediate.addSelection(idxtest[2], index[2],
intermediate.addSelection(idxtest[3], index[3],
intermediate.addSelection(idxtest[3], index[3],
getSamplePosArray(1), loc), loc), loc), loc);
compoundStatement = intermediate.growAggregate(compoundStatement, test);
compoundStatement->setOperator(EOpSequence);
compoundStatement->setLoc(loc);
@@ -4624,7 +4624,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
case EOpSubpassLoad:
{
const TIntermTyped* argSubpass =
const TIntermTyped* argSubpass =
argAggregate ? argAggregate->getSequence()[0]->getAsTyped() :
arguments->getAsTyped();
@@ -4639,7 +4639,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
break;
}
default:
break; // most pass through unchanged
@@ -5159,7 +5159,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
for (int idx = 0; idx < vecSize; ++idx) {
TIntermTyped* idxConst = intermediate.addConstantUnion(idx, loc, true);
TIntermTyped* component = argValue->getType().isVector() ?
TIntermTyped* component = argValue->getType().isVector() ?
intermediate.addIndex(EOpIndexDirect, argValue, idxConst, loc) : argValue;
if (component != argValue)
@@ -5171,7 +5171,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
unpackOp->setLoc(loc);
TIntermTyped* lowOrder = intermediate.addIndex(EOpIndexDirect, unpackOp, zero, loc);
if (result != nullptr) {
result->getSequence().push_back(lowOrder);
node = result;
@@ -5179,7 +5179,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
node = lowOrder;
}
}
break;
}
@@ -5210,7 +5210,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
for (int idx = 0; idx < vecSize; ++idx) {
TIntermTyped* idxConst = intermediate.addConstantUnion(idx, loc, true);
TIntermTyped* component = argValue->getType().isVector() ?
TIntermTyped* component = argValue->getType().isVector() ?
intermediate.addIndex(EOpIndexDirect, argValue, idxConst, loc) : argValue;
if (component != argValue)
@@ -5221,7 +5221,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
vec2ComponentAndZero->getSequence().push_back(zero);
vec2ComponentAndZero->setType(TType(EbtFloat, EvqTemporary, 2));
vec2ComponentAndZero->setLoc(loc);
TIntermTyped* packOp = new TIntermUnary(EOpPackHalf2x16);
packOp->getAsUnaryNode()->setOperand(vec2ComponentAndZero);
packOp->setLoc(loc);
@@ -5294,7 +5294,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
TIntermTyped* notinf = handleUnaryMath(loc, "!", EOpLogicalNot, isinf);
notinf->setType(boolType);
TIntermTyped* andNode = handleBinaryMath(loc, "and", EOpLogicalAnd, notnan, notinf);
andNode->setType(boolType);
@@ -5678,7 +5678,7 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
// means take 'arguments' itself as the one argument.
TIntermTyped* arg = function.getParamCount() == 1
? arguments->getAsTyped()
: (aggregate ?
: (aggregate ?
aggregate->getSequence()[param]->getAsTyped() :
arguments->getAsTyped());
if (*function[param].type != arg->getType()) {
@@ -5749,7 +5749,7 @@ void HlslParseContext::expandArguments(const TSourceLoc& loc, const TFunction& f
else if (args.size() > 1) {
if (function.getParamCount() + functionParamNumberOffset == 1) {
arguments = intermediate.makeAggregate(args.front());
std::for_each(args.begin() + 1, args.end(),
std::for_each(args.begin() + 1, args.end(),
[&](TIntermTyped* arg) {
arguments = intermediate.growAggregate(arguments, arg);
});
@@ -5768,7 +5768,7 @@ void HlslParseContext::expandArguments(const TSourceLoc& loc, const TFunction& f
// means take 'arguments' itself as the one argument.
TIntermTyped* arg = function.getParamCount() == 1
? arguments->getAsTyped()
: (aggregate ?
: (aggregate ?
aggregate->getSequence()[param + functionParamNumberOffset]->getAsTyped() :
arguments->getAsTyped());
@@ -8568,7 +8568,7 @@ TIntermTyped* HlslParseContext::convertArray(TIntermTyped* node, const TType& ty
// bump up to the next component to consume
const auto getNextComponent = [&]() {
TIntermTyped* component;
component = handleBracketDereference(node->getLoc(), constructee,
component = handleBracketDereference(node->getLoc(), constructee,
intermediate.addConstantUnion(constructeeElement, node->getLoc()));
if (component->isVector())
component = handleBracketDereference(node->getLoc(), component,
@@ -9640,7 +9640,7 @@ bool HlslParseContext::setTextureReturnType(TSampler& sampler, const TType& retT
// Insert it in the vector that tracks struct return types.
sampler.structReturnIndex = unsigned(textureReturnStruct.size());
textureReturnStruct.push_back(members);
// Success!
return true;
}
@@ -9688,7 +9688,7 @@ const TFunction* HlslParseContext::findPatchConstantFunction(const TSourceLoc& l
TVector<const TFunction*> candidateList;
bool builtIn;
symbolTable.findFunctionNameList(mangledName, candidateList, builtIn);
// We have to have one and only one, or we don't know which to pick: the patchconstantfunc does not
// allow any disambiguation of overloads.
if (candidateList.empty()) {
@@ -9759,26 +9759,26 @@ void HlslParseContext::addPatchConstantInvocation()
return type.isSizedArray() && biType == EbvOutputPatch;
};
// We will perform these steps. Each is in a scoped block for separation: they could
// become separate functions to make addPatchConstantInvocation shorter.
//
//
// 1. Union the interfaces, and create built-ins for anything present in the PCF and
// declared as a built-in variable that isn't present in the entry point's signature.
//
// 2. Synthesizes a call to the patchconstfunction using built-in variables from either main,
// or the ones we created. Matching is based on built-in type. We may use synthesized
// variables from (1) above.
//
//
// 2B: Synthesize per control point invocations of wrapped entry point if the PCF requires them.
//
// 3. Create a return sequence: copy the return value (if any) from the PCF to a
// (non-sanitized) output variable. In case this may involve multiple copies, such as for
// an arrayed variable, a temporary copy of the PCF output is created to avoid multiple
// indirections into a complex R-value coming from the call to the PCF.
//
//
// 4. Create a barrier.
//
//
// 5/5B. Call the PCF inside an if test for (invocation id == 0).
TFunction* patchConstantFunctionPtr = const_cast<TFunction*>(findPatchConstantFunction(loc));
@@ -9885,7 +9885,7 @@ void HlslParseContext::addPatchConstantInvocation()
} else {
// find which built-in it is
const TBuiltInVariable biType = patchConstantFunction[p].getDeclaredBuiltIn();
if (biType == EbvInputPatch && inputPatch == nullptr) {
error(loc, "unimplemented: PCF input patch without entry point input patch parameter", "", "");
return;
@@ -9992,7 +9992,7 @@ void HlslParseContext::addPatchConstantInvocation()
element->setType(derefType);
element->setLoc(loc);
pcfCallSequence = intermediate.growAggregate(pcfCallSequence,
pcfCallSequence = intermediate.growAggregate(pcfCallSequence,
handleAssign(loc, EOpAssign, element, callReturn));
}
}
@@ -10041,7 +10041,7 @@ void HlslParseContext::addPatchConstantInvocation()
pcfCallSequence = intermediate.growAggregate(pcfCallSequence, pcfCall);
}
// ================ Step 4: Barrier ================
// ================ Step 4: Barrier ================
TIntermTyped* barrier = new TIntermAggregate(EOpBarrier);
barrier->setLoc(loc);
barrier->setType(TType(EbtVoid));
@@ -10113,7 +10113,7 @@ void HlslParseContext::finalizeAppendMethods()
// Patch append sequences, now that we know the stream output symbol.
for (auto append = gsAppends.begin(); append != gsAppends.end(); ++append) {
append->node->getSequence()[0] =
append->node->getSequence()[0] =
handleAssign(append->loc, EOpAssign,
intermediate.addSymbol(*gsStreamOutput, append->loc),
append->node->getSequence()[0]->getAsTyped());

View File

@@ -36,9 +36,9 @@
#ifndef HLSL_PARSE_INCLUDED_
#define HLSL_PARSE_INCLUDED_
#include "../glslang/MachineIndependent/parseVersions.h"
#include "../glslang/MachineIndependent/ParseHelper.h"
#include "../glslang/MachineIndependent/attribute.h"
#include "../MachineIndependent/parseVersions.h"
#include "../MachineIndependent/ParseHelper.h"
#include "../MachineIndependent/attribute.h"
#include <array>
@@ -320,7 +320,7 @@ protected:
// Finalization step: remove unused buffer blocks from linkage (we don't know until the
// shader is entirely compiled)
void removeUnusedStructBufferCounters();
static bool isClipOrCullDistance(TBuiltInVariable);
static bool isClipOrCullDistance(const TQualifier& qual) { return isClipOrCullDistance(qual.builtIn); }
static bool isClipOrCullDistance(const TType& type) { return isClipOrCullDistance(type.getQualifier()); }
@@ -407,7 +407,7 @@ protected:
// This tracks texture sample user structure return types. Only a limited number are supported, as
// may fit in TSampler::structReturnIndex.
TVector<TTypeList*> textureReturnStruct;
TMap<TString, bool> structBufferCounter; // true if counter buffer is in use
// The built-in interstage IO map considers e.g, EvqPosition on input and output separately, so that we
@@ -456,7 +456,7 @@ protected:
std::array<int, maxClipCullRegs> cullSemanticNSizeOut; // vector, indexed by cull semantic ID
// This tracks the first (mip level) argument to the .mips[][] operator. Since this can be nested as
// in tx.mips[tx.mips[0][1].x][2], we need a stack. We also track the TSourceLoc for error reporting
// in tx.mips[tx.mips[0][1].x][2], we need a stack. We also track the TSourceLoc for error reporting
// purposes.
struct tMipsOperatorData {
tMipsOperatorData(TSourceLoc l, TIntermTyped* m) : loc(l), mipLevel(m) { }

View File

@@ -56,18 +56,6 @@
namespace { // anonymous namespace functions
const bool UseHlslTypes = true;
const char* BaseTypeName(const char argOrder, const char* scalarName, const char* vecName, const char* matName)
{
switch (argOrder) {
case 'S': return scalarName;
case 'V': return vecName;
case 'M': return matName;
default: return "UNKNOWN_TYPE";
}
}
// arg order queries
bool IsSamplerType(const char argType) { return argType == 'S' || argType == 's'; }
bool IsArrayed(const char argOrder) { return argOrder == '@' || argOrder == '&' || argOrder == '#'; }
@@ -216,8 +204,7 @@ int FixedVecSize(const char* arg)
return 0; // none found.
}
// Create and return a type name. This is done in GLSL, not HLSL conventions, until such
// time as builtins are parsed using the HLSL parser.
// Create and return a type name, using HLSL type conventions.
//
// order: S = scalar, V = vector, M = matrix
// argType: F = float, D = double, I = int, U = uint, B = bool, S = sampler
@@ -252,63 +239,35 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons
char order = *argOrder;
if (UseHlslTypes) {
switch (type) {
case '-': s += "void"; break;
case 'F': s += "float"; break;
case 'D': s += "double"; break;
case 'I': s += "int"; break;
case 'U': s += "uint"; break;
case 'L': s += "int64_t"; break;
case 'M': s += "uint64_t"; break;
case 'B': s += "bool"; break;
case 'S': s += "sampler"; break;
case 's': s += "SamplerComparisonState"; break;
case 'T': s += ((isBuffer && isImage) ? "RWBuffer" :
isSubpass ? "SubpassInput" :
isBuffer ? "Buffer" :
isImage ? "RWTexture" : "Texture"); break;
case 'i': s += ((isBuffer && isImage) ? "RWBuffer" :
isSubpass ? "SubpassInput" :
isBuffer ? "Buffer" :
isImage ? "RWTexture" : "Texture"); break;
case 'u': s += ((isBuffer && isImage) ? "RWBuffer" :
isSubpass ? "SubpassInput" :
isBuffer ? "Buffer" :
isImage ? "RWTexture" : "Texture"); break;
default: s += "UNKNOWN_TYPE"; break;
}
if (isSubpass && isMS)
s += "MS";
} else {
switch (type) {
case '-': s += "void"; break;
case 'F': s += BaseTypeName(order, "float", "vec", "mat"); break;
case 'D': s += BaseTypeName(order, "double", "dvec", "dmat"); break;
case 'I': s += BaseTypeName(order, "int", "ivec", "imat"); break;
case 'U': s += BaseTypeName(order, "uint", "uvec", "umat"); break;
case 'B': s += BaseTypeName(order, "bool", "bvec", "bmat"); break;
case 'S': s += "sampler"; break;
case 's': s += "samplerShadow"; break;
case 'T': // fall through
case 'i': // ...
case 'u': // ...
if (type != 'T') // create itexture, utexture, etc
s += type;
s += ((isImage && isBuffer) ? "imageBuffer" :
isSubpass ? "subpassInput" :
isImage ? "image" :
isBuffer ? "samplerBuffer" :
"texture");
break;
default: s += "UNKNOWN_TYPE"; break;
}
switch (type) {
case '-': s += "void"; break;
case 'F': s += "float"; break;
case 'D': s += "double"; break;
case 'I': s += "int"; break;
case 'U': s += "uint"; break;
case 'L': s += "int64_t"; break;
case 'M': s += "uint64_t"; break;
case 'B': s += "bool"; break;
case 'S': s += "sampler"; break;
case 's': s += "SamplerComparisonState"; break;
case 'T': s += ((isBuffer && isImage) ? "RWBuffer" :
isSubpass ? "SubpassInput" :
isBuffer ? "Buffer" :
isImage ? "RWTexture" : "Texture"); break;
case 'i': s += ((isBuffer && isImage) ? "RWBuffer" :
isSubpass ? "SubpassInput" :
isBuffer ? "Buffer" :
isImage ? "RWTexture" : "Texture"); break;
case 'u': s += ((isBuffer && isImage) ? "RWBuffer" :
isSubpass ? "SubpassInput" :
isBuffer ? "Buffer" :
isImage ? "RWTexture" : "Texture"); break;
default: s += "UNKNOWN_TYPE"; break;
}
if (isSubpass && isMS)
s += "MS";
// handle fixed vector sizes, such as float3, and only ever 3.
const int fixedVecSize = FixedVecSize(argOrder);
if (fixedVecSize != 0)
@@ -324,7 +283,7 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons
case 1: s += "1D"; break;
case 2: s += (isMS ? "2DMS" : "2D"); break;
case 3: s += "3D"; break;
case 4: s += "Cube"; break;
case 4: s += (type == 'S'? "CUBE" : "Cube"); break;
default: s += "UNKNOWN_SAMPLER"; break;
}
}
@@ -357,26 +316,24 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons
if (isArrayed)
s += "Array";
// For HLSL, append return type for texture types
if (UseHlslTypes) {
switch (type) {
case 'i': s += "<int"; s += dim0Char; s += ">"; break;
case 'u': s += "<uint"; s += dim0Char; s += ">"; break;
case 'T': s += "<float"; s += dim0Char; s += ">"; break;
default: break;
}
switch (type) {
case 'i': s += "<int"; s += dim0Char; s += ">"; break;
case 'u': s += "<uint"; s += dim0Char; s += ">"; break;
case 'T': s += "<float"; s += dim0Char; s += ">"; break;
default: break;
}
return s;
}
// The GLSL parser can be used to parse a subset of HLSL prototypes. However, many valid HLSL prototypes
// are not valid GLSL prototypes. This rejects the invalid ones. Thus, there is a single switch below
// to enable creation of the entire HLSL space.
// This rejects prototypes not normally valid for GLSL and it's way of finding
// overloaded built-ins under implicit type conversion.
//
// It is possible that this is not needed, but that would require some tweaking
// of other rules to get the same results.
inline bool IsValid(const char* cname, char retOrder, char retType, char argOrder, char argType, int dim0, int dim1)
{
const bool isVec = (argOrder == 'V');
const bool isMat = (argOrder == 'M');
const std::string name(cname);
@@ -387,26 +344,6 @@ inline bool IsValid(const char* cname, char retOrder, char retType, char argOrde
if (!IsTextureType(argOrder) && (isVec && dim0 == 1)) // avoid vec1
return false;
if (UseHlslTypes) {
// NO further restrictions for HLSL
} else {
// GLSL parser restrictions
if ((isMat && (argType == 'I' || argType == 'U' || argType == 'B')) ||
(retOrder == 'M' && (retType == 'I' || retType == 'U' || retType == 'B')))
return false;
if (isMat && dim0 == 1 && dim1 == 1) // avoid mat1x1
return false;
if (isMat && dim1 == 1) // TODO: avoid mat Nx1 until we find the right GLSL profile
return false;
if (name == "GetRenderTargetSamplePosition" ||
name == "tex1D" ||
name == "tex1Dgrad")
return false;
}
return true;
}
@@ -461,12 +398,10 @@ void TBuiltInParseablesHlsl::createMatTimesMat()
{
TString& s = commonBuiltins;
const int first = (UseHlslTypes ? 1 : 2);
for (int xRows = first; xRows <=4; xRows++) {
for (int xCols = first; xCols <=4; xCols++) {
for (int xRows = 1; xRows <=4; xRows++) {
for (int xCols = 1; xCols <=4; xCols++) {
const int yRows = xCols;
for (int yCols = first; yCols <=4; yCols++) {
for (int yCols = 1; yCols <=4; yCols++) {
const int retRows = xRows;
const int retCols = yCols;
@@ -917,7 +852,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
{ "WaveActiveAllEqual", "S", "B", "SV", "DFUI", EShLangPSCS, false},
{ "WaveActiveAllEqualBool", "S", "B", "S", "B", EShLangPSCS, false},
{ "WaveActiveCountBits", "S", "U", "S", "B", EShLangPSCS, false},
{ "WaveActiveSum", nullptr, nullptr, "SV", "DFUI", EShLangPSCS, false},
{ "WaveActiveProduct", nullptr, nullptr, "SV", "DFUI", EShLangPSCS, false},
{ "WaveActiveBitAnd", nullptr, nullptr, "SV", "DFUI", EShLangPSCS, false},

View File

@@ -36,7 +36,7 @@
#ifndef _HLSLPARSEABLES_INCLUDED_
#define _HLSLPARSEABLES_INCLUDED_
#include "../glslang/MachineIndependent/Initialize.h"
#include "../MachineIndependent/Initialize.h"
namespace glslang {

View File

@@ -42,15 +42,15 @@
#include <unordered_map>
#include <unordered_set>
#include "../glslang/Include/Types.h"
#include "../glslang/MachineIndependent/SymbolTable.h"
#include "../glslang/MachineIndependent/ParseHelper.h"
#include "../Include/Types.h"
#include "../MachineIndependent/SymbolTable.h"
#include "../MachineIndependent/ParseHelper.h"
#include "hlslScanContext.h"
#include "hlslTokens.h"
// preprocessor includes
#include "../glslang/MachineIndependent/preprocessor/PpContext.h"
#include "../glslang/MachineIndependent/preprocessor/PpTokens.h"
#include "../MachineIndependent/preprocessor/PpContext.h"
#include "../MachineIndependent/preprocessor/PpTokens.h"
namespace {
@@ -317,7 +317,7 @@ void HlslScanContext::fillInKeywordMap()
(*KeywordMap)["sampler1D"] = EHTokSampler1d;
(*KeywordMap)["sampler2D"] = EHTokSampler2d;
(*KeywordMap)["sampler3D"] = EHTokSampler3d;
(*KeywordMap)["samplerCube"] = EHTokSamplerCube;
(*KeywordMap)["samplerCUBE"] = EHTokSamplerCube;
(*KeywordMap)["sampler_state"] = EHTokSamplerState;
(*KeywordMap)["SamplerState"] = EHTokSamplerState;
(*KeywordMap)["SamplerComparisonState"] = EHTokSamplerComparisonState;

View File

@@ -41,7 +41,7 @@
#ifndef HLSLSCANCONTEXT_H_
#define HLSLSCANCONTEXT_H_
#include "../glslang/MachineIndependent/ParseHelper.h"
#include "../MachineIndependent/ParseHelper.h"
#include "hlslTokens.h"
namespace glslang {

View File

@@ -34,21 +34,20 @@
// POSSIBILITY OF SUCH DAMAGE.
//
#include "hlslAttributes.h"
#include "hlslGrammar.h"
#include "hlslParseHelper.h"
#include "hlslScanContext.h"
#include "hlslGrammar.h"
#include "hlslAttributes.h"
#include "../glslang/MachineIndependent/Scan.h"
#include "../glslang/MachineIndependent/preprocessor/PpContext.h"
#include "../MachineIndependent/Scan.h"
#include "../MachineIndependent/preprocessor/PpContext.h"
#include "../glslang/OSDependent/osinclude.h"
#include "../OSDependent/osinclude.h"
#include <algorithm>
#include <functional>
#include <cctype>
#include <array>
#include <cctype>
#include <functional>
#include <set>
#endif /* _PCH_H */

View File

@@ -1,3 +1,3 @@
// This header is generated by the make-revision script.
#define GLSLANG_PATCH_LEVEL 3795
#define GLSLANG_PATCH_LEVEL 3802

View File

@@ -51,9 +51,9 @@
#include "ScanContext.h"
#ifdef ENABLE_HLSL
#include "../../hlsl/hlslParseHelper.h"
#include "../../hlsl/hlslParseables.h"
#include "../../hlsl/hlslScanContext.h"
#include "../HLSL/hlslParseHelper.h"
#include "../HLSL/hlslParseables.h"
#include "../HLSL/hlslScanContext.h"
#endif
#include "../Include/ShHandle.h"

View File

@@ -68,7 +68,7 @@
// This should always increase, as some paths to do not consume
// a more major number.
// It should increment by one when new functionality is added.
#define GLSLANG_MINOR_VERSION 14
#define GLSLANG_MINOR_VERSION 15
//
// Call before doing any other compiler/linker operations.

View File

@@ -1,25 +1,11 @@
set(SOURCES
hlslAttributes.cpp
hlslParseHelper.cpp
hlslScanContext.cpp
hlslOpMap.cpp
hlslTokenStream.cpp
hlslGrammar.cpp
hlslParseables.cpp)
set(HEADERS
hlslAttributes.h
hlslParseHelper.h
hlslTokens.h
hlslScanContext.h
hlslOpMap.h
hlslTokenStream.h
hlslGrammar.h
hlslParseables.h)
# The HLSL source is directly embedded into the glslang target when ENABLE_HLSL
# is set.
# This source now lives at: glslang/HLSL/
# The HLSL target is now just a stub that exists for backwards compatibility for
# projects that referenced this target.
glslang_pch(SOURCES pch.cpp)
add_library(HLSL ${LIB_TYPE} ${SOURCES} ${HEADERS})
add_library(HLSL ${LIB_TYPE} "stub.cpp")
set_property(TARGET HLSL PROPERTY FOLDER hlsl)
set_property(TARGET HLSL PROPERTY POSITION_INDEPENDENT_CODE ON)
@@ -27,10 +13,6 @@ if(WIN32 AND BUILD_SHARED_LIBS)
set_target_properties(HLSL PROPERTIES PREFIX "")
endif()
if(WIN32)
source_group("Source" FILES ${SOURCES} ${HEADERS})
endif(WIN32)
if(ENABLE_GLSLANG_INSTALL)
if(BUILD_SHARED_LIBS)
install(TARGETS HLSL EXPORT HLSLTargets

41
3rdparty/glslang/hlsl/stub.cpp vendored Normal file
View File

@@ -0,0 +1,41 @@
//
// Copyright (C) 2020 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 Google, Inc., 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.
//
// The HLSL source is directly embedded into the glslang target when ENABLE_HLSL
// is set.
// This source now lives at: glslang/HLSL/
// The HLSL target is now just a stub that exists for backwards compatibility
// for projects that referenced this target. As a target requires at least one
// source file to build, this file acts as that stub.