Types.h#

Parent directory (types)

Basic file used in the PowerVR Framework. Defines several types used throughout the Framework (sized arithmetic types, enumerations, character types).

Includes#

  • algorithm

  • array

  • assert.h

  • cmath

  • cstddef

  • cstdio

  • cstdlib

  • cstring

  • functional

  • limits

  • memory

  • stdint.h

  • string (CompileTimeHash.h)

  • type_traits

  • vector

Included By#

Namespaces#

Classes#

Enums#

Functions#

Defines#

Typedefs#

Source Code#

#pragma once

#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef GLM_FORCE_SSE2
#define GLM_FORCE_SSE2
#endif
#endif
#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#endif

#if defined(X11)
// undef these macros from the xlib files, they are breaking the framework types.
#undef Success
#undef Enum
#undef None
#undef Always
#undef byte
#undef char8
#undef ShaderStageFlags
#undef capability
#endif

#include <vector>
#include <array>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstddef>
#include <cstring>
#include <memory>
#include <algorithm>
#include <functional>
#include <string>
#include <stdint.h>
#include <limits>
#include <assert.h>
#include <type_traits>

#define DEFINE_ENUM_OPERATORS(type_) \
\
    inline type_ operator|(type_ lhs, type_ rhs) \
\
    { \
        return static_cast<type_>(static_cast<std::underlying_type<type_>::type >(lhs) | static_cast<std::underlying_type<type_>::type >(rhs)); \
    } \
\
    inline void operator|=(type_& lhs, type_ rhs) \
\
    { \
        lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type >(lhs) | static_cast<std::underlying_type<type_>::type >(rhs)); \
    } \
\
    inline type_ operator&(type_ lhs, type_ rhs) \
\
    { \
        return static_cast<type_>(static_cast<std::underlying_type<type_>::type >(lhs) & static_cast<std::underlying_type<type_>::type >(rhs)); \
    } \
\
    inline void operator&=(type_& lhs, type_ rhs) \
\
    { \
        lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type >(lhs) & static_cast<std::underlying_type<type_>::type >(rhs)); \
    }

