Last active
December 28, 2021 11:51
-
-
Save Quackward/af9506572aee751214b778d7e268371d to your computer and use it in GitHub Desktop.
check out the bottom for a lovely surprise
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "IntTypes.h" | |
#include "CoreGL.h" | |
namespace TextureFormat { | |
enum Type : uint8 { | |
// if a combo is missing, it's because it's not a required format by OpenGL | |
r8, rg8, rgb8, rgba8, | |
r16, rg16, rgb16, rgba16, | |
r8snorm, rg8snorm, rgb8snorm, rgba8snorm, | |
r16snorm, rg16snorm, rgb16snorm, rgba16snorm, | |
r8uint, rg8uint, rgb8uint, rgba8uint, | |
r16uint, rg16uint, rgb16uint, rgba16uint, | |
r32uint, rg32uint, rgb32uint, rgba32uint, | |
r8int, rg8int, rgb8int, rgba8int, | |
r16int, rg16int, rgb16int, rgba16int, | |
r32int, rg32int, rgb32int, rgba32int, | |
r16f, rg16f, rgb16f, rgba16f, | |
r32f, rg32f, rgb32f, rgba32f, | |
special_rgb10a2, | |
special_rgb10a2uint, | |
special_r11g11b10f, | |
depth16, | |
//depth24, no lol | |
depth32, | |
depth32f, | |
depth24Stencil8, | |
depth32fStencil8, | |
stencil8, | |
compress_dxt1, | |
compress_dxt5, | |
__count | |
}; | |
class Stats { | |
public: | |
Stats(GLuint _format, GLuint _uploadFormat, GLuint _uploadType, uint32 _bits = 0) | |
: m_format{_format}, m_uploadFormat{_uploadFormat}, m_uploadType{_uploadType}, m_bits{_bits} {} | |
GLuint format() const; | |
GLuint uploadFormat() const; | |
GLuint uploadType() const; | |
uint8 pixelSize() const; // this will always be accurate and represent the pixel size on upload (for compressed types... uh, iunno yet TODO) | |
uint8 channelSize() const; // if special or compressed, this is zero | |
uint8 channelCount() const; // this will always be accurate | |
bool isIntegral() const; | |
bool isSigned() const; // TODO: this may not be entirely accurate (are floats signed)? | |
bool isNormalized() const; // TODO: this may not be entirely accurate (are floats normalized)? | |
bool isAttachment() const; // if depth or stencil | |
bool hasDepth() const; | |
bool hasStencil() const; | |
bool isCompressed() const; | |
bool isFilterable() const; | |
private: | |
GLuint m_format; | |
GLuint m_uploadFormat; | |
GLuint m_uploadType; | |
uint32 m_bits; | |
}; | |
namespace { | |
// private namespace | |
const uint32 mChCountShift = 5u; | |
const uint32 mChSizeShift = 8u; | |
const uint32 mSizeMask = 0b00000000'00000000'00011111; | |
const uint32 mChCountMask = 0b00000000'00000000'11100000; | |
const uint32 mChSizeMask = 0b00000000'00000111'00000000; // a channel size of 0 is used for formats where the channels aren't the same size (or are not byte-aligned) | |
const uint32 mIntegral = 0b00000000'00001000'00000000; | |
const uint32 mFloat = 0b00000000'00010000'00000000; | |
const uint32 mSign = 0b00000000'00100000'00000000; | |
const uint32 mDepth = 0b00000000'01000000'00000000; | |
const uint32 mStencil = 0b00000000'10000000'00000000; | |
const uint32 mCompressed = 0b00000001'00000000'00000000; | |
const uint32 mUNTESTED = 0b00000010'00000000'00000000; // using this will write an INFO log, until we remove the tag from below (in theory ensuring we know it works?) | |
const uint32 mDEPRECATED = 0b00000100'00000000'00000000; // use this to trigger a WARN log if the format is used, to remind us to avoid it in the future | |
constexpr uint32 pixel(const uint32 pixelSize, uint32 channelCount, uint32 channelSize) { | |
return pixelSize | channelCount << mChCountShift | channelSize << mChSizeShift; | |
} | |
const Stats m_lut[__count] ={ | |
{ GL_R8 , GL_RED , GL_UNSIGNED_BYTE , pixel( 1, 1, 1 ) | mUNTESTED }, | |
{ GL_RG8 , GL_RG , GL_UNSIGNED_BYTE , pixel( 2, 2, 1 ) | mUNTESTED }, | |
{ GL_RGB8 , GL_RGB , GL_UNSIGNED_BYTE , pixel( 3, 3, 1 ) | mUNTESTED }, | |
{ GL_RGBA8 , GL_RGBA , GL_UNSIGNED_BYTE , pixel( 4, 4, 1 ) | mUNTESTED }, | |
{ GL_R16 , GL_RED , GL_UNSIGNED_SHORT , pixel( 2, 1, 2 ) | mUNTESTED }, | |
{ GL_RG16 , GL_RG , GL_UNSIGNED_SHORT , pixel( 4, 2, 2 ) | mUNTESTED }, | |
{ GL_RGB16 , GL_RGB , GL_UNSIGNED_SHORT , pixel( 6, 3, 2 ) | mUNTESTED }, | |
{ GL_RGBA16 , GL_RGBA , GL_UNSIGNED_SHORT , pixel( 8, 4, 2 ) | mUNTESTED }, | |
{ GL_R8_SNORM , GL_RED , GL_BYTE , pixel( 1, 1, 1 ) | mUNTESTED | mSign }, | |
{ GL_RG8_SNORM , GL_RG , GL_BYTE , pixel( 2, 2, 1 ) | mUNTESTED | mSign }, | |
{ GL_RGB8_SNORM , GL_RGB , GL_BYTE , pixel( 3, 3, 1 ) | mUNTESTED | mSign }, | |
{ GL_RGBA8_SNORM , GL_RGBA , GL_BYTE , pixel( 4, 4, 1 ) | mUNTESTED | mSign }, | |
{ GL_R16_SNORM , GL_RED , GL_SHORT , pixel( 2, 1, 2 ) | mUNTESTED | mSign }, | |
{ GL_RG16_SNORM , GL_RG , GL_SHORT , pixel( 4, 2, 2 ) | mUNTESTED | mSign }, | |
{ GL_RGB16_SNORM , GL_RGB , GL_SHORT , pixel( 6, 3, 2 ) | mUNTESTED | mSign }, | |
{ GL_RGBA16_SNORM , GL_RGBA , GL_SHORT , pixel( 8, 4, 2 ) | mUNTESTED | mSign }, | |
{ GL_R8UI , GL_RED_INTEGER , GL_UNSIGNED_BYTE , pixel( 1, 1, 1 ) | mUNTESTED | mIntegral }, | |
{ GL_RG8UI , GL_RG_INTEGER , GL_UNSIGNED_BYTE , pixel( 2, 2, 1 ) | mUNTESTED | mIntegral }, | |
{ GL_RGB8UI , GL_RGB_INTEGER , GL_UNSIGNED_BYTE , pixel( 3, 3, 1 ) | mUNTESTED | mIntegral }, | |
{ GL_RGBA8UI , GL_RGBA_INTEGER , GL_UNSIGNED_BYTE , pixel( 4, 4, 1 ) | mUNTESTED | mIntegral }, | |
{ GL_R16UI , GL_RED_INTEGER , GL_UNSIGNED_SHORT , pixel( 2, 1, 2 ) | mUNTESTED | mIntegral }, | |
{ GL_RG16UI , GL_RG_INTEGER , GL_UNSIGNED_SHORT , pixel( 4, 2, 2 ) | mUNTESTED | mIntegral }, | |
{ GL_RGB16UI , GL_RGB_INTEGER , GL_UNSIGNED_SHORT , pixel( 6, 3, 2 ) | mUNTESTED | mIntegral }, | |
{ GL_RGBA16UI , GL_RGBA_INTEGER , GL_UNSIGNED_SHORT , pixel( 8, 4, 2 ) | mUNTESTED | mIntegral }, | |
{ GL_R32UI , GL_RED_INTEGER , GL_UNSIGNED_INT , pixel( 4, 1, 4 ) | mUNTESTED | mIntegral }, | |
{ GL_RG32UI , GL_RG_INTEGER , GL_UNSIGNED_INT , pixel( 8, 2, 4 ) | mUNTESTED | mIntegral }, | |
{ GL_RGB32UI , GL_RGB_INTEGER , GL_UNSIGNED_INT , pixel(12, 3, 4 ) | mUNTESTED | mIntegral }, | |
{ GL_RGBA32UI , GL_RGBA_INTEGER , GL_UNSIGNED_INT , pixel(16, 4, 4 ) | mUNTESTED | mIntegral }, | |
{ GL_R8I , GL_RED_INTEGER , GL_BYTE , pixel( 1, 1, 1 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_RG8I , GL_RG_INTEGER , GL_BYTE , pixel( 2, 2, 1 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_RGB8I , GL_RGB_INTEGER , GL_BYTE , pixel( 3, 3, 1 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_RGBA8I , GL_RGBA_INTEGER , GL_BYTE , pixel( 4, 4, 1 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_R16I , GL_RED_INTEGER , GL_SHORT , pixel( 2, 1, 2 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_RG16I , GL_RG_INTEGER , GL_SHORT , pixel( 4, 2, 2 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_RGB16I , GL_RGB_INTEGER , GL_SHORT , pixel( 6, 3, 2 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_RGBA16I , GL_RGBA_INTEGER , GL_SHORT , pixel( 8, 4, 2 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_R32I , GL_RED_INTEGER , GL_INT , pixel( 4, 1, 4 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_RG32I , GL_RG_INTEGER , GL_INT , pixel( 8, 2, 4 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_RGB32I , GL_RGB_INTEGER , GL_INT , pixel(12, 3, 4 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_RGBA32I , GL_RGBA_INTEGER , GL_INT , pixel(16, 4, 4 ) | mUNTESTED | mIntegral | mSign }, | |
{ GL_R16F , GL_RED , GL_HALF_FLOAT , pixel( 2, 1, 2 ) | mUNTESTED | mFloat }, | |
{ GL_RG16F , GL_RG , GL_HALF_FLOAT , pixel( 4, 2, 2 ) | mUNTESTED | mFloat }, | |
{ GL_RGB16F , GL_RGB , GL_HALF_FLOAT , pixel( 6, 3, 2 ) | mUNTESTED | mFloat }, | |
{ GL_RGBA16F , GL_RGBA , GL_HALF_FLOAT , pixel( 8, 4, 2 ) | mUNTESTED | mFloat }, | |
{ GL_R32F , GL_RED , GL_FLOAT , pixel( 4, 1, 4 ) | mUNTESTED | mFloat }, | |
{ GL_RG32F , GL_RG , GL_FLOAT , pixel( 8, 2, 4 ) | mUNTESTED | mFloat }, | |
{ GL_RGB32F , GL_RGB , GL_FLOAT , pixel(12, 3, 4 ) | mUNTESTED | mFloat }, | |
{ GL_RGBA32F , GL_RGBA , GL_FLOAT , pixel(16, 4, 4 ) | mUNTESTED | mFloat }, | |
{ GL_RGB10_A2 , GL_RGBA , GL_UNSIGNED_INT_10_10_10_2 , pixel( 4, 4, 0 ) | mUNTESTED }, | |
{ GL_RGB10_A2UI , GL_RGBA_INTEGER , GL_UNSIGNED_INT_10_10_10_2 , pixel( 4, 4, 0 ) | mUNTESTED | mIntegral }, | |
{ GL_R11F_G11F_B10F , GL_RGB , GL_UNSIGNED_INT_10F_11F_11F_REV , pixel( 4, 3, 0 ) | mUNTESTED | mFloat }, | |
{ GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT , GL_UNSIGNED_SHORT , pixel( 2, 1, 2 ) | mUNTESTED | mDepth }, | |
{ GL_DEPTH_COMPONENT32 , GL_DEPTH_COMPONENT , GL_UNSIGNED_INT , pixel( 4, 1, 4 ) | mUNTESTED | mDepth }, | |
{ GL_DEPTH_COMPONENT32F , GL_DEPTH_COMPONENT , GL_FLOAT , pixel( 4, 1, 4 ) | mUNTESTED | mDepth | mFloat }, | |
{ GL_DEPTH24_STENCIL8 , GL_DEPTH_COMPONENT , GL_UNSIGNED_INT_24_8 , pixel( 4, 2, 0 ) | mUNTESTED | mDepth | mStencil }, | |
{ GL_DEPTH32F_STENCIL8 , GL_DEPTH_COMPONENT , GL_FLOAT_32_UNSIGNED_INT_24_8_REV , pixel( 8, 2, 4 ) | mUNTESTED | mDepth | mStencil }, | |
{ GL_STENCIL_INDEX8 , GL_STENCIL_INDEX , GL_UNSIGNED_BYTE , pixel( 1, 1, 1 ) | mUNTESTED | mIntegral | mStencil }, | |
// I actually don't know what to put here for compressed formats exactly, though it's not like I'll be needing them anyway | |
{ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT , GL_RGBA , 0 , pixel( 4, 4, 0 ) | mUNTESTED|mDEPRECATED | mCompressed }, | |
{ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT , GL_RGBA , 0 , pixel( 4, 4, 0 ) | mUNTESTED|mDEPRECATED | mCompressed }, | |
}; | |
} | |
inline GLuint Stats::format() const { return m_format; } | |
inline GLuint Stats::uploadFormat() const { return m_uploadFormat; } | |
inline GLuint Stats::uploadType() const { return m_uploadType; } | |
inline uint8 Stats::pixelSize() const { return m_bits & mSizeMask; } | |
inline uint8 Stats::channelSize() const { return (m_bits & mChSizeMask) >> mChSizeShift; } | |
inline uint8 Stats::channelCount() const { return (m_bits & mChCountMask) >> mChCountShift;} | |
inline bool Stats::isIntegral() const { return m_bits & mIntegral; } | |
inline bool Stats::isSigned() const { return m_bits & mSign; } | |
inline bool Stats::isNormalized() const { return !isIntegral(); } | |
inline bool Stats::isAttachment() const { return m_bits & (mDepth | mStencil); } | |
inline bool Stats::hasDepth() const { return m_bits & mDepth; } | |
inline bool Stats::hasStencil() const { return m_bits & mStencil; } | |
inline bool Stats::isCompressed() const { return m_bits & mCompressed; } | |
inline bool Stats::isFilterable() const { return !hasStencil() && !isIntegral(); } | |
inline const Stats & LUT(TextureFormat::Type format) { | |
return m_lut[format]; | |
} | |
}; | |
inline const TextureFormat::Stats & operator++(TextureFormat::Type type, int) { | |
// godless | |
return TextureFormat::LUT(type); | |
} | |
inline const TextureFormat::Stats * operator--(TextureFormat::Type type, int) { | |
// godless (funny) | |
return &TextureFormat::LUT(type); | |
} | |
int test() { | |
TextureFormat::LUT(TextureFormat::rgba8).format(); | |
TextureFormat::rgba8++.format(); | |
TextureFormat::rgba8--->format(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment