Unravel Engine C++ Reference
Loading...
Searching...
No Matches
format.cpp
Go to the documentation of this file.
1#include "format.h"
2
3namespace gfx
4{
5
6auto get_best_float_format(std::uint16_t type_flags,
7 std::uint32_t search_flags,
8 bool requires_alpha,
9 bool accept_padding,
10 bool accept_half,
11 bool accept_full) -> texture_format
12{
13 if(search_flags & format_search_flags::four_channels)
14 {
15 if(accept_full && is_format_supported(type_flags, texture_format::RGBA32F))
16 return texture_format::RGBA32F;
17 if(accept_half && is_format_supported(type_flags, texture_format::RGBA16F))
18 return texture_format::RGBA16F;
19 }
20 else if(search_flags & format_search_flags::two_channels)
21 {
22 if(!requires_alpha)
23 {
24 if(accept_full && is_format_supported(type_flags, texture_format::RG32F))
25 return texture_format::RG32F;
26 if(accept_half && is_format_supported(type_flags, texture_format::RG16F))
27 return texture_format::RG16F;
28 if(accept_padding && accept_half && is_format_supported(type_flags, texture_format::RGBA16F))
29 return texture_format::RGBA16F;
30 if(accept_padding && accept_full && is_format_supported(type_flags, texture_format::RGBA32F))
31 return texture_format::RGBA32F;
32 }
33 else
34 {
35 if(accept_padding && accept_half && is_format_supported(type_flags, texture_format::RGBA16F))
36 return texture_format::RGBA16F;
37 if(accept_padding && accept_full && is_format_supported(type_flags, texture_format::RGBA32F))
38 return texture_format::RGBA32F;
39 }
40 }
41 else if(search_flags & format_search_flags::one_channel)
42 {
43 if(!requires_alpha)
44 {
45 if(accept_full && is_format_supported(type_flags, texture_format::R32F))
46 return texture_format::R32F;
47 if(accept_half && is_format_supported(type_flags, texture_format::R16F))
48 return texture_format::R16F;
49 if(accept_padding && accept_half && is_format_supported(type_flags, texture_format::RG16F))
50 return texture_format::RG16F;
51 if(accept_padding && accept_full && is_format_supported(type_flags, texture_format::RG32F))
52 return texture_format::RG32F;
53 if(accept_padding && accept_half && is_format_supported(type_flags, texture_format::RGBA16F))
54 return texture_format::RGBA16F;
55 if(accept_padding && accept_full && is_format_supported(type_flags, texture_format::RGBA32F))
56 return texture_format::RGBA32F;
57 }
58 else
59 {
60 if(accept_padding && accept_half && is_format_supported(type_flags, texture_format::RGBA16F))
61 return texture_format::RGBA16F;
62 if(accept_padding && accept_full && is_format_supported(type_flags, texture_format::RGBA32F))
63 return texture_format::RGBA32F;
64 }
65 }
66
67 return texture_format::Unknown;
68}
69
70auto get_best_standard_format(std::uint16_t type_flags,
71 std::uint32_t search_flags,
72 bool requires_alpha,
73 bool accept_padding) -> texture_format
74{
75 if(search_flags & format_search_flags::four_channels)
76 {
77 if(requires_alpha)
78 {
79 if(is_format_supported(type_flags, texture_format::RGBA8))
80 return texture_format::RGBA8;
81 if(is_format_supported(type_flags, texture_format::BGRA8))
82 return texture_format::BGRA8;
83 if(is_format_supported(type_flags, texture_format::RGBA16))
84 return texture_format::RGBA16;
85 if(is_format_supported(type_flags, texture_format::RGB10A2))
86 return texture_format::RGB10A2;
87 if(is_format_supported(type_flags, texture_format::RGB5A1))
88 return texture_format::RGB5A1;
89 }
90 else
91 {
92 if(is_format_supported(type_flags, texture_format::RGBA8))
93 return texture_format::RGBA8;
94 if(is_format_supported(type_flags, texture_format::BGRA8))
95 return texture_format::BGRA8;
96 if(is_format_supported(type_flags, texture_format::RGB8))
97 return texture_format::RGB8;
98 if(is_format_supported(type_flags, texture_format::RGB10A2))
99 return texture_format::RGB10A2;
100 if(is_format_supported(type_flags, texture_format::RGBA16))
101 return texture_format::RGBA16;
102 if(is_format_supported(type_flags, texture_format::R5G6B5))
103 return texture_format::R5G6B5;
104 if(is_format_supported(type_flags, texture_format::RGB5A1))
105 return texture_format::RGB5A1;
106 }
107 }
108 else if(search_flags & format_search_flags::two_channels)
109 {
110 if(!requires_alpha)
111 {
112 if(is_format_supported(type_flags, texture_format::RG16))
113 return texture_format::RG16;
114 if(accept_padding)
115 {
116 if(is_format_supported(type_flags, texture_format::RGB8))
117 return texture_format::RGB8;
118 if(is_format_supported(type_flags, texture_format::RGBA8))
119 return texture_format::RGBA8;
120 if(is_format_supported(type_flags, texture_format::BGRA8))
121 return texture_format::BGRA8;
122 if(is_format_supported(type_flags, texture_format::RGB10A2))
123 return texture_format::RGB10A2;
124 if(is_format_supported(type_flags, texture_format::RGBA16))
125 return texture_format::RGBA16;
126 if(is_format_supported(type_flags, texture_format::R5G6B5))
127 return texture_format::R5G6B5;
128 if(is_format_supported(type_flags, texture_format::RGB5A1))
129 return texture_format::RGB5A1;
130 }
131 }
132 else
133 {
134 if(accept_padding)
135 {
136 if(is_format_supported(type_flags, texture_format::RGBA8))
137 return texture_format::RGBA8;
138 if(is_format_supported(type_flags, texture_format::BGRA8))
139 return texture_format::BGRA8;
140 if(is_format_supported(type_flags, texture_format::RGBA16))
141 return texture_format::RGBA16;
142 if(is_format_supported(type_flags, texture_format::RGB10A2))
143 return texture_format::RGB10A2;
144 if(is_format_supported(type_flags, texture_format::RGB5A1))
145 return texture_format::RGB5A1;
146 }
147 }
148 }
149 else if(search_flags & format_search_flags::one_channel)
150 {
151 if(!requires_alpha)
152 {
153 if(is_format_supported(type_flags, texture_format::R8))
154 return texture_format::R8;
155 if(accept_padding)
156 {
157 if(is_format_supported(type_flags, texture_format::RG16))
158 return texture_format::RG16;
159 if(is_format_supported(type_flags, texture_format::RGB8))
160 return texture_format::RGB8;
161 if(is_format_supported(type_flags, texture_format::RGBA8))
162 return texture_format::RGBA8;
163 if(is_format_supported(type_flags, texture_format::BGRA8))
164 return texture_format::BGRA8;
165 if(is_format_supported(type_flags, texture_format::RGB10A2))
166 return texture_format::RGB10A2;
167 if(is_format_supported(type_flags, texture_format::RGBA16))
168 return texture_format::RGBA16;
169 if(is_format_supported(type_flags, texture_format::R5G6B5))
170 return texture_format::R5G6B5;
171 if(is_format_supported(type_flags, texture_format::RGB5A1))
172 return texture_format::RGB5A1;
173 }
174 }
175 else
176 {
177 if(is_format_supported(type_flags, texture_format::A8))
178 return texture_format::A8;
179 if(accept_padding)
180 {
181 if(is_format_supported(type_flags, texture_format::RGBA8))
182 return texture_format::RGBA8;
183 if(is_format_supported(type_flags, texture_format::BGRA8))
184 return texture_format::BGRA8;
185 if(is_format_supported(type_flags, texture_format::RGBA16))
186 return texture_format::RGBA16;
187 if(is_format_supported(type_flags, texture_format::RGB10A2))
188 return texture_format::RGB10A2;
189 if(is_format_supported(type_flags, texture_format::RGB5A1))
190 return texture_format::RGB5A1;
191 }
192 }
193 }
194
195 return texture_format::Unknown;
196}
197
198auto get_best_depth_format(std::uint16_t type_flags, std::uint32_t search_flags) -> texture_format
199{
200 bool requires_stencil = (search_flags & format_search_flags::requires_stencil) != 0;
201 bool accept_full = (search_flags & format_search_flags::full_precision_float) != 0;
202
203 if(search_flags & format_search_flags::floating_point)
204 {
205 if(!requires_stencil)
206 {
207 if(accept_full && is_format_supported(type_flags, texture_format::D32F))
208 return texture_format::D32F;
209 if(accept_full && is_format_supported(type_flags, texture_format::D24F))
210 return texture_format::D24F;
211 }
212 }
213 else
214 {
215 if(!requires_stencil)
216 {
217 if(is_format_supported(type_flags, texture_format::D32))
218 return texture_format::D32;
219 if(is_format_supported(type_flags, texture_format::D24))
220 return texture_format::D24;
221 if(is_format_supported(type_flags, texture_format::D16))
222 return texture_format::D16;
223 }
224 else
225 {
226 if(is_format_supported(type_flags, texture_format::D24S8))
227 return texture_format::D24S8;
228 }
229 }
230
231 return texture_format::Unknown;
232}
233
234auto get_best_format(std::uint16_t type_flags, std::uint32_t search_flags) -> texture_format
235{
236 bool is_depth = (search_flags & format_search_flags::requires_depth) != 0;
237 bool requires_alpha = (search_flags & format_search_flags::requires_alpha) != 0;
238 bool accept_padding = (search_flags & format_search_flags::allow_padding_channels) != 0;
239 bool accept_half = (search_flags & format_search_flags::half_precision_float) != 0;
240 bool accept_full = (search_flags & format_search_flags::full_precision_float) != 0;
241
242 if(!is_depth)
243 {
244 if((search_flags & format_search_flags::prefer_compressed) &&
246 {
247 if(requires_alpha)
248 {
249 if(is_format_supported(type_flags, texture_format::BC2))
250 return texture_format::BC2;
251 if(is_format_supported(type_flags, texture_format::BC3))
252 return texture_format::BC3;
253 }
254 else
255 {
256 if(is_format_supported(type_flags, texture_format::BC1))
257 return texture_format::BC1;
258 }
259 }
260
261 if(search_flags & format_search_flags::floating_point)
262 {
263 return get_best_float_format(type_flags,
264 search_flags,
265 requires_alpha,
266 accept_padding,
267 accept_half,
268 accept_full);
269 }
270 else
271 {
272 return get_best_standard_format(type_flags, search_flags, requires_alpha, accept_padding);
273 }
274 }
275 else
276 {
277 return get_best_depth_format(type_flags, search_flags);
278 }
279
280 return texture_format::Unknown;
281}
282
284{
285 static std::uint64_t sampler_flags = 0 | BGFX_TEXTURE_RT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
286
287 return sampler_flags;
288}
289
290auto is_format_supported(uint16_t flags, texture_format format) -> bool
291{
292 const std::uint32_t formatCaps = bgfx::getCaps()->formats[format];
293 return 0 != (formatCaps & flags);
294}
295
297{
298 switch(fmt)
299 {
300 // --- Common BC formats ---
301 case texture_format::BC1: // DXT1
302 // Typically 3 channels (RGB), can do 1-bit alpha, but we ignore that here.
303 return {false, false, 3};
304 case texture_format::BC2: // DXT3
305 // Explicit alpha
306 return {true, false, 4};
307 case texture_format::BC3: // DXT5
308 // Interpolated alpha
309 return {true, false, 4};
310 case texture_format::BC4: // LATC1 / ATI1
311 // Single channel
312 return {false, false, 1};
313 case texture_format::BC5: // LATC2 / ATI2
314 // Two-channel, often used for XY in normal maps
315 return {false, false, 2};
316 case texture_format::BC6H:
317 // HDR (RGB only), no alpha
318 return {false, true, 3};
319 case texture_format::BC7:
320 // More advanced block compression for RGBA
321 return {true, false, 4};
322
323 // --- Common uncompressed “RGBA” forms you might care about ---
324 case texture_format::RGBA8:
325 case texture_format::BGRA8:
326 case texture_format::RGBA8I:
327 case texture_format::RGBA8U:
328 case texture_format::RGBA8S:
329 case texture_format::RGBA16:
330 case texture_format::RGBA16I:
331 case texture_format::RGBA16U:
332 // 4 channels, 8-16 bits. Not HDR by default unless floating.
333 return {true, false, 4};
334
335 // Float-based RGBA => can be HDR
336 case texture_format::RGBA16F:
337 case texture_format::RGBA32F:
338 // 4 channels, floating point
339 return {true, true, 4};
340
341 // Similarly, if you commonly use some other uncompressed formats:
342 case texture_format::RGB8:
343 return {false, false, 3};
344 case texture_format::R8:
345 case texture_format::R16:
346 case texture_format::R16F:
347 case texture_format::R32F:
348 // Single channel, might or might not be HDR:
349 // R16F / R32F is single-channel float => isHdr = true
350 switch(fmt)
351 {
352 case texture_format::R16F:
353 case texture_format::R32F:
354 return {false, true, 1};
355 default:
356 return {false, false, 1};
357 }
358
359 case texture_format::RG8:
360 case texture_format::RG16:
361 // 2 channels, integer, not HDR
362 return {false, false, 2};
363 case texture_format::RG16F:
364 case texture_format::RG32F:
365 // 2 channels, float => HDR
366 return {false, true, 2};
367
368 // ... etc. Add more if needed for your typical usage.
369
370 default:
371 // For depth formats, rarely used/unknown formats, fallback.
372 // Depth is definitely not alpha or typical color data:
373 // Or if you're ignoring them, just do:
374 return {false, false, 3}; // e.g., default to “no alpha, no HDR, 3 channels”
375 }
376}
377
378auto to_string(texture_format fmt) -> std::string
379{
380 switch (fmt)
381 {
382 case texture_format::BC1: return "BC1";
383 case texture_format::BC2: return "BC2";
384 case texture_format::BC3: return "BC3";
385 case texture_format::BC4: return "BC4";
386 case texture_format::BC5: return "BC5";
387 case texture_format::BC6H: return "BC6H";
388 case texture_format::BC7: return "BC7";
389 case texture_format::ETC1: return "ETC1";
390 case texture_format::ETC2: return "ETC2";
391 case texture_format::ETC2A: return "ETC2A";
392 case texture_format::ETC2A1: return "ETC2A1";
393 case texture_format::PTC12: return "PTC12";
394 case texture_format::PTC14: return "PTC14";
395 case texture_format::PTC12A: return "PTC12A";
396 case texture_format::PTC14A: return "PTC14A";
397 case texture_format::PTC22: return "PTC22";
398 case texture_format::PTC24: return "PTC24";
399 case texture_format::ATC: return "ATC";
400 case texture_format::ATCE: return "ATCE";
401 case texture_format::ATCI: return "ATCI";
402 case texture_format::ASTC4x4: return "ASTC4x4";
403 case texture_format::ASTC5x4: return "ASTC5x4";
404 case texture_format::ASTC5x5: return "ASTC5x5";
405 case texture_format::ASTC6x5: return "ASTC6x5";
406 case texture_format::ASTC6x6: return "ASTC6x6";
407 case texture_format::ASTC8x5: return "ASTC8x5";
408 case texture_format::ASTC8x6: return "ASTC8x6";
409 case texture_format::ASTC8x8: return "ASTC8x8";
410 case texture_format::ASTC10x5: return "ASTC10x5";
411 case texture_format::ASTC10x6: return "ASTC10x6";
412 case texture_format::ASTC10x8: return "ASTC10x8";
413 case texture_format::ASTC10x10: return "ASTC10x10";
414 case texture_format::ASTC12x10: return "ASTC12x10";
415 case texture_format::ASTC12x12: return "ASTC12x12";
416
417 case texture_format::Unknown: return "Unknown";
418
419 case texture_format::R1: return "R1";
420 case texture_format::A8: return "A8";
421 case texture_format::R8: return "R8";
422 case texture_format::R8I: return "R8I";
423 case texture_format::R8U: return "R8U";
424 case texture_format::R8S: return "R8S";
425 case texture_format::R16: return "R16";
426 case texture_format::R16I: return "R16I";
427 case texture_format::R16U: return "R16U";
428 case texture_format::R16F: return "R16F";
429 case texture_format::R16S: return "R16S";
430 case texture_format::R32I: return "R32I";
431 case texture_format::R32U: return "R32U";
432 case texture_format::R32F: return "R32F";
433 case texture_format::RG8: return "RG8";
434 case texture_format::RG8I: return "RG8I";
435 case texture_format::RG8U: return "RG8U";
436 case texture_format::RG8S: return "RG8S";
437 case texture_format::RG16: return "RG16";
438 case texture_format::RG16I: return "RG16I";
439 case texture_format::RG16U: return "RG16U";
440 case texture_format::RG16F: return "RG16F";
441 case texture_format::RG16S: return "RG16S";
442 case texture_format::RG32I: return "RG32I";
443 case texture_format::RG32U: return "RG32U";
444 case texture_format::RG32F: return "RG32F";
445 case texture_format::RGB8: return "RGB8";
446 case texture_format::RGB8I: return "RGB8I";
447 case texture_format::RGB8U: return "RGB8U";
448 case texture_format::RGB8S: return "RGB8S";
449 case texture_format::RGB9E5F: return "RGB9E5F";
450 case texture_format::BGRA8: return "BGRA8";
451 case texture_format::RGBA8: return "RGBA8";
452 case texture_format::RGBA8I: return "RGBA8I";
453 case texture_format::RGBA8U: return "RGBA8U";
454 case texture_format::RGBA8S: return "RGBA8S";
455 case texture_format::RGBA16: return "RGBA16";
456 case texture_format::RGBA16I: return "RGBA16I";
457 case texture_format::RGBA16U: return "RGBA16U";
458 case texture_format::RGBA16F: return "RGBA16F";
459 case texture_format::RGBA16S: return "RGBA16S";
460 case texture_format::RGBA32I: return "RGBA32I";
461 case texture_format::RGBA32U: return "RGBA32U";
462 case texture_format::RGBA32F: return "RGBA32F";
463 case texture_format::B5G6R5: return "B5G6R5";
464 case texture_format::R5G6B5: return "R5G6B5";
465 case texture_format::BGRA4: return "BGRA4";
466 case texture_format::RGBA4: return "RGBA4";
467 case texture_format::BGR5A1: return "BGR5A1";
468 case texture_format::RGB5A1: return "RGB5A1";
469 case texture_format::RGB10A2: return "RGB10A2";
470 case texture_format::RG11B10F: return "RG11B10F";
471
472 case texture_format::UnknownDepth: return "UnknownDepth";
473
474 case texture_format::D16: return "D16";
475 case texture_format::D24: return "D24";
476 case texture_format::D24S8: return "D24S8";
477 case texture_format::D32: return "D32";
478 case texture_format::D16F: return "D16F";
479 case texture_format::D24F: return "D24F";
480 case texture_format::D32F: return "D32F";
481 case texture_format::D0S8: return "D0S8";
482
483 case texture_format::Count: return "Count";
484
485 default:
486 // If somehow it doesn't match any known enumerator
487 return "Unknown";
488 }
489}
490
491} // namespace gfx
auto to_string(texture_format fmt) -> std::string
Definition format.cpp:378
auto is_format_supported(uint16_t flags, texture_format format) -> bool
Definition format.cpp:290
bgfx::TextureFormat::Enum texture_format
Definition format.h:10
auto get_best_standard_format(std::uint16_t type_flags, std::uint32_t search_flags, bool requires_alpha, bool accept_padding) -> texture_format
Definition format.cpp:70
auto get_best_depth_format(std::uint16_t type_flags, std::uint32_t search_flags) -> texture_format
Definition format.cpp:198
auto get_best_float_format(std::uint16_t type_flags, std::uint32_t search_flags, bool requires_alpha, bool accept_padding, bool accept_half, bool accept_full) -> texture_format
Definition format.cpp:6
auto get_format_info(texture_format fmt) -> format_details
Definition format.cpp:296
auto get_default_rt_sampler_flags() -> uint64_t
Definition format.cpp:283
auto get_best_format(std::uint16_t type_flags, std::uint32_t search_flags) -> texture_format
Definition format.cpp:234