namespace pvr {

enum class Api
{
    Unspecified = 0,
    // OpenGL,
    OpenGLES2,
    OpenGLES3,
    OpenGLES31,
    OpenGLESMaxVersion = OpenGLES31,
    Vulkan,
    NumApis
};

inline const char* apiCode(Api api)
{
    static const char* ApiCodes[] = {
        "",
        "ES2",
        "ES3",
        "ES31",
        "vk",
    };
    return ApiCodes[static_cast<int>(api)];
}

inline const char* apiName(Api api)
{
    static const char* ApiCodes[] = {
        "Unknown",
        "OpenGL ES 2.0",
        "OpenGL ES 3.0",
        "OpenGL ES 3.1",
        "Vulkan",
    };
    return ApiCodes[static_cast<int>(api)];
}

enum class DescriptorType : uint32_t
{
    // DO NOT RE-ARRANGE THIS
    Sampler,
    CombinedImageSampler,
    SampledImage,
    StorageImage,
    UniformTexelBuffer,
    StorageTexelBuffer,
    UniformBuffer,
    StorageBuffer,
    UniformBufferDynamic,
    StorageBufferDynamic,
    InputAttachment,
    Count = 12,
    NumBits = 4
};

enum class BufferUsageFlags : uint32_t
{
    TransferSrc = 0x00000001,
    TransferDest = 0x00000002,
    UniformTexelBuffer = 0x00000004,
    StorageTexelBuffer = 0x00000008,
    UniformBuffer = 0x00000010,
    StorageBuffer = 0x00000020,
    IndexBuffer = 0x00000040,
    VertexBuffer = 0x00000080,
    IndirectBuffer = 0x00000100,
    Count = 10
};
DEFINE_ENUM_OPERATORS(BufferUsageFlags)


inline BufferUsageFlags descriptorTypeToBufferUsage(DescriptorType descType)
{
    if (descType == DescriptorType::UniformBuffer || descType == DescriptorType::UniformBufferDynamic) { return BufferUsageFlags::UniformBuffer; }
    return BufferUsageFlags::StorageBuffer;
}

inline bool isDescriptorTypeDynamic(DescriptorType descType) { return (descType == DescriptorType::UniformBufferDynamic || descType == DescriptorType::StorageBufferDynamic); }

template<typename t1, typename t2>
inline t1 align(t1 numberToAlign, t2 alignment)
{
    if (alignment)
    {
        t1 align1 = numberToAlign % (t1)alignment;
        if (!align1) { align1 += (t1)alignment; }
        numberToAlign += t1(alignment) - align1;
    }
    return numberToAlign;
}

enum class DataType
{
    None,
    Float32,
    Int32,
    UInt16,
    RGBA,
    ARGB,
    D3DCOLOR,
    UBYTE4,
    DEC3N,
    Fixed16_16,
    UInt8,
    Int16,
    Int16Norm,
    Int8,
    Int8Norm,
    UInt8Norm,
    UInt16Norm,
    UInt32,
    ABGR,
    Float16,
    Custom = 1000
};

inline uint32_t dataTypeSize(DataType type)
{
    switch (type)
    {
    default: assert(false); return 0;
    case DataType::Float32:
    case DataType::Int32:
    case DataType::UInt32:
    case DataType::RGBA:
    case DataType::ABGR:
    case DataType::ARGB:
    case DataType::D3DCOLOR:
    case DataType::UBYTE4:
    case DataType::DEC3N: //(1D/2D/3D).
    case DataType::Fixed16_16: return 4;
    case DataType::Int16:
    case DataType::Int16Norm:
    case DataType::UInt16: return 2;
    case DataType::UInt8:
    case DataType::UInt8Norm:
    case DataType::Int8:
    case DataType::Int8Norm: return 1;
    }
}
inline uint32_t numDataTypeComponents(DataType type)
{
    switch (type)
    {
    default: assert(false); return 0;
    case DataType::Float32:
    case DataType::Int32:
    case DataType::UInt32:
    case DataType::Int16:
    case DataType::Int16Norm:
    case DataType::UInt16:
    case DataType::Fixed16_16:
    case DataType::Int8:
    case DataType::Int8Norm:
    case DataType::UInt8:
    case DataType::UInt8Norm: return 1;
    case DataType::DEC3N: return 3;
    case DataType::RGBA:
    case DataType::ABGR:
    case DataType::ARGB:
    case DataType::D3DCOLOR:
    case DataType::UBYTE4: return 4;
    }
}

inline bool dataTypeIsNormalised(DataType type)
{
    return (type == DataType::Int8Norm || type == DataType::UInt8Norm || type == DataType::Int16Norm || type == DataType::UInt16Norm);
}

enum class PrimitiveTopology : uint32_t
{
    // POSITION-SENSITIVE. Do not renumber unless also refactoring ConvertToPVRVkTypes.
    PointList,
    LineList,
    LineStrip,
    TriangleList,
    TriangleStrip,
    TriangleFan,
    LineListWithAdjacency,
    LineStripWithAdjacency,
    TriangleListWithAdjacency,
    TriangleStripWithAdjacency,
    PatchList,
    Count
};

enum class ColorChannelFlags : uint32_t
{
    // DO NOT REARRANGE - Direct mapping to Vulkan
    R = 0x01,
    G = 0x02,
    B = 0x04,
    A = 0x08,
    None = 0,
    All = R | G | B | A //< write to all channel
};
DEFINE_ENUM_OPERATORS(ColorChannelFlags)


enum class StepRate : uint32_t
{
    Vertex,
    Instance,
    Default = Vertex
};

enum class Face : uint32_t
{
    // DO NOT REARRANGE - DIRECT TO VULKAN
    None = 0,
    Front = 1,
    Back = 2,
    FrontAndBack = 3,
    Default = None
};

enum class BlendOp : uint32_t
{
    // DO NOT REARRANGE - Direct mapping to Vulkan. See convertToPVRVk
    Add,
    Subtract,
    ReverseSubtract,
    Min,
    Max,
    NumBlendFunc,
    Default = Add
};

enum class BlendFactor : uint8_t
{
    Zero,
    One,
    SrcColor,
    OneMinusSrcColor,
    DstColor,
    OneMinusDstColor,
    SrcAlpha,
    OneMinusSrcAlpha,
    DstAlpha,
    OneMinusDstAlpha,
    ConstantColor,
    OneMinusConstantColor,
    ConstantAlpha,
    OneMinusConstantAlpha,
    Src1Color,
    OneMinusSrc1Color,
    Src1Alpha,
    OneMinusSrc1Alpha,
    NumBlendFactor,
    DefaultSrcRgba = One,
    DefaultDestRgba = Zero
};

enum class PolygonWindingOrder : uint8_t
{
    // DO NOT REARRANGE - VULKAN DIRECT MAPPING
    FrontFaceCCW,
    FrontFaceCW,
    Default = FrontFaceCCW
};

enum class StencilOp : uint8_t
{
    // DO NOT REARRANGE - VULKAN DIRECT MAPPING
    Keep,
    Zero,
    Replace,
    IncrementClamp,
    DecrementClamp,
    Invert,
    IncrementWrap,
    DecrementWrap,
    NumStencilOp,

