GpuDataTypes.h#

Parent directory (types)

Includes#

  • PVRCore/types/Types.h

  • cstdint

Included By#

Namespaces#

Enums#

Functions#

Source Code#

#pragma once
#include <cstdint>
#include "PVRCore/types/Types.h"

namespace pvr {
namespace GpuDatatypesHelper {
enum class BaseType
{
    Integer = 0,
    Float = 1
};
enum class VectorWidth
{
    Scalar = 0,
    Vec2 = 1,
    Vec3 = 2,
    Vec4 = 3,
};
enum class MatrixColumns
{
    OneCol = 0,
    Mat2x = 1,
    Mat3x = 2,
    Mat4x = 3
};

enum class Bits : uint32_t
{
    Integer = 0,
    Float = 1,
    BitScalar = 0,
    BitVec2 = 2,
    BitVec3 = 4,
    BitVec4 = 6,
    BitOneCol = 0,
    BitMat2x = 8,
    BitMat3x = 16,
    BitMat4x = 24,
    ShiftType = 0,
    MaskType = 1,
    NotMaskType = static_cast<uint32_t>(~MaskType),
    ShiftVec = 1,
    MaskVec = (3 << ShiftVec),
    NotMaskVec = static_cast<uint32_t>(~MaskVec),
    ShiftCols = 3,
    MaskCols = (3 << ShiftCols),
    NotMaskCols = static_cast<uint32_t>(~MaskCols)
};

inline Bits operator|(Bits lhs, Bits rhs)
{
    return static_cast<Bits>(static_cast<std::underlying_type<Bits>::type >(lhs) | static_cast<std::underlying_type<Bits>::type >(rhs));
}

inline void operator|=(Bits& lhs, Bits rhs)
{
    lhs = static_cast<Bits>(static_cast<std::underlying_type<Bits>::type >(lhs) | static_cast<std::underlying_type<Bits>::type >(rhs));
}

inline Bits operator&(Bits lhs, Bits rhs)
{
    return static_cast<Bits>(static_cast<std::underlying_type<Bits>::type >(lhs) & static_cast<std::underlying_type<Bits>::type >(rhs));
}

inline void operator&=(Bits& lhs, Bits rhs)
{
    lhs = static_cast<Bits>(static_cast<std::underlying_type<Bits>::type >(lhs) & static_cast<std::underlying_type<Bits>::type >(rhs));
}
} // namespace GpuDatatypesHelper

enum class GpuDatatypes : uint32_t
{
    Integer = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Integer) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitScalar) |
        static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitOneCol),
    uinteger = Integer,
    boolean = Integer,
    Float = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitScalar) |
        static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitOneCol),
    ivec2 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Integer) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec2) |
        static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitOneCol),
    uvec2 = ivec2,
    bvec2 = ivec2,
    ivec3 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Integer) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec3) |
        static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitOneCol),
    uvec3 = ivec3,
    bvec3 = ivec3,
    ivec4 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Integer) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec4) |
        static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitOneCol),
    uvec4 = ivec4,
    bvec4 = ivec4,
    vec2 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec2) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitOneCol),
    vec3 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec3) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitOneCol),
    vec4 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec4) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitOneCol),
    mat2x2 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec2) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitMat2x),
    mat2x3 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec3) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitMat2x),
    mat2x4 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec4) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitMat2x),
    mat3x2 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec2) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitMat3x),
    mat3x3 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec3) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitMat3x),
    mat3x4 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec4) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitMat3x),
    mat4x2 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec2) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitMat4x),
    mat4x3 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec3) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitMat4x),
    mat4x4 = static_cast<uint32_t>(GpuDatatypesHelper::Bits::Float) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec4) | static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitMat4x),
    none = 0xFFFFFFFF,
    structure = none
};
inline GpuDatatypes operator&(GpuDatatypes lhs, GpuDatatypesHelper::Bits rhs) { return static_cast<GpuDatatypes>(static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs)); }

