aboutsummaryrefslogtreecommitdiff
path: root/libs/preview_dds_native/src/ddsformat.h
blob: 22d3565078178be94c58d50a53f12f692210b8a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#ifndef DDSFORMAT_H
#define DDSFORMAT_H

#include <cstdint>
#include <functional>
#include <vector>

#include <QByteArray>

// DDS file magic number
constexpr uint32_t DDS_MAGIC = 0x20534444;  // "DDS "

// DDS_PIXELFORMAT flags
constexpr uint32_t DDPF_ALPHAPIXELS = 0x1;
constexpr uint32_t DDPF_ALPHA       = 0x2;
constexpr uint32_t DDPF_FOURCC      = 0x4;
constexpr uint32_t DDPF_RGB         = 0x40;
constexpr uint32_t DDPF_YUV         = 0x200;
constexpr uint32_t DDPF_LUMINANCE   = 0x20000;

// DDS_HEADER flags
constexpr uint32_t DDSD_CAPS        = 0x1;
constexpr uint32_t DDSD_HEIGHT      = 0x2;
constexpr uint32_t DDSD_WIDTH       = 0x4;
constexpr uint32_t DDSD_PITCH       = 0x8;
constexpr uint32_t DDSD_PIXELFORMAT = 0x1000;
constexpr uint32_t DDSD_MIPMAPCOUNT = 0x20000;
constexpr uint32_t DDSD_LINEARSIZE  = 0x80000;
constexpr uint32_t DDSD_DEPTH       = 0x800000;

// DDS_HEADER caps2
constexpr uint32_t DDSCAPS2_CUBEMAP           = 0x200;
constexpr uint32_t DDSCAPS2_CUBEMAP_POSITIVEX = 0x400;
constexpr uint32_t DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800;
constexpr uint32_t DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000;
constexpr uint32_t DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000;
constexpr uint32_t DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000;
constexpr uint32_t DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000;
constexpr uint32_t DDSCAPS2_VOLUME            = 0x200000;

constexpr uint32_t DDSCAPS2_CUBEMAP_ALLFACES =
    DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_NEGATIVEX |
    DDSCAPS2_CUBEMAP_POSITIVEY | DDSCAPS2_CUBEMAP_NEGATIVEY |
    DDSCAPS2_CUBEMAP_POSITIVEZ | DDSCAPS2_CUBEMAP_NEGATIVEZ;

// DXGI formats (subset covering common DDS textures)
enum class DXGIFormat : uint32_t {
  UNKNOWN                    = 0,
  R32G32B32A32_FLOAT         = 2,
  R32G32B32A32_UINT          = 3,
  R32G32B32A32_SINT          = 4,
  R32G32B32_FLOAT            = 6,
  R32G32B32_UINT             = 7,
  R32G32B32_SINT             = 8,
  R16G16B16A16_FLOAT         = 10,
  R16G16B16A16_UNORM         = 11,
  R16G16B16A16_UINT          = 12,
  R16G16B16A16_SNORM         = 13,
  R16G16B16A16_SINT          = 14,
  R32G32_FLOAT               = 16,
  R32G32_UINT                = 17,
  R32G32_SINT                = 18,
  R10G10B10A2_UNORM          = 24,
  R10G10B10A2_UINT           = 25,
  R11G11B10_FLOAT            = 26,
  R8G8B8A8_UNORM             = 28,
  R8G8B8A8_UNORM_SRGB        = 29,
  R8G8B8A8_UINT              = 30,
  R8G8B8A8_SNORM             = 31,
  R8G8B8A8_SINT              = 32,
  R16G16_FLOAT               = 34,
  R16G16_UNORM               = 35,
  R16G16_UINT                = 36,
  R16G16_SNORM               = 37,
  R16G16_SINT                = 38,
  R32_FLOAT                  = 41,
  R32_UINT                   = 42,
  R32_SINT                   = 43,
  R8G8_UNORM                 = 49,
  R8G8_UINT                  = 50,
  R8G8_SNORM                 = 51,
  R8G8_SINT                  = 52,
  R16_FLOAT                  = 54,
  R16_UNORM                  = 56,
  R16_UINT                   = 57,
  R16_SNORM                  = 58,
  R16_SINT                   = 59,
  R8_UNORM                   = 61,
  R8_UINT                    = 62,
  R8_SNORM                   = 63,
  R8_SINT                    = 64,
  A8_UNORM                   = 65,
  BC1_UNORM                  = 71,
  BC1_UNORM_SRGB             = 72,
  BC2_UNORM                  = 74,
  BC2_UNORM_SRGB             = 75,
  BC3_UNORM                  = 77,
  BC3_UNORM_SRGB             = 78,
  BC4_UNORM                  = 80,
  BC4_SNORM                  = 81,
  BC5_UNORM                  = 83,
  BC5_SNORM                  = 84,
  B5G6R5_UNORM               = 85,
  B5G5R5A1_UNORM             = 86,
  B8G8R8A8_UNORM             = 87,
  B8G8R8X8_UNORM             = 88,
  B8G8R8A8_UNORM_SRGB        = 91,
  B8G8R8X8_UNORM_SRGB        = 93,
  BC6H_UF16                  = 95,
  BC6H_SF16                  = 96,
  BC7_UNORM                  = 98,
  BC7_UNORM_SRGB             = 99,
  B4G4R4A4_UNORM             = 115,
};