    // Defaults
    Default = Keep,
};

enum class Capability : uint8_t
{
    Unsupported,
    Immutable,
    Mutable
};

enum class IndexType : uint32_t
{
    IndexType16Bit = static_cast<uint32_t>(DataType::UInt16),
    IndexType32Bit = static_cast<uint32_t>(DataType::UInt32)
};

inline uint32_t indexTypeSizeInBytes(const IndexType type)
{
    switch (type)
    {
    default: assert(false); return false;
    case IndexType::IndexType16Bit: return 2;
    case IndexType::IndexType32Bit: return 4;
    }
}

enum class CompareOp : uint32_t
{
    // DIRECT MAPPING FOR VULKAN - DO NOT REARRANGE
    Never = 0,
    Less = 1,
    Equal = 2,
    LessEqual = 3,
    Greater = 4,
    NotEqual = 5,
    GreaterEqual = 6,
    Always = 7,
    NumComparisonMode,
    DefaultDepthFunc = Less,
    DefaultStencilFunc = Always,
};

enum class Filter : uint8_t
{
    Nearest,
    Linear, //< Linear (average weighted by distance)
    None,
    Cubic,
    Default = Linear,
    MipDefault = Linear,
    Size = 4
};

enum class SamplerAddressMode : uint8_t
{
    Repeat,
    MirrorRepeat,
    ClampToEdge,
    ClampToBorder,
    MirrorClampToEdge,
    Size,
    Default = Repeat
};

enum class SamplerMipmapMode : uint8_t
{
    Nearest,
    Linear,
    Count
};

enum PackedSamplerFilter : int8_t
{
    PackNone, //< no filter
    PackNearestMipNone = static_cast<uint8_t>(static_cast<uint8_t>(Filter::Nearest) | (static_cast<uint8_t>(Filter::Nearest) << 2) |
        (static_cast<uint8_t>(SamplerMipmapMode::Nearest) << 4)), //<Nearest Neighbour, no mipmap use
    PackNearestMipNearest = static_cast<uint8_t>(static_cast<uint8_t>(Filter::Nearest) | (static_cast<uint8_t>(Filter::Nearest) << 2) |
        (static_cast<uint8_t>(SamplerMipmapMode::Nearest) << 4)), //<Nearest Neighbour per mipmap, nearest neighbour between mipmaps
    PackNearestMipLinear = static_cast<uint8_t>(static_cast<uint8_t>(Filter::Nearest) | (static_cast<uint8_t>(Filter::Nearest) << 2) |
        (static_cast<uint8_t>(SamplerMipmapMode::Linear) << 4)), //<Nearest Neighbour, linearly interpolate between mipmaps (OpenGL Default)
    PackLinearMipNone = static_cast<uint8_t>(
        static_cast<uint8_t>(Filter::Linear) | (static_cast<uint8_t>(Filter::Linear) << 2) | (static_cast<uint8_t>(SamplerMipmapMode::Nearest) << 4)), //< Bilinear, no mipmap use
    PackLinearMipNearest = static_cast<uint8_t>(static_cast<uint8_t>(Filter::Linear) | (static_cast<uint8_t>(Filter::Linear) << 2) |
        (static_cast<uint8_t>(SamplerMipmapMode::Nearest) << 4)), //< Bilinear, nearest neighbour between mipmaps
    PackTrilinear = static_cast<uint8_t>(static_cast<uint8_t>(Filter::Linear) | (static_cast<uint8_t>(Filter::Linear) << 2) |
        (static_cast<uint8_t>(SamplerMipmapMode::Linear) << 4)), //< Full Trilinear (bilinear, linearly interpolate between mipmaps)
    Size, //< number of supported filter
    PackDefault = PackTrilinear //< default filter
};

inline PackedSamplerFilter packSamplerFilter(Filter mini, Filter magni, SamplerMipmapMode mip)
{
    return PackedSamplerFilter(static_cast<PackedSamplerFilter>(mini) + (static_cast<PackedSamplerFilter>(magni) << 2) + (static_cast<PackedSamplerFilter>(mip) << 4));
}

inline void unpackSamplerFilter(PackedSamplerFilter packed, Filter& mini, Filter& magni, SamplerMipmapMode& mip)
{
    mini = static_cast<Filter>(packed & 3);
    magni = static_cast<Filter>((packed >> 2) & 3);
    mip = static_cast<SamplerMipmapMode>(packed >> 4);
}

enum class ShaderType
{
    UnknownShader = 0,
    VertexShader,
    FragmentShader,
    ComputeShader,
    TessControlShader,
    TessEvaluationShader,
    GeometryShader,
    RayShader,
    FrameShader,
    Count
};

inline std::string to_string(ShaderType shaderType)
{
    switch (shaderType)
    {
    case ShaderType::VertexShader: return "Vertex";
    case ShaderType::FragmentShader: return "Fragment";
    case ShaderType::ComputeShader: return "Compute";
    case ShaderType::TessControlShader: return "Tessellation Control";
    case ShaderType::TessEvaluationShader: return "Tessellation Evaluation";
    case ShaderType::GeometryShader: return "Geometry";
    case ShaderType::RayShader: return "Ray";
    case ShaderType::FrameShader: return "Frame";
    default: return "Unknown";
    }
}

enum class Result
{
    Success,
    UnknownError,
    NotInitialized,
    // Shell Error
    InitializationError,
    UnsupportedRequest,

