Skip to content

Instantly share code, notes, and snippets.

@Quackward
Last active December 28, 2021 11:51
Show Gist options
  • Save Quackward/af9506572aee751214b778d7e268371d to your computer and use it in GitHub Desktop.
Save Quackward/af9506572aee751214b778d7e268371d to your computer and use it in GitHub Desktop.
check out the bottom for a lovely surprise
#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