blob: 8323e946f6954bf1f3e5df6c44b7644ed29d2186 [file] [log] [blame]
//
// 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 <vector>
namespace angle
{
namespace spirv
{
template <typename Helper>
class BoxedUint32
{
public:
BoxedUint32() : mValue{0} {}
explicit BoxedUint32(uint32_t value) : mValue{value} {}
template <typename T>
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<bool>(mValue.value); }
private:
Helper mValue;
};
struct IdRefHelper
{
uint32_t value;
};
struct LiteralIntegerHelper
{
uint32_t value;
};
using IdRef = BoxedUint32<IdRefHelper>;
template <>
inline BoxedUint32<IdRefHelper>::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<LiteralIntegerHelper>;
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 <typename T>
using FastVectorHelper = angle::FastVector<T, kFastVectorSize>;
using IdRefList = FastVectorHelper<IdRef>;
using LiteralIntegerList = FastVectorHelper<LiteralInteger>;
using PairLiteralIntegerIdRefList = FastVectorHelper<PairLiteralIntegerIdRef>;
using PairIdRefLiteralIntegerList = FastVectorHelper<PairIdRefLiteralInteger>;
using PairIdRefIdRefList = FastVectorHelper<PairIdRefIdRef>;
// 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<uint32_t>;
// 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);
} // namespace spirv
} // namespace angle
#endif // COMMON_SPIRV_TYPES_H_