// D3D10 resource dimension
enum class D3D10ResourceDimension : uint32_t {
  Unknown   = 0,
  Buffer    = 1,
  Texture1D = 2,
  Texture2D = 3,
  Texture3D = 4,
};

#pragma pack(push, 1)

struct DDSPixelFormat {
  uint32_t dwSize;
  uint32_t dwFlags;
  uint32_t dwFourCC;
  uint32_t dwRGBBitCount;
  uint32_t dwRBitMask;
  uint32_t dwGBitMask;
  uint32_t dwBBitMask;
  uint32_t dwABitMask;
};

struct DDSHeader {
  uint32_t dwSize;
  uint32_t dwFlags;
  uint32_t dwHeight;
  uint32_t dwWidth;
  uint32_t dwPitchOrLinearSize;
  uint32_t dwDepth;
  uint32_t dwMipMapCount;
  uint32_t dwReserved1[11];
  DDSPixelFormat ddspf;
  uint32_t dwCaps;
  uint32_t dwCaps2;
  uint32_t dwCaps3;
  uint32_t dwCaps4;
  uint32_t dwReserved2;
};

struct DDSHeaderDXT10 {
  DXGIFormat dxgiFormat;
  D3D10ResourceDimension resourceDimension;
  uint32_t miscFlag;
  uint32_t arraySize;
  uint32_t miscFlags2;
};

#pragma pack(pop)

// Sampler type for shader selection
enum class SamplerType { Float, UInt, SInt };

// OpenGL format info
struct GLFormatInfo {
  bool valid       = false;
  bool compressed  = false;
  uint32_t internalFormat = 0;
  uint32_t format         = 0;  // only for uncompressed
  uint32_t type           = 0;  // only for uncompressed
  SamplerType sampler     = SamplerType::Float;
  // Optional converter for non-standard bitmask formats
  std::function<QByteArray(const QByteArray&, int, int)> converter;
};

// Inline helper: make a FourCC from 4 chars
constexpr uint32_t makeFourCC(char a, char b, char c, char d)
{
  return static_cast<uint32_t>(a) | (static_cast<uint32_t>(b) << 8) |
         (static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24);
}

// Convert a FourCC code to DXGI format
DXGIFormat fourCCToDXGI(uint32_t fourCC);

// Resolve the OpenGL format from a DDS pixel format + optional DXT10 header
GLFormatInfo getGLFormat(const DDSPixelFormat& pf, const DDSHeaderDXT10* dxt10);

// Calculate mip level data size in bytes
uint32_t mipDataSize(DXGIFormat fmt, const DDSPixelFormat& pf,
                     uint32_t width, uint32_t height);

// Get a human-readable format description
QString formatDescription(const DDSPixelFormat& pf, const DDSHeaderDXT10* dxt10);

#endif  // DDSFORMAT_H