mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Updated glslang.
This commit is contained in:
141
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
141
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
@@ -43,6 +43,7 @@
|
|||||||
#include "spirv.hpp"
|
#include "spirv.hpp"
|
||||||
#include "GlslangToSpv.h"
|
#include "GlslangToSpv.h"
|
||||||
#include "SpvBuilder.h"
|
#include "SpvBuilder.h"
|
||||||
|
#include "SpvTools.h"
|
||||||
namespace spv {
|
namespace spv {
|
||||||
#include "GLSL.std.450.h"
|
#include "GLSL.std.450.h"
|
||||||
#include "GLSL.ext.KHR.h"
|
#include "GLSL.ext.KHR.h"
|
||||||
@@ -66,6 +67,7 @@ namespace spv {
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -164,6 +166,7 @@ protected:
|
|||||||
spv::Id convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly = false);
|
spv::Id convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly = false);
|
||||||
spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&,
|
spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&,
|
||||||
bool lastBufferBlockMember, bool forwardReferenceOnly = false);
|
bool lastBufferBlockMember, bool forwardReferenceOnly = false);
|
||||||
|
void applySpirvDecorate(const glslang::TType& type, spv::Id id, std::optional<int> member);
|
||||||
bool filterMember(const glslang::TType& member);
|
bool filterMember(const glslang::TType& member);
|
||||||
spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
|
spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
|
||||||
glslang::TLayoutPacking, const glslang::TQualifier&);
|
glslang::TLayoutPacking, const glslang::TQualifier&);
|
||||||
@@ -4705,6 +4708,64 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||||||
return spvType;
|
return spvType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply SPIR-V decorations to the SPIR-V object (provided by SPIR-V ID). If member index is provided, the
|
||||||
|
// decorations are applied to this member.
|
||||||
|
void TGlslangToSpvTraverser::applySpirvDecorate(const glslang::TType& type, spv::Id id, std::optional<int> member)
|
||||||
|
{
|
||||||
|
assert(type.getQualifier().hasSpirvDecorate());
|
||||||
|
|
||||||
|
const glslang::TSpirvDecorate& spirvDecorate = type.getQualifier().getSpirvDecorate();
|
||||||
|
|
||||||
|
// Add spirv_decorate
|
||||||
|
for (auto& decorate : spirvDecorate.decorates) {
|
||||||
|
if (!decorate.second.empty()) {
|
||||||
|
std::vector<unsigned> literals;
|
||||||
|
TranslateLiterals(decorate.second, literals);
|
||||||
|
if (member.has_value())
|
||||||
|
builder.addMemberDecoration(id, *member, static_cast<spv::Decoration>(decorate.first), literals);
|
||||||
|
else
|
||||||
|
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
|
||||||
|
} else {
|
||||||
|
if (member.has_value())
|
||||||
|
builder.addMemberDecoration(id, *member, static_cast<spv::Decoration>(decorate.first));
|
||||||
|
else
|
||||||
|
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add spirv_decorate_id
|
||||||
|
if (member.has_value()) {
|
||||||
|
// spirv_decorate_id not applied to members
|
||||||
|
assert(spirvDecorate.decorateIds.empty());
|
||||||
|
} else {
|
||||||
|
for (auto& decorateId : spirvDecorate.decorateIds) {
|
||||||
|
std::vector<spv::Id> operandIds;
|
||||||
|
assert(!decorateId.second.empty());
|
||||||
|
for (auto extraOperand : decorateId.second) {
|
||||||
|
if (extraOperand->getQualifier().isFrontEndConstant())
|
||||||
|
operandIds.push_back(createSpvConstant(*extraOperand));
|
||||||
|
else
|
||||||
|
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
|
||||||
|
}
|
||||||
|
builder.addDecorationId(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add spirv_decorate_string
|
||||||
|
for (auto& decorateString : spirvDecorate.decorateStrings) {
|
||||||
|
std::vector<const char*> strings;
|
||||||
|
assert(!decorateString.second.empty());
|
||||||
|
for (auto extraOperand : decorateString.second) {
|
||||||
|
const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
|
||||||
|
strings.push_back(string);
|
||||||
|
}
|
||||||
|
if (member.has_value())
|
||||||
|
builder.addMemberDecoration(id, *member, static_cast<spv::Decoration>(decorateString.first), strings);
|
||||||
|
else
|
||||||
|
builder.addDecoration(id, static_cast<spv::Decoration>(decorateString.first), strings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: this functionality should exist at a higher level, in creating the AST
|
// TODO: this functionality should exist at a higher level, in creating the AST
|
||||||
//
|
//
|
||||||
// Identify interface members that don't have their required extension turned on.
|
// Identify interface members that don't have their required extension turned on.
|
||||||
@@ -4943,37 +5004,9 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
|
|||||||
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Add SPIR-V decorations (GL_EXT_spirv_intrinsics)
|
||||||
// Add SPIR-V decorations for members (GL_EXT_spirv_intrinsics)
|
if (glslangMember.getQualifier().hasSpirvDecorate())
|
||||||
//
|
applySpirvDecorate(glslangMember, spvType, member);
|
||||||
if (glslangMember.getQualifier().hasSprivDecorate()) {
|
|
||||||
const glslang::TSpirvDecorate& spirvDecorate = glslangMember.getQualifier().getSpirvDecorate();
|
|
||||||
|
|
||||||
// Add spirv_decorate
|
|
||||||
for (auto& decorate : spirvDecorate.decorates) {
|
|
||||||
if (!decorate.second.empty()) {
|
|
||||||
std::vector<unsigned> literals;
|
|
||||||
TranslateLiterals(decorate.second, literals);
|
|
||||||
builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first), literals);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first));
|
|
||||||
}
|
|
||||||
|
|
||||||
// spirv_decorate_id not applied to members
|
|
||||||
assert(spirvDecorate.decorateIds.empty());
|
|
||||||
|
|
||||||
// Add spirv_decorate_string
|
|
||||||
for (auto& decorateString : spirvDecorate.decorateStrings) {
|
|
||||||
std::vector<const char*> strings;
|
|
||||||
assert(!decorateString.second.empty());
|
|
||||||
for (auto extraOperand : decorateString.second) {
|
|
||||||
const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
|
|
||||||
strings.push_back(string);
|
|
||||||
}
|
|
||||||
builder.addDecoration(spvType, static_cast<spv::Decoration>(decorateString.first), strings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decorate the structure
|
// Decorate the structure
|
||||||
@@ -5462,7 +5495,7 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
|
|||||||
spv::Function* function = builder.makeFunctionEntry(
|
spv::Function* function = builder.makeFunctionEntry(
|
||||||
TranslatePrecisionDecoration(glslFunction->getType()), convertGlslangToSpvType(glslFunction->getType()),
|
TranslatePrecisionDecoration(glslFunction->getType()), convertGlslangToSpvType(glslFunction->getType()),
|
||||||
glslFunction->getName().c_str(), convertGlslangLinkageToSpv(glslFunction->getLinkType()), paramTypes,
|
glslFunction->getName().c_str(), convertGlslangLinkageToSpv(glslFunction->getLinkType()), paramTypes,
|
||||||
paramNames, paramDecorations, &functionBlock);
|
paramDecorations, &functionBlock);
|
||||||
builder.setupDebugFunctionEntry(function, glslFunction->getName().c_str(), glslFunction->getLoc().line,
|
builder.setupDebugFunctionEntry(function, glslFunction->getName().c_str(), glslFunction->getLoc().line,
|
||||||
paramTypes, paramNames);
|
paramTypes, paramNames);
|
||||||
if (implicitThis)
|
if (implicitThis)
|
||||||
@@ -9598,47 +9631,9 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||||||
spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
|
spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Add SPIR-V decorations (GL_EXT_spirv_intrinsics)
|
||||||
// Add SPIR-V decorations for structure (GL_EXT_spirv_intrinsics)
|
if (symbol->getType().getQualifier().hasSpirvDecorate())
|
||||||
//
|
applySpirvDecorate(symbol->getType(), id, {});
|
||||||
if (symbol->getType().getQualifier().hasSprivDecorate()) {
|
|
||||||
const glslang::TSpirvDecorate& spirvDecorate = symbol->getType().getQualifier().getSpirvDecorate();
|
|
||||||
|
|
||||||
// Add spirv_decorate
|
|
||||||
for (auto& decorate : spirvDecorate.decorates) {
|
|
||||||
if (!decorate.second.empty()) {
|
|
||||||
std::vector<unsigned> literals;
|
|
||||||
TranslateLiterals(decorate.second, literals);
|
|
||||||
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spirv_decorate_id
|
|
||||||
for (auto& decorateId : spirvDecorate.decorateIds) {
|
|
||||||
std::vector<spv::Id> operandIds;
|
|
||||||
assert(!decorateId.second.empty());
|
|
||||||
for (auto extraOperand : decorateId.second) {
|
|
||||||
if (extraOperand->getQualifier().isFrontEndConstant())
|
|
||||||
operandIds.push_back(createSpvConstant(*extraOperand));
|
|
||||||
else
|
|
||||||
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
|
|
||||||
}
|
|
||||||
builder.addDecorationId(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spirv_decorate_string
|
|
||||||
for (auto& decorateString : spirvDecorate.decorateStrings) {
|
|
||||||
std::vector<const char*> strings;
|
|
||||||
assert(!decorateString.second.empty());
|
|
||||||
for (auto extraOperand : decorateString.second) {
|
|
||||||
const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
|
|
||||||
strings.push_back(string);
|
|
||||||
}
|
|
||||||
builder.addDecoration(id, static_cast<spv::Decoration>(decorateString.first), strings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|||||||
20
3rdparty/glslang/SPIRV/GlslangToSpv.h
vendored
20
3rdparty/glslang/SPIRV/GlslangToSpv.h
vendored
@@ -35,19 +35,25 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
|
||||||
#pragma warning(disable : 4464) // relative include path contains '..'
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "SpvTools.h"
|
|
||||||
#include "glslang/Include/intermediate.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
class TIntermediate;
|
||||||
|
|
||||||
|
struct SpvOptions {
|
||||||
|
bool generateDebugInfo {false};
|
||||||
|
bool stripDebugInfo {false};
|
||||||
|
bool disableOptimizer {true};
|
||||||
|
bool optimizeSize {false};
|
||||||
|
bool disassemble {false};
|
||||||
|
bool validate {false};
|
||||||
|
bool emitNonSemanticShaderDebugInfo {false};
|
||||||
|
bool emitNonSemanticShaderDebugSource{ false };
|
||||||
|
bool compileOnly{false};
|
||||||
|
};
|
||||||
|
|
||||||
void GetSpirvVersion(std::string&);
|
void GetSpirvVersion(std::string&);
|
||||||
int GetSpirvGeneratorVersion();
|
int GetSpirvGeneratorVersion();
|
||||||
|
|||||||
2
3rdparty/glslang/SPIRV/SPVRemapper.h
vendored
2
3rdparty/glslang/SPIRV/SPVRemapper.h
vendored
@@ -77,9 +77,9 @@ public:
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include "spirv.hpp"
|
#include "spirv.hpp"
|
||||||
#include "spvIR.h"
|
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
|
const Id NoResult = 0;
|
||||||
|
|
||||||
// class to hold SPIR-V binary data for remapping, DCE, and debug stripping
|
// class to hold SPIR-V binary data for remapping, DCE, and debug stripping
|
||||||
class spirvbin_t : public spirvbin_base_t
|
class spirvbin_t : public spirvbin_base_t
|
||||||
|
|||||||
58
3rdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
58
3rdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
@@ -1182,13 +1182,26 @@ Id Builder::makeDebugExpression()
|
|||||||
return debugExpression;
|
return debugExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Builder::makeDebugDeclare(Id const debugLocalVariable, Id const localVariable)
|
Id Builder::makeDebugDeclare(Id const debugLocalVariable, Id const pointer)
|
||||||
{
|
{
|
||||||
Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
|
Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
|
||||||
inst->addIdOperand(nonSemanticShaderDebugInfo);
|
inst->addIdOperand(nonSemanticShaderDebugInfo);
|
||||||
inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugDeclare);
|
inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugDeclare);
|
||||||
inst->addIdOperand(debugLocalVariable); // debug local variable id
|
inst->addIdOperand(debugLocalVariable); // debug local variable id
|
||||||
inst->addIdOperand(localVariable); // local variable id
|
inst->addIdOperand(pointer); // pointer to local variable id
|
||||||
|
inst->addIdOperand(makeDebugExpression()); // expression id
|
||||||
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
|
||||||
|
|
||||||
|
return inst->getResultId();
|
||||||
|
}
|
||||||
|
|
||||||
|
Id Builder::makeDebugValue(Id const debugLocalVariable, Id const value)
|
||||||
|
{
|
||||||
|
Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
|
||||||
|
inst->addIdOperand(nonSemanticShaderDebugInfo);
|
||||||
|
inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugValue);
|
||||||
|
inst->addIdOperand(debugLocalVariable); // debug local variable id
|
||||||
|
inst->addIdOperand(value); // value of local variable id
|
||||||
inst->addIdOperand(makeDebugExpression()); // expression id
|
inst->addIdOperand(makeDebugExpression()); // expression id
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
|
||||||
|
|
||||||
@@ -2061,11 +2074,6 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
|
|||||||
{
|
{
|
||||||
assert(! entryPointFunction);
|
assert(! entryPointFunction);
|
||||||
|
|
||||||
Block* entry;
|
|
||||||
std::vector<Id> paramsTypes;
|
|
||||||
std::vector<char const*> paramNames;
|
|
||||||
std::vector<std::vector<Decoration>> decorations;
|
|
||||||
|
|
||||||
auto const returnType = makeVoidType();
|
auto const returnType = makeVoidType();
|
||||||
|
|
||||||
restoreNonSemanticShaderDebugInfo = emitNonSemanticShaderDebugInfo;
|
restoreNonSemanticShaderDebugInfo = emitNonSemanticShaderDebugInfo;
|
||||||
@@ -2073,7 +2081,8 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
|
|||||||
emitNonSemanticShaderDebugInfo = false;
|
emitNonSemanticShaderDebugInfo = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
entryPointFunction = makeFunctionEntry(NoPrecision, returnType, entryPoint, LinkageTypeMax, paramsTypes, paramNames, decorations, &entry);
|
Block* entry = nullptr;
|
||||||
|
entryPointFunction = makeFunctionEntry(NoPrecision, returnType, entryPoint, LinkageTypeMax, {}, {}, &entry);
|
||||||
|
|
||||||
emitNonSemanticShaderDebugInfo = restoreNonSemanticShaderDebugInfo;
|
emitNonSemanticShaderDebugInfo = restoreNonSemanticShaderDebugInfo;
|
||||||
|
|
||||||
@@ -2082,8 +2091,8 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
|
|||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, LinkageType linkType,
|
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, LinkageType linkType,
|
||||||
const std::vector<Id>& paramTypes, const std::vector<char const*>& paramNames,
|
const std::vector<Id>& paramTypes,
|
||||||
const std::vector<std::vector<Decoration>>& decorations, Block **entry)
|
const std::vector<std::vector<Decoration>>& decorations, Block** entry)
|
||||||
{
|
{
|
||||||
// Make the function and initial instructions in it
|
// Make the function and initial instructions in it
|
||||||
Id typeId = makeFunctionType(returnType, paramTypes);
|
Id typeId = makeFunctionType(returnType, paramTypes);
|
||||||
@@ -2148,20 +2157,25 @@ void Builder::setupDebugFunctionEntry(Function* function, const char* name, int
|
|||||||
Id firstParamId = function->getParamId(0);
|
Id firstParamId = function->getParamId(0);
|
||||||
|
|
||||||
for (size_t p = 0; p < paramTypes.size(); ++p) {
|
for (size_t p = 0; p < paramTypes.size(); ++p) {
|
||||||
auto getParamTypeId = [this](Id const& typeId) {
|
bool passByRef = false;
|
||||||
if (isPointerType(typeId) || isArrayType(typeId)) {
|
Id paramTypeId = paramTypes[p];
|
||||||
return getContainedTypeId(typeId);
|
|
||||||
} else {
|
// For pointer-typed parameters, they are actually passed by reference and we need unwrap the pointer to get the actual parameter type.
|
||||||
return typeId;
|
if (isPointerType(paramTypeId) || isArrayType(paramTypeId)) {
|
||||||
}
|
passByRef = true;
|
||||||
};
|
paramTypeId = getContainedTypeId(paramTypeId);
|
||||||
|
}
|
||||||
|
|
||||||
auto const& paramName = paramNames[p];
|
auto const& paramName = paramNames[p];
|
||||||
auto const debugLocalVariableId =
|
auto const debugLocalVariableId = createDebugLocalVariable(debugId[paramTypeId], paramName, p + 1);
|
||||||
createDebugLocalVariable(debugId[getParamTypeId(paramTypes[p])], paramName, p + 1);
|
auto const paramId = static_cast<Id>(firstParamId + p);
|
||||||
|
debugId[paramId] = debugLocalVariableId;
|
||||||
|
|
||||||
debugId[firstParamId + p] = debugLocalVariableId;
|
if (passByRef) {
|
||||||
|
makeDebugDeclare(debugLocalVariableId, paramId);
|
||||||
makeDebugDeclare(debugLocalVariableId, firstParamId + p);
|
} else {
|
||||||
|
makeDebugValue(debugLocalVariableId, paramId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
9
3rdparty/glslang/SPIRV/SpvBuilder.h
vendored
9
3rdparty/glslang/SPIRV/SpvBuilder.h
vendored
@@ -231,7 +231,7 @@ public:
|
|||||||
Id createDebugGlobalVariable(Id const type, char const*const name, Id const variable);
|
Id createDebugGlobalVariable(Id const type, char const*const name, Id const variable);
|
||||||
Id createDebugLocalVariable(Id type, char const*const name, size_t const argNumber = 0);
|
Id createDebugLocalVariable(Id type, char const*const name, size_t const argNumber = 0);
|
||||||
Id makeDebugExpression();
|
Id makeDebugExpression();
|
||||||
Id makeDebugDeclare(Id const debugLocalVariable, Id const localVariable);
|
Id makeDebugDeclare(Id const debugLocalVariable, Id const pointer);
|
||||||
Id makeDebugValue(Id const debugLocalVariable, Id const value);
|
Id makeDebugValue(Id const debugLocalVariable, Id const value);
|
||||||
Id makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTypes);
|
Id makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTypes);
|
||||||
Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId);
|
Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId);
|
||||||
@@ -420,10 +420,9 @@ public:
|
|||||||
// Make a shader-style function, and create its entry block if entry is non-zero.
|
// Make a shader-style function, and create its entry block if entry is non-zero.
|
||||||
// Return the function, pass back the entry.
|
// Return the function, pass back the entry.
|
||||||
// The returned pointer is only valid for the lifetime of this builder.
|
// The returned pointer is only valid for the lifetime of this builder.
|
||||||
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name,
|
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, LinkageType linkType,
|
||||||
LinkageType linkType, const std::vector<Id>& paramTypes,
|
const std::vector<Id>& paramTypes,
|
||||||
const std::vector<char const*>& paramNames,
|
const std::vector<std::vector<Decoration>>& precisions, Block** entry = nullptr);
|
||||||
const std::vector<std::vector<Decoration>>& precisions, Block **entry = nullptr);
|
|
||||||
|
|
||||||
// Create a return. An 'implicit' return is one not appearing in the source
|
// Create a return. An 'implicit' return is one not appearing in the source
|
||||||
// code. In the case of an implicit return, no post-return block is inserted.
|
// code. In the case of an implicit return, no post-return block is inserted.
|
||||||
|
|||||||
13
3rdparty/glslang/SPIRV/SpvTools.h
vendored
13
3rdparty/glslang/SPIRV/SpvTools.h
vendored
@@ -48,22 +48,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "glslang/MachineIndependent/localintermediate.h"
|
#include "glslang/MachineIndependent/localintermediate.h"
|
||||||
|
#include "GlslangToSpv.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
struct SpvOptions {
|
|
||||||
bool generateDebugInfo {false};
|
|
||||||
bool stripDebugInfo {false};
|
|
||||||
bool disableOptimizer {true};
|
|
||||||
bool optimizeSize {false};
|
|
||||||
bool disassemble {false};
|
|
||||||
bool validate {false};
|
|
||||||
bool emitNonSemanticShaderDebugInfo {false};
|
|
||||||
bool emitNonSemanticShaderDebugSource{ false };
|
|
||||||
bool compileOnly{false};
|
|
||||||
};
|
|
||||||
|
|
||||||
#if ENABLE_OPT
|
#if ENABLE_OPT
|
||||||
|
|
||||||
// Translate glslang's view of target versioning to what SPIRV-Tools uses.
|
// Translate glslang's view of target versioning to what SPIRV-Tools uses.
|
||||||
|
|||||||
1
3rdparty/glslang/StandAlone/StandAlone.cpp
vendored
1
3rdparty/glslang/StandAlone/StandAlone.cpp
vendored
@@ -46,6 +46,7 @@
|
|||||||
#include "DirStackFileIncluder.h"
|
#include "DirStackFileIncluder.h"
|
||||||
#include "./../glslang/Include/ShHandle.h"
|
#include "./../glslang/Include/ShHandle.h"
|
||||||
#include "./../glslang/Public/ShaderLang.h"
|
#include "./../glslang/Public/ShaderLang.h"
|
||||||
|
#include "../glslang/MachineIndependent/localintermediate.h"
|
||||||
#include "../SPIRV/GlslangToSpv.h"
|
#include "../SPIRV/GlslangToSpv.h"
|
||||||
#include "../SPIRV/GLSL.std.450.h"
|
#include "../SPIRV/GLSL.std.450.h"
|
||||||
#include "../SPIRV/doc.h"
|
#include "../SPIRV/doc.h"
|
||||||
|
|||||||
@@ -9551,6 +9551,8 @@ bool HlslParseContext::isInputBuiltIn(const TQualifier& qualifier) const
|
|||||||
return language == EShLangTessEvaluation;
|
return language == EShLangTessEvaluation;
|
||||||
case EbvTessCoord:
|
case EbvTessCoord:
|
||||||
return language == EShLangTessEvaluation;
|
return language == EShLangTessEvaluation;
|
||||||
|
case EbvViewIndex:
|
||||||
|
return language != EShLangCompute;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -512,6 +512,7 @@ void HlslScanContext::fillInKeywordMap()
|
|||||||
(*SemanticMap)["SV_PRIMITIVEID"] = EbvPrimitiveId;
|
(*SemanticMap)["SV_PRIMITIVEID"] = EbvPrimitiveId;
|
||||||
(*SemanticMap)["SV_OUTPUTCONTROLPOINTID"] = EbvInvocationId;
|
(*SemanticMap)["SV_OUTPUTCONTROLPOINTID"] = EbvInvocationId;
|
||||||
(*SemanticMap)["SV_ISFRONTFACE"] = EbvFace;
|
(*SemanticMap)["SV_ISFRONTFACE"] = EbvFace;
|
||||||
|
(*SemanticMap)["SV_VIEWID"] = EbvViewIndex;
|
||||||
(*SemanticMap)["SV_INSTANCEID"] = EbvInstanceIndex;
|
(*SemanticMap)["SV_INSTANCEID"] = EbvInstanceIndex;
|
||||||
(*SemanticMap)["SV_INSIDETESSFACTOR"] = EbvTessLevelInner;
|
(*SemanticMap)["SV_INSIDETESSFACTOR"] = EbvTessLevelInner;
|
||||||
(*SemanticMap)["SV_GSINSTANCEID"] = EbvInvocationId;
|
(*SemanticMap)["SV_GSINSTANCEID"] = EbvInvocationId;
|
||||||
|
|||||||
28
3rdparty/glslang/glslang/Include/Common.h
vendored
28
3rdparty/glslang/glslang/Include/Common.h
vendored
@@ -294,34 +294,6 @@ template <class T> int IntLog2(T n)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsInfinity(double x) {
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
switch (_fpclass(x)) {
|
|
||||||
case _FPCLASS_NINF:
|
|
||||||
case _FPCLASS_PINF:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return std::isinf(x);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsNan(double x) {
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
switch (_fpclass(x)) {
|
|
||||||
case _FPCLASS_SNAN:
|
|
||||||
case _FPCLASS_QNAN:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return std::isnan(x);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // _COMMON_INCLUDED_
|
#endif // _COMMON_INCLUDED_
|
||||||
|
|||||||
4
3rdparty/glslang/glslang/Include/Types.h
vendored
4
3rdparty/glslang/glslang/Include/Types.h
vendored
@@ -1075,7 +1075,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GL_EXT_spirv_intrinsics
|
// GL_EXT_spirv_intrinsics
|
||||||
bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
|
bool hasSpirvDecorate() const { return spirvDecorate != nullptr; }
|
||||||
void setSpirvDecorate(int decoration, const TIntermAggregate* args = nullptr);
|
void setSpirvDecorate(int decoration, const TIntermAggregate* args = nullptr);
|
||||||
void setSpirvDecorateId(int decoration, const TIntermAggregate* args);
|
void setSpirvDecorateId(int decoration, const TIntermAggregate* args);
|
||||||
void setSpirvDecorateString(int decoration, const TIntermAggregate* args);
|
void setSpirvDecorateString(int decoration, const TIntermAggregate* args);
|
||||||
@@ -2096,7 +2096,7 @@ public:
|
|||||||
const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); };
|
const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); };
|
||||||
|
|
||||||
if (getQualifiers) {
|
if (getQualifiers) {
|
||||||
if (qualifier.hasSprivDecorate())
|
if (qualifier.hasSpirvDecorate())
|
||||||
appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
|
appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
|
||||||
|
|
||||||
if (qualifier.hasLayout()) {
|
if (qualifier.hasLayout()) {
|
||||||
|
|||||||
@@ -628,12 +628,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
|
|
||||||
case EOpIsNan:
|
case EOpIsNan:
|
||||||
{
|
{
|
||||||
newConstArray[i].setBConst(IsNan(unionArray[i].getDConst()));
|
newConstArray[i].setBConst(std::isnan(unionArray[i].getDConst()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EOpIsInf:
|
case EOpIsInf:
|
||||||
{
|
{
|
||||||
newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst()));
|
newConstArray[i].setBConst(std::isinf(unionArray[i].getDConst()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -144,10 +144,10 @@ EProfile EDesktopProfile = static_cast<EProfile>(ENoProfile | ECoreProfile | ECo
|
|||||||
{ EBadProfile } };
|
{ EBadProfile } };
|
||||||
const Versioning* Es300Desktop130 = &Es300Desktop130Version[0];
|
const Versioning* Es300Desktop130 = &Es300Desktop130Version[0];
|
||||||
|
|
||||||
const Versioning Es310Desktop420Version[] = { { EEsProfile, 0, 310, 0, nullptr },
|
const Versioning Es310Desktop400Version[] = { { EEsProfile, 0, 310, 0, nullptr },
|
||||||
{ EDesktopProfile, 0, 420, 0, nullptr },
|
{ EDesktopProfile, 0, 400, 0, nullptr },
|
||||||
{ EBadProfile } };
|
{ EBadProfile } };
|
||||||
const Versioning* Es310Desktop420 = &Es310Desktop420Version[0];
|
const Versioning* Es310Desktop400 = &Es310Desktop400Version[0];
|
||||||
|
|
||||||
const Versioning Es310Desktop450Version[] = { { EEsProfile, 0, 310, 0, nullptr },
|
const Versioning Es310Desktop450Version[] = { { EEsProfile, 0, 310, 0, nullptr },
|
||||||
{ EDesktopProfile, 0, 450, 0, nullptr },
|
{ EDesktopProfile, 0, 450, 0, nullptr },
|
||||||
@@ -246,14 +246,14 @@ const BuiltInFunction BaseFunctions[] = {
|
|||||||
{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 },
|
{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 },
|
||||||
{ EOpVectorEqual, "equal", 2, TypeU, ClassBNS, Es300Desktop130 },
|
{ EOpVectorEqual, "equal", 2, TypeU, ClassBNS, Es300Desktop130 },
|
||||||
{ EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, Es300Desktop130 },
|
{ EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, Es300Desktop130 },
|
||||||
{ EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
|
{ EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
|
||||||
{ EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
|
{ EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
|
||||||
{ EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
|
{ EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
|
||||||
{ EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
|
{ EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
|
||||||
{ EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
|
{ EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
|
||||||
{ EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
|
{ EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
|
||||||
{ EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
|
{ EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop400 },
|
||||||
{ EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop420 },
|
{ EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop400 },
|
||||||
{ EOpMix, "mix", 3, TypeB, ClassRegular, Es310Desktop450 },
|
{ EOpMix, "mix", 3, TypeB, ClassRegular, Es310Desktop450 },
|
||||||
{ EOpMix, "mix", 3, TypeIU, ClassLB, Es310Desktop450 },
|
{ EOpMix, "mix", 3, TypeIU, ClassLB, Es310Desktop450 },
|
||||||
|
|
||||||
|
|||||||
@@ -2590,6 +2590,18 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT
|
|||||||
{
|
{
|
||||||
assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);
|
assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);
|
||||||
|
|
||||||
|
if (isEsProfile() && (baseType == EbtFloat || baseType == EbtFloat16)) {
|
||||||
|
int exponent = 0;
|
||||||
|
frexp(d, &exponent);
|
||||||
|
int minExp = baseType == EbtFloat ? -126 : -14;
|
||||||
|
int maxExp = baseType == EbtFloat ? 127 : 15;
|
||||||
|
if (exponent > maxExp) { //overflow, d = inf
|
||||||
|
d = std::numeric_limits<double>::infinity();
|
||||||
|
} else if (exponent < minExp) { //underflow, d = 0.0;
|
||||||
|
d = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TConstUnionArray unionArray(1);
|
TConstUnionArray unionArray(1);
|
||||||
unionArray[0].setDConst(d);
|
unionArray[0].setDConst(d);
|
||||||
|
|
||||||
@@ -2647,28 +2659,42 @@ TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selecto
|
|||||||
// 'swizzleOkay' says whether or not it is okay to consider a swizzle
|
// 'swizzleOkay' says whether or not it is okay to consider a swizzle
|
||||||
// a valid part of the dereference chain.
|
// a valid part of the dereference chain.
|
||||||
//
|
//
|
||||||
// 'BufferReferenceOk' says if type is buffer_reference, the routine stop to find the most left node.
|
// 'bufferReferenceOk' says if type is buffer_reference, the routine will stop to find the most left node.
|
||||||
//
|
//
|
||||||
|
// 'proc' is an optional function to run on each node that is processed during the traversal. 'proc' must
|
||||||
|
// return true to continue the traversal, or false to end the traversal early.
|
||||||
//
|
//
|
||||||
|
|
||||||
const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay , bool bufferReferenceOk)
|
const TIntermTyped* TIntermediate::traverseLValueBase(const TIntermTyped* node, bool swizzleOkay,
|
||||||
|
bool bufferReferenceOk,
|
||||||
|
std::function<bool(const TIntermNode&)> proc)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
const TIntermBinary* binary = node->getAsBinaryNode();
|
const TIntermBinary* binary = node->getAsBinaryNode();
|
||||||
if (binary == nullptr)
|
if (binary == nullptr) {
|
||||||
|
if (proc) {
|
||||||
|
proc(*node);
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
|
}
|
||||||
TOperator op = binary->getOp();
|
TOperator op = binary->getOp();
|
||||||
if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && op != EOpMatrixSwizzle)
|
if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle &&
|
||||||
|
op != EOpMatrixSwizzle)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (! swizzleOkay) {
|
if (!swizzleOkay) {
|
||||||
if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle)
|
if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
|
if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
|
||||||
(binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
|
(binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
|
||||||
! binary->getLeft()->getType().isArray())
|
!binary->getLeft()->getType().isArray())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
node = node->getAsBinaryNode()->getLeft();
|
if (proc) {
|
||||||
|
if (!proc(*node)) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = binary->getLeft();
|
||||||
if (bufferReferenceOk && node->isReference())
|
if (bufferReferenceOk && node->isReference())
|
||||||
return node;
|
return node;
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
|||||||
//
|
//
|
||||||
// If we get here, we have an error and a message.
|
// If we get here, we have an error and a message.
|
||||||
//
|
//
|
||||||
const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true);
|
const TIntermTyped* leftMostTypeNode = TIntermediate::traverseLValueBase(node, true);
|
||||||
|
|
||||||
if (symNode)
|
if (symNode)
|
||||||
error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
|
error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
|
||||||
@@ -234,7 +234,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
|
|||||||
const TIntermSymbol* symNode = node->getAsSymbolNode();
|
const TIntermSymbol* symNode = node->getAsSymbolNode();
|
||||||
|
|
||||||
if (node->getQualifier().isWriteOnly()) {
|
if (node->getQualifier().isWriteOnly()) {
|
||||||
const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true);
|
const TIntermTyped* leftMostTypeNode = TIntermediate::traverseLValueBase(node, true);
|
||||||
|
|
||||||
if (symNode != nullptr)
|
if (symNode != nullptr)
|
||||||
error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
|
error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
|
||||||
|
|||||||
@@ -2571,7 +2571,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
|
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true);
|
const TIntermTyped* base = TIntermediate::traverseLValueBase(arg0, true, true);
|
||||||
const char* errMsg = "Only l-values corresponding to shader block storage or shared variables can be used with "
|
const char* errMsg = "Only l-values corresponding to shader block storage or shared variables can be used with "
|
||||||
"atomic memory functions.";
|
"atomic memory functions.";
|
||||||
if (base) {
|
if (base) {
|
||||||
@@ -2591,20 +2591,57 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
case EOpInterpolateAtCentroid:
|
case EOpInterpolateAtCentroid:
|
||||||
case EOpInterpolateAtSample:
|
case EOpInterpolateAtSample:
|
||||||
case EOpInterpolateAtOffset:
|
case EOpInterpolateAtOffset:
|
||||||
case EOpInterpolateAtVertex:
|
case EOpInterpolateAtVertex: {
|
||||||
// Make sure the first argument is an interpolant, or an array element of an interpolant
|
|
||||||
if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
|
if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
|
||||||
// It might still be an array element.
|
// Traverse down the left branch of arg0 to ensure this argument is a valid interpolant.
|
||||||
//
|
//
|
||||||
// We could check more, but the semantics of the first argument are already met; the
|
// For desktop GL >4.3 we effectively only need to ensure that arg0 represents an l-value from an
|
||||||
// only way to turn an array into a float/vec* is array dereference and swizzle.
|
// input declaration.
|
||||||
//
|
//
|
||||||
// ES and desktop 4.3 and earlier: swizzles may not be used
|
// For desktop GL <= 4.3 and ES, we must also ensure that swizzling is not used
|
||||||
// desktop 4.4 and later: swizzles may be used
|
//
|
||||||
bool swizzleOkay = (!isEsProfile()) && (version >= 440);
|
// For ES, we must also ensure that a field selection operator (i.e., '.') is not used on a named
|
||||||
const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay);
|
// struct.
|
||||||
if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn)
|
|
||||||
error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), "");
|
const bool esProfile = isEsProfile();
|
||||||
|
const bool swizzleOkay = !esProfile && (version >= 440);
|
||||||
|
|
||||||
|
std::string interpolantErrorMsg = "first argument must be an interpolant, or interpolant-array element";
|
||||||
|
bool isValid = true; // Assume that the interpolant is valid until we find a condition making it invalid
|
||||||
|
bool isIn = false; // Checks whether or not the interpolant is a shader input
|
||||||
|
bool structAccessOp = false; // Whether or not the previous node in the chain is a struct accessor
|
||||||
|
TIntermediate::traverseLValueBase(
|
||||||
|
arg0, swizzleOkay, false,
|
||||||
|
[&isValid, &isIn, &interpolantErrorMsg, esProfile, &structAccessOp](const TIntermNode& n) -> bool {
|
||||||
|
auto* type = n.getAsTyped();
|
||||||
|
if (type) {
|
||||||
|
if (type->getType().getQualifier().storage == EvqVaryingIn) {
|
||||||
|
isIn = true;
|
||||||
|
}
|
||||||
|
// If a field accessor was used, it can only be used to access a field with an input block, not a struct.
|
||||||
|
if (structAccessOp && (type->getType().getBasicType() != EbtBlock)) {
|
||||||
|
interpolantErrorMsg +=
|
||||||
|
". Using the field of a named struct as an interpolant argument is not "
|
||||||
|
"allowed (ES-only).";
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ES has different requirements for interpolants than GL
|
||||||
|
if (esProfile) {
|
||||||
|
// Swizzling will be taken care of by the 'swizzleOkay' argument passsed to traverseLValueBase,
|
||||||
|
// so we only ned to check whether or not a field accessor has been used with a named struct.
|
||||||
|
auto* binary = n.getAsBinaryNode();
|
||||||
|
if (binary && (binary->getOp() == EOpIndexDirectStruct)) {
|
||||||
|
structAccessOp = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't continue traversing if we know we have an invalid interpolant at this point.
|
||||||
|
return isValid;
|
||||||
|
});
|
||||||
|
if (!isIn || !isValid) {
|
||||||
|
error(loc, interpolantErrorMsg.c_str(), fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callNode.getOp() == EOpInterpolateAtVertex) {
|
if (callNode.getOp() == EOpInterpolateAtVertex) {
|
||||||
@@ -2620,7 +2657,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
case EOpEmitStreamVertex:
|
case EOpEmitStreamVertex:
|
||||||
case EOpEndStreamPrimitive:
|
case EOpEndStreamPrimitive:
|
||||||
@@ -4191,8 +4228,8 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
|
|||||||
dst.spirvStorageClass = src.spirvStorageClass;
|
dst.spirvStorageClass = src.spirvStorageClass;
|
||||||
|
|
||||||
// SPIR-V decorate qualifiers (GL_EXT_spirv_intrinsics)
|
// SPIR-V decorate qualifiers (GL_EXT_spirv_intrinsics)
|
||||||
if (src.hasSprivDecorate()) {
|
if (src.hasSpirvDecorate()) {
|
||||||
if (dst.hasSprivDecorate()) {
|
if (dst.hasSpirvDecorate()) {
|
||||||
const TSpirvDecorate& srcSpirvDecorate = src.getSpirvDecorate();
|
const TSpirvDecorate& srcSpirvDecorate = src.getSpirvDecorate();
|
||||||
TSpirvDecorate& dstSpirvDecorate = dst.getSpirvDecorate();
|
TSpirvDecorate& dstSpirvDecorate = dst.getSpirvDecorate();
|
||||||
for (auto& decorate : srcSpirvDecorate.decorates) {
|
for (auto& decorate : srcSpirvDecorate.decorates) {
|
||||||
@@ -6326,8 +6363,7 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
|
|||||||
switch (qualifier.storage) {
|
switch (qualifier.storage) {
|
||||||
case EvqVaryingIn:
|
case EvqVaryingIn:
|
||||||
case EvqVaryingOut:
|
case EvqVaryingOut:
|
||||||
if (!type.getQualifier().isTaskMemory() &&
|
if (!type.getQualifier().isTaskMemory() && !type.getQualifier().hasSpirvDecorate() &&
|
||||||
!type.getQualifier().hasSprivDecorate() &&
|
|
||||||
(type.getBasicType() != EbtBlock ||
|
(type.getBasicType() != EbtBlock ||
|
||||||
(!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
|
(!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
|
||||||
(*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)))
|
(*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)))
|
||||||
@@ -8540,7 +8576,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
memberQualifier.storage = EvqtaskPayloadSharedEXT;
|
memberQualifier.storage = EvqtaskPayloadSharedEXT;
|
||||||
if (memberQualifier.storage == EvqSpirvStorageClass)
|
if (memberQualifier.storage == EvqSpirvStorageClass)
|
||||||
error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), "");
|
error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), "");
|
||||||
if (memberQualifier.hasSprivDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty())
|
if (memberQualifier.hasSpirvDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty())
|
||||||
error(memberLoc, "member cannot have a spirv_decorate_id qualifier", memberType.getFieldName().c_str(), "");
|
error(memberLoc, "member cannot have a spirv_decorate_id qualifier", memberType.getFieldName().c_str(), "");
|
||||||
if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
|
if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
|
||||||
error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
|
error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
|
||||||
|
|||||||
@@ -1208,12 +1208,12 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node
|
|||||||
// - shows all digits, no premature rounding
|
// - shows all digits, no premature rounding
|
||||||
static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra)
|
static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra)
|
||||||
{
|
{
|
||||||
if (IsInfinity(value)) {
|
if (std::isinf(value)) {
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
out.debug << "-1.#INF";
|
out.debug << "-1.#INF";
|
||||||
else
|
else
|
||||||
out.debug << "+1.#INF";
|
out.debug << "+1.#INF";
|
||||||
} else if (IsNan(value))
|
} else if (std::isnan(value))
|
||||||
out.debug << "1.#IND";
|
out.debug << "1.#IND";
|
||||||
else {
|
else {
|
||||||
const int maxSize = 340;
|
const int maxSize = 340;
|
||||||
|
|||||||
@@ -866,7 +866,7 @@ int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
|
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
|
||||||
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
|
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSpirvDecorate()) {
|
||||||
return ent.newLocation = -1;
|
return ent.newLocation = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -953,7 +953,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
|
|||||||
return ent.newLocation = type.getQualifier().layoutLocation;
|
return ent.newLocation = type.getQualifier().layoutLocation;
|
||||||
}
|
}
|
||||||
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
|
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
|
||||||
if (type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
|
if (type.isBuiltIn() || type.getQualifier().hasSpirvDecorate()) {
|
||||||
return ent.newLocation = -1;
|
return ent.newLocation = -1;
|
||||||
}
|
}
|
||||||
// no locations on blocks of built-in variables
|
// no locations on blocks of built-in variables
|
||||||
|
|||||||
@@ -43,11 +43,12 @@
|
|||||||
#include "../Public/ShaderLang.h"
|
#include "../Public/ShaderLang.h"
|
||||||
#include "Versions.h"
|
#include "Versions.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <functional>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
|
||||||
#include <set>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
class TInfoSink;
|
class TInfoSink;
|
||||||
|
|
||||||
@@ -572,7 +573,8 @@ public:
|
|||||||
TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
|
TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
|
||||||
|
|
||||||
// Tree ops
|
// Tree ops
|
||||||
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false);
|
static const TIntermTyped* traverseLValueBase(const TIntermTyped*, bool swizzleOkay, bool bufferReferenceOk = false,
|
||||||
|
std::function<bool(const TIntermNode&)> proc = {});
|
||||||
|
|
||||||
// Linkage related
|
// Linkage related
|
||||||
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "shaderc.h"
|
#include "shaderc.h"
|
||||||
|
|
||||||
|
#include <iostream> // std::cout
|
||||||
|
|
||||||
BX_PRAGMA_DIAGNOSTIC_PUSH()
|
BX_PRAGMA_DIAGNOSTIC_PUSH()
|
||||||
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // error C4100: 'inclusionDepth' : unreferenced formal parameter
|
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // error C4100: 'inclusionDepth' : unreferenced formal parameter
|
||||||
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4265) // error C4265: 'spv::spirvbin_t': class has virtual functions, but destructor is not virtual
|
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4265) // error C4265: 'spv::spirvbin_t': class has virtual functions, but destructor is not virtual
|
||||||
@@ -15,8 +17,9 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
|
|||||||
#define ENABLE_OPT 1
|
#define ENABLE_OPT 1
|
||||||
#include <ShaderLang.h>
|
#include <ShaderLang.h>
|
||||||
#include <ResourceLimits.h>
|
#include <ResourceLimits.h>
|
||||||
#include <SPIRV/SPVRemapper.h>
|
|
||||||
#include <SPIRV/GlslangToSpv.h>
|
#include <SPIRV/GlslangToSpv.h>
|
||||||
|
#include <SPIRV/SPVRemapper.h>
|
||||||
|
#include <SPIRV/SpvTools.h>
|
||||||
#define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
|
#define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
|
||||||
#include <spirv_msl.hpp>
|
#include <spirv_msl.hpp>
|
||||||
#include <spirv_reflect.hpp>
|
#include <spirv_reflect.hpp>
|
||||||
@@ -489,8 +492,6 @@ namespace bgfx { namespace metal
|
|||||||
program->dumpReflection();
|
program->dumpReflection();
|
||||||
}
|
}
|
||||||
|
|
||||||
BX_UNUSED(spv::MemorySemanticsAllMemory);
|
|
||||||
|
|
||||||
glslang::TIntermediate* intermediate = program->getIntermediate(stage);
|
glslang::TIntermediate* intermediate = program->getIntermediate(stage);
|
||||||
std::vector<uint32_t> spirv;
|
std::vector<uint32_t> spirv;
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "shaderc.h"
|
#include "shaderc.h"
|
||||||
|
|
||||||
|
#include <iostream> // std::cout
|
||||||
|
|
||||||
BX_PRAGMA_DIAGNOSTIC_PUSH()
|
BX_PRAGMA_DIAGNOSTIC_PUSH()
|
||||||
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // error C4100: 'inclusionDepth' : unreferenced formal parameter
|
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // error C4100: 'inclusionDepth' : unreferenced formal parameter
|
||||||
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4265) // error C4265: 'spv::spirvbin_t': class has virtual functions, but destructor is not virtual
|
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4265) // error C4265: 'spv::spirvbin_t': class has virtual functions, but destructor is not virtual
|
||||||
@@ -17,6 +19,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
|
|||||||
#include <ResourceLimits.h>
|
#include <ResourceLimits.h>
|
||||||
#include <SPIRV/SPVRemapper.h>
|
#include <SPIRV/SPVRemapper.h>
|
||||||
#include <SPIRV/GlslangToSpv.h>
|
#include <SPIRV/GlslangToSpv.h>
|
||||||
|
#include <SPIRV/SpvTools.h>
|
||||||
#define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
|
#define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
|
||||||
#include <spirv_msl.hpp>
|
#include <spirv_msl.hpp>
|
||||||
#include <spirv_reflect.hpp>
|
#include <spirv_reflect.hpp>
|
||||||
@@ -698,8 +701,6 @@ namespace bgfx { namespace spirv
|
|||||||
program->dumpReflection();
|
program->dumpReflection();
|
||||||
}
|
}
|
||||||
|
|
||||||
BX_UNUSED(spv::MemorySemanticsAllMemory);
|
|
||||||
|
|
||||||
glslang::TIntermediate* intermediate = program->getIntermediate(stage);
|
glslang::TIntermediate* intermediate = program->getIntermediate(stage);
|
||||||
std::vector<uint32_t> spirv;
|
std::vector<uint32_t> spirv;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user