inline GpuDatatypes operator>>(GpuDatatypes lhs, GpuDatatypesHelper::Bits rhs) { return static_cast<GpuDatatypes>(static_cast<uint32_t>(lhs) >> static_cast<uint32_t>(rhs)); }

inline GpuDatatypes operator<<(GpuDatatypes lhs, GpuDatatypesHelper::Bits rhs) { return static_cast<GpuDatatypes>(static_cast<uint32_t>(lhs) << static_cast<uint32_t>(rhs)); }

inline uint32_t getNumMatrixColumns(GpuDatatypes type)
{
    return static_cast<uint32_t>(GpuDatatypesHelper::MatrixColumns(static_cast<uint32_t>((type & GpuDatatypesHelper::Bits::MaskCols) >> GpuDatatypesHelper::Bits::ShiftCols) + 1));
}

inline uint32_t getAlignment(GpuDatatypes type)
{
    uint32_t vectype = static_cast<uint32_t>(type & GpuDatatypesHelper::Bits::MaskVec);
    return (vectype == static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitScalar) ? 4u : vectype == static_cast<uint32_t>(GpuDatatypesHelper::Bits::BitVec2) ? 8u : 16u);
}

inline uint32_t getVectorSelfAlignedSize(GpuDatatypes type) { return getAlignment(type); }

inline uint32_t getNumVecElements(GpuDatatypes type)
{
    return static_cast<uint32_t>(GpuDatatypesHelper::VectorWidth(static_cast<uint32_t>((type & GpuDatatypesHelper::Bits::MaskVec) >> GpuDatatypesHelper::Bits::ShiftVec) + 1));
}

inline uint32_t getVectorUnalignedSize(GpuDatatypes type) { return 4 * getNumVecElements(type); }

inline GpuDatatypesHelper::BaseType getBaseType(GpuDatatypes type) { return GpuDatatypesHelper::BaseType(static_cast<uint32_t>(type) & 1); }

inline GpuDatatypes mergeDatatypesBigger(GpuDatatypes type1, GpuDatatypes type2)
{
    uint32_t baseTypeBits = static_cast<uint32_t>((::std::max)(type1 & GpuDatatypesHelper::Bits::MaskType, type2 & GpuDatatypesHelper::Bits::MaskType));
    uint32_t vectorWidthBits = static_cast<uint32_t>((::std::max)(type1 & GpuDatatypesHelper::Bits::MaskVec, type2 & GpuDatatypesHelper::Bits::MaskVec));
    uint32_t matrixColBits = static_cast<uint32_t>((::std::max)(type1 & GpuDatatypesHelper::Bits::MaskCols, type2 & GpuDatatypesHelper::Bits::MaskCols));
    return GpuDatatypes(baseTypeBits | vectorWidthBits | matrixColBits);
}

inline GpuDatatypes mergeDatatypesSmaller(GpuDatatypes type1, GpuDatatypes type2)
{
    uint32_t baseTypeBits = static_cast<uint32_t>((::std::max)(type1 & GpuDatatypesHelper::Bits::MaskType, type2 & GpuDatatypesHelper::Bits::MaskType));
    uint32_t vectorWidthBits = static_cast<uint32_t>((::std::min)(type1 & GpuDatatypesHelper::Bits::MaskVec, type2 & GpuDatatypesHelper::Bits::MaskVec));
    uint32_t matrixColBits = static_cast<uint32_t>((::std::min)(type1 & GpuDatatypesHelper::Bits::MaskCols, type2 & GpuDatatypesHelper::Bits::MaskCols));
    return GpuDatatypes(baseTypeBits | vectorWidthBits | matrixColBits);
}

inline uint32_t getSelfAlignedSize(GpuDatatypes type)
{
    uint32_t isMatrix = (getNumMatrixColumns(type) > 1);

    return (::std::max)(getVectorSelfAlignedSize(type), static_cast<uint32_t>(16) * isMatrix) * getNumMatrixColumns(type);
}

inline uint32_t getSelfAlignedArraySize(GpuDatatypes type) { return (::std::max)(getVectorSelfAlignedSize(type), static_cast<uint32_t>(16)) * getNumMatrixColumns(type); }