    ExitRenderFrame, // Used to exit the renderscene loop in the shell
};
inline const char* getResultCodeString(Result result)
{
    switch (result)
    {
    case Result::Success: return "Success";
    case Result::UnknownError: return "Unknown Error";
    case Result::ExitRenderFrame: return "Exit Render Scene";
    case Result::NotInitialized: return "Not initialized";
    case Result::InitializationError: return "Error while initializing";
    default: return "UNRECOGNIZED CODE";
    }
}

typedef ::std::vector<unsigned char> UInt8Buffer;

class StridedBuffer : public UInt8Buffer
{
public:
    uint16_t stride;
};

inline float randomrange(float min, float max)
{
    float zero_to_one = static_cast<float>(double(rand()) / double(RAND_MAX));
    float diff = max - min;
    return zero_to_one * diff + min;
}

enum class VsyncMode
{
    Off,
    On,
    Relaxed,
    Mailbox,
    Half,
};

class DisplayAttributes
{
public:
    enum
    {
        PosDefault = -1
    };

    std::string windowTitle;

    uint32_t width;
    uint32_t height;
    uint32_t x;
    uint32_t y;

    uint32_t depthBPP;
    uint32_t stencilBPP;

    uint32_t redBits;
    uint32_t greenBits;
    uint32_t blueBits;
    uint32_t alphaBits;

    uint32_t aaSamples;

    uint32_t configID;

    VsyncMode vsyncMode;
    int32_t contextPriority;
    int32_t swapLength;

    bool forceColorBPP;
    bool fullscreen;
    bool frameBufferSrgb;

    // Default constructor
    DisplayAttributes()
        : width(1280), height(800), x(static_cast<uint32_t>(0)), y(static_cast<uint32_t>(0)), depthBPP(32u), stencilBPP(0u), redBits(8u), greenBits(8u), blueBits(8u),
          alphaBits(8u), aaSamples(0u), configID(0u), vsyncMode(VsyncMode::On), contextPriority(2), swapLength(0), forceColorBPP(false), fullscreen(false), frameBufferSrgb(true)
    {}
    bool isDisplayPortrait() const { return height > width; }
    bool isFullScreen() const { return fullscreen; }
};

typedef void* OSConnection;

typedef void* OSDisplay;

typedef void* OSWindow;

typedef void* OSApplication;

typedef void* OSDATA;

enum class Swizzle : uint8_t // DIRECT VULKAN MAPPING - DO NOT REARRANGE
{
    Identity = 0,
    // Unset = 0,
    Zero = 1,
    One = 2,
    R = 3,
    G = 4,
    B = 5,
    A = 6,
    Red = R,
    Green = G,
    Blue = B,
    Alpha = A,
};

struct SwizzleChannels
{
    Swizzle r;
    Swizzle g;
    Swizzle b;
    Swizzle a;

