#include "compiler/translator/spirv/OutputSPIRV.h"
#include "angle_gl.h"
#include "common/debug.h"
#include "common/mathutil.h"
#include "common/spirv/spirv_instruction_builder_autogen.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/spirv/BuildSPIRV.h"
#include "compiler/translator/tree_util/FindPreciseNodes.h"
#include "compiler/translator/tree_util/IntermTraverse.h"
#include <cfloat>
namespace spv
{
#include <spirv/unified1/GLSL.std.450.h>
}
#include <spirv-tools/libspirv.hpp>
#if !defined(ANGLE_DEBUG_SPIRV_GENERATION)
#define ANGLE_DEBUG_SPIRV_GENERATION …
#endif
namespace sh
{
namespace
{
struct SpirvIdOrLiteral
{ … };
struct AccessChain
{ … };
struct NodeData
{ … };
struct FunctionIds
{ … };
struct BuiltInResultStruct
{ … };
struct BuiltInResultStructHash
{ … };
bool operator==(const BuiltInResultStruct &a, const BuiltInResultStruct &b)
{ … }
bool IsAccessChainRValue(const AccessChain &accessChain)
{ … }
class OutputSPIRVTraverser : public TIntermTraverser
{ … };
spv::StorageClass GetStorageClass(const ShCompileOptions &compileOptions,
const TType &type,
GLenum shaderType)
{ … }
OutputSPIRVTraverser::OutputSPIRVTraverser(TCompiler *compiler,
const ShCompileOptions &compileOptions,
const angle::HashMap<int, uint32_t> &uniqueToSpirvIdMap,
uint32_t firstUnusedSpirvId)
: … { … }
OutputSPIRVTraverser::~OutputSPIRVTraverser()
{ … }
spirv::IdRef OutputSPIRVTraverser::getSymbolIdAndStorageClass(const TSymbol *symbol,
const TType &type,
spv::StorageClass *storageClass)
{ … }
void OutputSPIRVTraverser::nodeDataInitLValue(NodeData *data,
spirv::IdRef baseId,
spirv::IdRef typeId,
spv::StorageClass storageClass,
const SpirvTypeSpec &typeSpec) const
{ … }
void OutputSPIRVTraverser::nodeDataInitRValue(NodeData *data,
spirv::IdRef baseId,
spirv::IdRef typeId) const
{ … }
void OutputSPIRVTraverser::accessChainOnPush(NodeData *data, const TType &parentType, size_t index)
{ … }
void OutputSPIRVTraverser::accessChainPush(NodeData *data,
spirv::IdRef index,
spirv::IdRef typeId) const
{ … }
void OutputSPIRVTraverser::accessChainPushLiteral(NodeData *data,
spirv::LiteralInteger index,
spirv::IdRef typeId) const
{ … }
void OutputSPIRVTraverser::accessChainPushSwizzle(NodeData *data,
const TVector<int> &swizzle,
spirv::IdRef typeId,
uint8_t componentCount) const
{ … }
void OutputSPIRVTraverser::accessChainPushDynamicComponent(NodeData *data,
spirv::IdRef index,
spirv::IdRef typeId)
{ … }
spirv::IdRef OutputSPIRVTraverser::accessChainCollapse(NodeData *data)
{ … }
spirv::IdRef OutputSPIRVTraverser::accessChainLoad(NodeData *data,
const TType &valueType,
spirv::IdRef *resultTypeIdOut)
{ … }
void OutputSPIRVTraverser::accessChainStore(NodeData *data,
spirv::IdRef value,
const TType &valueType)
{ … }
void OutputSPIRVTraverser::makeAccessChainIdList(NodeData *data, spirv::IdRefList *idsOut)
{ … }
void OutputSPIRVTraverser::makeAccessChainLiteralList(NodeData *data,
spirv::LiteralIntegerList *literalsOut)
{ … }
spirv::IdRef OutputSPIRVTraverser::getAccessChainTypeId(NodeData *data)
{ … }
void OutputSPIRVTraverser::declareConst(TIntermDeclaration *decl)
{ … }
void OutputSPIRVTraverser::declareSpecConst(TIntermDeclaration *decl)
{ … }
spirv::IdRef OutputSPIRVTraverser::createConstant(const TType &type,
TBasicType expectedBasicType,
const TConstantUnion *constUnion,
bool isConstantNullValue)
{ … }
spirv::IdRef OutputSPIRVTraverser::createComplexConstant(const TType &type,
spirv::IdRef typeId,
const spirv::IdRefList ¶meters)
{ … }
spirv::IdRef OutputSPIRVTraverser::createConstructor(TIntermAggregate *node, spirv::IdRef typeId)
{ … }
spirv::IdRef OutputSPIRVTraverser::createArrayOrStructConstructor(
TIntermAggregate *node,
spirv::IdRef typeId,
const spirv::IdRefList ¶meters)
{ … }
spirv::IdRef OutputSPIRVTraverser::createConstructorScalarFromNonScalar(
TIntermAggregate *node,
spirv::IdRef typeId,
const spirv::IdRefList ¶meters)
{ … }
spirv::IdRef OutputSPIRVTraverser::createConstructorVectorFromScalar(
const TType ¶meterType,
const TType &expectedType,
spirv::IdRef typeId,
const spirv::IdRefList ¶meters)
{ … }
spirv::IdRef OutputSPIRVTraverser::createConstructorVectorFromMatrix(
TIntermAggregate *node,
spirv::IdRef typeId,
const spirv::IdRefList ¶meters)
{ … }
spirv::IdRef OutputSPIRVTraverser::createConstructorVectorFromMultiple(
TIntermAggregate *node,
spirv::IdRef typeId,
const spirv::IdRefList ¶meters)
{ … }
spirv::IdRef OutputSPIRVTraverser::createConstructorMatrixFromScalar(
TIntermAggregate *node,
spirv::IdRef typeId,
const spirv::IdRefList ¶meters)
{ … }
spirv::IdRef OutputSPIRVTraverser::createConstructorMatrixFromVectors(
TIntermAggregate *node,
spirv::IdRef typeId,
const spirv::IdRefList ¶meters)
{ … }
spirv::IdRef OutputSPIRVTraverser::createConstructorMatrixFromMatrix(
TIntermAggregate *node,
spirv::IdRef typeId,
const spirv::IdRefList ¶meters)
{ … }
spirv::IdRefList OutputSPIRVTraverser::loadAllParams(TIntermOperator *node,
size_t skipCount,
spirv::IdRefList *paramTypeIds)
{ … }
void OutputSPIRVTraverser::extractComponents(TIntermAggregate *node,
size_t componentCount,
const spirv::IdRefList ¶meters,
spirv::IdRefList *extractedComponentsOut)
{ … }
void OutputSPIRVTraverser::startShortCircuit(TIntermBinary *node)
{ … }
spirv::IdRef OutputSPIRVTraverser::endShortCircuit(TIntermBinary *node, spirv::IdRef *typeId)
{ … }
spirv::IdRef OutputSPIRVTraverser::createFunctionCall(TIntermAggregate *node,
spirv::IdRef resultTypeId)
{ … }
void OutputSPIRVTraverser::visitArrayLength(TIntermUnary *node)
{ … }
bool IsShortCircuitNeeded(TIntermOperator *node)
{ … }
WriteUnaryOp;
WriteBinaryOp;
WriteTernaryOp;
WriteQuaternaryOp;
WriteAtomicOp;
spirv::IdRef OutputSPIRVTraverser::visitOperator(TIntermOperator *node, spirv::IdRef resultTypeId)
{ … }
spirv::IdRef OutputSPIRVTraverser::createCompare(TIntermOperator *node, spirv::IdRef resultTypeId)
{ … }
spirv::IdRef OutputSPIRVTraverser::createAtomicBuiltIn(TIntermOperator *node,
spirv::IdRef resultTypeId)
{ … }
spirv::IdRef OutputSPIRVTraverser::createImageTextureBuiltIn(TIntermOperator *node,
spirv::IdRef resultTypeId)
{ … }
spirv::IdRef OutputSPIRVTraverser::createSubpassLoadBuiltIn(TIntermOperator *node,
spirv::IdRef resultTypeId)
{ … }
spirv::IdRef OutputSPIRVTraverser::createInterpolate(TIntermOperator *node,
spirv::IdRef resultTypeId)
{ … }
spirv::IdRef OutputSPIRVTraverser::castBasicType(spirv::IdRef value,
const TType &valueType,
const TType &expectedType,
spirv::IdRef *resultTypeIdOut)
{ … }
spirv::IdRef OutputSPIRVTraverser::cast(spirv::IdRef value,
const TType &valueType,
const SpirvTypeSpec &valueTypeSpec,
const SpirvTypeSpec &expectedTypeSpec,
spirv::IdRef *resultTypeIdOut)
{ … }
void OutputSPIRVTraverser::extendScalarParamsToVector(TIntermOperator *node,
spirv::IdRef resultTypeId,
spirv::IdRefList *parameters)
{ … }
spirv::IdRef OutputSPIRVTraverser::reduceBoolVector(TOperator op,
const spirv::IdRefList &valueIds,
spirv::IdRef typeId,
const SpirvDecorations &decorations)
{ … }
void OutputSPIRVTraverser::createCompareImpl(TOperator op,
const TType &operandType,
spirv::IdRef resultTypeId,
spirv::IdRef leftId,
spirv::IdRef rightId,
const SpirvDecorations &operandDecorations,
const SpirvDecorations &resultDecorations,
spirv::LiteralIntegerList *currentAccessChain,
spirv::IdRefList *intermediateResultsOut)
{ … }
spirv::IdRef OutputSPIRVTraverser::makeBuiltInOutputStructType(TIntermOperator *node,
size_t lvalueCount)
{ … }
void OutputSPIRVTraverser::storeBuiltInStructOutputInParamsAndReturnValue(
TIntermOperator *node,
size_t lvalueCount,
spirv::IdRef structValue,
spirv::IdRef returnValue,
spirv::IdRef returnValueType)
{ … }
void OutputSPIRVTraverser::storeBuiltInStructOutputInParamHelper(NodeData *data,
TIntermTyped *param,
spirv::IdRef structValue,
uint32_t fieldIndex)
{ … }
void OutputSPIRVTraverser::visitSymbol(TIntermSymbol *node)
{ … }
void OutputSPIRVTraverser::visitConstantUnion(TIntermConstantUnion *node)
{ … }
bool OutputSPIRVTraverser::visitSwizzle(Visit visit, TIntermSwizzle *node)
{ … }
bool OutputSPIRVTraverser::visitBinary(Visit visit, TIntermBinary *node)
{ … }
bool OutputSPIRVTraverser::visitUnary(Visit visit, TIntermUnary *node)
{ … }
bool OutputSPIRVTraverser::visitTernary(Visit visit, TIntermTernary *node)
{ … }
bool OutputSPIRVTraverser::visitIfElse(Visit visit, TIntermIfElse *node)
{ … }
bool OutputSPIRVTraverser::visitSwitch(Visit visit, TIntermSwitch *node)
{ … }
bool OutputSPIRVTraverser::visitCase(Visit visit, TIntermCase *node)
{ … }
bool OutputSPIRVTraverser::visitBlock(Visit visit, TIntermBlock *node)
{ … }
bool OutputSPIRVTraverser::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
{ … }
bool OutputSPIRVTraverser::visitGlobalQualifierDeclaration(Visit visit,
TIntermGlobalQualifierDeclaration *node)
{ … }
void OutputSPIRVTraverser::visitFunctionPrototype(TIntermFunctionPrototype *node)
{ … }
bool OutputSPIRVTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
{ … }
bool OutputSPIRVTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
{ … }
void GetLoopBlocks(const SpirvConditional *conditional,
TLoopType loopType,
bool hasCondition,
spirv::IdRef *headerBlock,
spirv::IdRef *condBlock,
spirv::IdRef *bodyBlock,
spirv::IdRef *continueBlock,
spirv::IdRef *mergeBlock)
{ … }
bool OutputSPIRVTraverser::visitLoop(Visit visit, TIntermLoop *node)
{ … }
bool OutputSPIRVTraverser::visitBranch(Visit visit, TIntermBranch *node)
{ … }
void OutputSPIRVTraverser::visitPreprocessorDirective(TIntermPreprocessorDirective *node)
{ … }
void OutputSPIRVTraverser::markVertexOutputOnShaderEnd()
{ … }
void OutputSPIRVTraverser::markVertexOutputOnEmitVertex()
{ … }
spirv::Blob OutputSPIRVTraverser::getSpirv()
{ … }
}
bool OutputSPIRV(TCompiler *compiler,
TIntermBlock *root,
const ShCompileOptions &compileOptions,
const angle::HashMap<int, uint32_t> &uniqueToSpirvIdMap,
uint32_t firstUnusedSpirvId)
{ … }
}