// // Copyright 2021 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // spirv_types.h: // Strong types for SPIR-V Ids to prevent mistakes when using the builder and parser APIs. // #ifndef COMMON_SPIRV_TYPES_H_ #define COMMON_SPIRV_TYPES_H_ #include "common/FastVector.h" #include namespace angle { namespace spirv { template class BoxedUint32 { public: BoxedUint32() : mValue{0} {} explicit BoxedUint32(uint32_t value) : mValue{value} {} template T as() const { return T{mValue}; } BoxedUint32(const BoxedUint32 &other) = default; BoxedUint32 &operator=(const BoxedUint32 &other) = default; operator uint32_t() const { return mValue.value; } bool operator==(const BoxedUint32 &other) const { return mValue.value == other.mValue.value; } // Applicable to ids, which cannot be 0. bool valid() const { return static_cast(mValue.value); } private: Helper mValue; }; struct IdRefHelper { uint32_t value; }; struct LiteralIntegerHelper { uint32_t value; }; using IdRef = BoxedUint32; template <> inline BoxedUint32::operator uint32_t() const { ASSERT(valid()); return mValue.value; } // IdResult, IdResultType, IdMemorySemantics and IdScope are all translated as IdRef. This makes // the type verification weaker, but stops the API from becoming tediously verbose. using IdResult = IdRef; using IdResultType = IdRef; using IdMemorySemantics = IdRef; using IdScope = IdRef; using LiteralInteger = BoxedUint32; using LiteralString = const char *; // Note: In ANGLE's use cases, all literals fit in 32 bits. using LiteralContextDependentNumber = LiteralInteger; // TODO(syoussefi): To be made stronger when generating SPIR-V from the translator. // http://anglebug.com/4889 using LiteralExtInstInteger = LiteralInteger; struct PairLiteralIntegerIdRef { LiteralInteger literal; IdRef id; }; struct PairIdRefLiteralInteger { IdRef id; LiteralInteger literal; }; struct PairIdRefIdRef { IdRef id1; IdRef id2; }; // Some instructions need 4 components. The drivers uniform struct in ANGLE has 8 fields. A value // of 8 means almost no instruction would end up making dynamic allocations. Notable exceptions are // user-defined structs/blocks and OpEntryPoint. constexpr size_t kFastVectorSize = 8; template using FastVectorHelper = angle::FastVector; using IdRefList = FastVectorHelper; using LiteralIntegerList = FastVectorHelper; using PairLiteralIntegerIdRefList = FastVectorHelper; using PairIdRefLiteralIntegerList = FastVectorHelper; using PairIdRefIdRefList = FastVectorHelper; // Id 0 is invalid in SPIR-V. constexpr uint32_t kMinValidId = 1; // The SPIR-V blob is a sequence of uint32_t's using Blob = std::vector; // Format of the SPIR-V header. // SPIR-V 1.0 Table 1: First Words of Physical Layout enum HeaderIndex { kHeaderIndexMagic = 0, kHeaderIndexVersion = 1, kHeaderIndexGenerator = 2, kHeaderIndexIndexBound = 3, kHeaderIndexSchema = 4, kHeaderIndexInstructions = 5, }; // Returns whether SPIR-V is valid. Useful for ASSERTs. Automatically generates a warning if // SPIR-V is not valid. bool Validate(const Blob &blob); void Print(const Blob &blob); } // namespace spirv } // namespace angle #endif // COMMON_SPIRV_TYPES_H_