    SwizzleChannels() : r(Swizzle::Identity), g(Swizzle::Identity), b(Swizzle::Identity), a(Swizzle::Identity) {}

    SwizzleChannels(Swizzle r, Swizzle g, Swizzle b, Swizzle a) : r(r), g(g), b(b), a(a) {}
};

struct VertexAttributeLayout
{
    DataType dataType;
    uint16_t offset;
    uint8_t width;

    VertexAttributeLayout() : dataType(DataType::None), offset(static_cast<uint16_t>(-1)), width(static_cast<uint8_t>(-1)) {}

    VertexAttributeLayout(DataType dataType, uint8_t width, uint16_t offset) : dataType(dataType), offset(offset), width(width) {}
};

struct BlendingConfig
{
    bool blendEnable;
    BlendFactor srcBlendColor;
    BlendFactor dstBlendColor;
    BlendOp blendOpColor;
    BlendFactor srcBlendAlpha;
    BlendFactor dstBlendAlpha;
    BlendOp blendOpAlpha;
    ColorChannelFlags channelWriteMask;

    BlendingConfig(bool blendEnable = false, BlendFactor srcBlendColor = BlendFactor::One, BlendFactor dstBlendColor = BlendFactor::Zero, BlendOp blendOpColor = BlendOp::Add,
        BlendFactor srcBlendAlpha = BlendFactor::One, BlendFactor dstBlendAlpha = BlendFactor::Zero, BlendOp blendOpAlpha = BlendOp::Add,
        ColorChannelFlags channelWriteMask = ColorChannelFlags::All)
        : blendEnable(blendEnable), srcBlendColor(srcBlendColor), dstBlendColor(dstBlendColor), blendOpColor(blendOpColor), srcBlendAlpha(srcBlendAlpha),
          dstBlendAlpha(dstBlendAlpha), blendOpAlpha(blendOpAlpha), channelWriteMask(channelWriteMask)
    {}

    BlendingConfig(bool blendEnable, BlendFactor srcBlendFactor, BlendFactor dstBlendFactor, BlendOp blendOpColorAlpha, ColorChannelFlags channelWriteMask = ColorChannelFlags::All)
        : blendEnable(blendEnable), srcBlendColor(srcBlendFactor), dstBlendColor(dstBlendFactor), blendOpColor(blendOpColorAlpha), srcBlendAlpha(srcBlendFactor),
          dstBlendAlpha(dstBlendFactor), blendOpAlpha(blendOpColorAlpha), channelWriteMask(channelWriteMask)
    {}
};

struct StencilState
{
    StencilOp opDepthPass;
    StencilOp opDepthFail;
    StencilOp opStencilFail;
    uint32_t compareMask;
    uint32_t writeMask;
    uint32_t reference;
    CompareOp compareOp;

    StencilState(StencilOp depthPass = StencilOp::Keep, StencilOp depthFail = StencilOp::Keep, StencilOp stencilFail = StencilOp::Keep,
        CompareOp compareOp = CompareOp::DefaultStencilFunc, uint32_t compareMask = 0xff, uint32_t writeMask = 0xff, uint32_t reference = 0)
        : opDepthPass(depthPass), opDepthFail(depthFail), opStencilFail(stencilFail), compareMask(compareMask), writeMask(writeMask), reference(reference), compareOp(compareOp)
    {}
};

#if defined(_MSC_VER)
#define PVR_ALIGNED __declspec(align(16))
#elif defined(__GNUC__) || defined(__clang__)
#define PVR_ALIGNED __attribute__((aligned(16)))
#else
#define PVR_ALIGNED alignas(16)
#endif
} // namespace pvr

#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))

#undef DEFINE_ENUM_OPERATORS