inline uint64_t getSize(GpuDatatypes type, uint32_t arrayElements = 1)
{
    uint64_t numElements = getNumMatrixColumns(type) * arrayElements;

    uint64_t selfAlign = (::std::max)(static_cast<uint64_t>(getVectorSelfAlignedSize(type)), static_cast<uint64_t>(16)) * numElements *
        (numElements > 1); // Equivalent to: if (arrayElements!=0) selfAlign = getVectorSelfAlignedSize(...) else selfAlign=0;
    uint64_t unaligned = getVectorUnalignedSize(type) * (numElements == 1); // Equivalent to: if (arrayElements==0) unaligned = getVectorUnalignedSize(...) else unaligned = 0;
    return selfAlign + unaligned;

    // *** THIS IS A BRANCHLESS EQUIVALENT OF THE FOLLOWING CODE ***
    // if (numElements > 1)
    //{
    // return (std::max)(getVectorSelfAlignedSize(type), 16u) * numElements;
    //}
    // else
    //{
    // return getVectorUnalignedSize(type);
    //}
}

inline const char* toString(GpuDatatypes type)
{
    switch (type)
    {
    case GpuDatatypes::Integer: return "int";
    case GpuDatatypes::ivec2: return "ivec2";
    case GpuDatatypes::ivec3: return "ivec3";
    case GpuDatatypes::ivec4: return "ivec4";
    case GpuDatatypes::Float: return "float";
    case GpuDatatypes::vec2: return "vec2";
    case GpuDatatypes::vec3: return "vec3";
    case GpuDatatypes::vec4: return "vec4";
    case GpuDatatypes::mat2x2: return "mat2x2";
    case GpuDatatypes::mat2x3: return "mat2x3";
    case GpuDatatypes::mat2x4: return "mat2x4";
    case GpuDatatypes::mat3x2: return "mat3x2";
    case GpuDatatypes::mat3x3: return "mat3x3";
    case GpuDatatypes::mat3x4: return "mat3x4";
    case GpuDatatypes::mat4x2: return "mat4x2";
    case GpuDatatypes::mat4x3: return "mat4x3";
    case GpuDatatypes::mat4x4: return "mat4x4";
    case GpuDatatypes::none: return "NONE";
    default: return "UNKNOWN";
    }
}

inline uint64_t getCpuPackedSize(GpuDatatypes type, uint32_t arrayElements = 1) { return getVectorUnalignedSize(type) * getNumMatrixColumns(type) * arrayElements; }

inline uint32_t getOffsetAfter(GpuDatatypes type, uint64_t previousTotalSize)
{
    uint32_t align = getAlignment(type);

    uint32_t diff = previousTotalSize % align;
    diff += (align * (diff == 0)); // REMOVE BRANCHING -- equal to : if(diff==0) { diff+=8 }
    return static_cast<uint32_t>(previousTotalSize) - diff + align;
}

inline uint64_t getTotalSizeAfter(GpuDatatypes type, uint32_t arrayElements, uint64_t previousTotalSize)
{
    // Arrays pads their last element to their alignments. Standalone objects do not. vec3[3] is NOT the same as vec3;vec3;vec3;
    uint64_t selfAlignedSize = getSelfAlignedArraySize(type) * arrayElements * (arrayElements != 1); // Equivalent to: if (arrayElements!=1) selfAlign = getSelfAl... else selfAlign=0
    // Other elements do not.
    uint64_t unalignedSize = getSize(type) * (arrayElements == 1); // Equivalent to: if (arrayElements==1) unaligned = getUnaligned.... else unaligned=0

    return getOffsetAfter(type, previousTotalSize) + selfAlignedSize + unalignedSize;
}

inline DataType toDataType(GpuDatatypes type) { return getBaseType(type) == GpuDatatypesHelper::BaseType::Float ? DataType::Float32 : DataType::Int32; }

namespace GpuDatatypesHelper {
template<typename T>
struct Metadata; // Template specializations in FreeValue.h
}
} // namespace pvr