1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "BsGLPixelFormat.h"
4#include "RenderAPI/BsRenderAPI.h"
5#include "Utility/BsBitwise.h"
6#include "Debug/BsDebug.h"
7
8namespace bs { namespace ct
9{
10 PixelFormat GLPixelUtil::getClosestSupportedPF(PixelFormat format, TextureType texType, int usage)
11 {
12 // Check for any obvious issues first
13 PixelUtil::checkFormat(format, texType, usage);
14
15 // We don't check for any platform-specific format issues, assumed all are supported
16 return format;
17 }
18
19 GLenum GLPixelUtil::getGLOriginFormat(PixelFormat format)
20 {
21 switch (format)
22 {
23 case PF_R8:
24 case PF_R8S:
25 return GL_RED;
26 case PF_R8I:
27 case PF_R8U:
28 return GL_RED_INTEGER;
29 case PF_RG8:
30 case PF_RG8S:
31 return GL_RG;
32 case PF_RG8I:
33 case PF_RG8U:
34 return GL_RG_INTEGER;
35 case PF_RGB8:
36 return GL_RGB;
37 case PF_BGR8:
38 return GL_BGR;
39 case PF_RGBA8:
40 case PF_RGBA8S:
41 return GL_RGBA;
42 case PF_RGBA8I:
43 case PF_RGBA8U:
44 return GL_RGBA_INTEGER;
45 case PF_BGRA8:
46 return GL_BGRA;
47 case PF_R16F:
48 case PF_R16S:
49 case PF_R16:
50 return GL_RED;
51 case PF_R16I:
52 case PF_R16U:
53 return GL_RED_INTEGER;
54 case PF_RG16F:
55 case PF_RG16S:
56 case PF_RG16:
57 return GL_RG;
58 case PF_RG16I:
59 case PF_RG16U:
60 return GL_RG_INTEGER;
61 case PF_RGBA16F:
62 case PF_RGBA16S:
63 case PF_RGBA16:
64 return GL_RGBA;
65 case PF_RGBA16I:
66 case PF_RGBA16U:
67 return GL_RGBA_INTEGER;
68 case PF_R32F:
69 return GL_RED;
70 case PF_R32I:
71 case PF_R32U:
72 return GL_RED_INTEGER;
73 case PF_RG32F:
74 return GL_RG;
75 case PF_RG32I:
76 case PF_RG32U:
77 return GL_RG_INTEGER;
78 case PF_RGB32F:
79 return GL_RGB;
80 case PF_RGB32I:
81 case PF_RGB32U:
82 return GL_RGB_INTEGER;
83 case PF_RGBA32F:
84 return GL_RGBA;
85 case PF_RGBA32I:
86 case PF_RGBA32U:
87 return GL_RGBA_INTEGER;
88 case PF_RG11B10F:
89 return GL_RGB;
90 case PF_RGB10A2:
91 return GL_RGBA;
92 case PF_BC1:
93 case PF_BC1a:
94 case PF_BC3:
95 case PF_BC7:
96 return GL_RGBA;
97 case PF_BC4:
98 return GL_RED;
99 case PF_BC5:
100 return GL_RG;
101 case PF_BC6H:
102 return GL_RGB;
103 default:
104 return 0;
105 }
106 }
107
108 GLenum GLPixelUtil::getGLOriginDataType(PixelFormat format)
109 {
110 switch (format)
111 {
112 case PF_R8:
113 case PF_RG8:
114 case PF_RGB8:
115 case PF_BGR8:
116 case PF_R8U:
117 case PF_RG8U:
118 case PF_RGBA8U:
119 return GL_UNSIGNED_BYTE;
120 case PF_BGRA8:
121 case PF_RGBA8:
122 return GL_UNSIGNED_INT_8_8_8_8_REV;
123 case PF_R8I:
124 case PF_RG8I:
125 case PF_RGBA8I:
126 case PF_R8S:
127 case PF_RG8S:
128 case PF_RGBA8S:
129 return GL_BYTE;
130 case PF_R16I:
131 case PF_RG16I:
132 case PF_RGBA16I:
133 case PF_R16S:
134 case PF_RG16S:
135 case PF_RGBA16S:
136 return GL_SHORT;
137 case PF_R16:
138 case PF_RG16:
139 case PF_RGBA16:
140 case PF_R16U:
141 case PF_RG16U:
142 case PF_RGBA16U:
143 return GL_UNSIGNED_SHORT;
144 case PF_R16F:
145 case PF_RG16F:
146 case PF_RGBA16F:
147 return GL_HALF_FLOAT;
148 case PF_R32I:
149 case PF_RG32I:
150 case PF_RGB32I:
151 case PF_RGBA32I:
152 return GL_INT;
153 case PF_R32U:
154 case PF_RG32U:
155 case PF_RGB32U:
156 case PF_RGBA32U:
157 return GL_UNSIGNED_INT;
158 case PF_R32F:
159 case PF_RG32F:
160 case PF_RGB32F:
161 case PF_RGBA32F:
162 return GL_FLOAT;
163 case PF_RG11B10F:
164 return GL_UNSIGNED_INT_10F_11F_11F_REV;
165 case PF_RGB10A2:
166 return GL_UNSIGNED_INT_2_10_10_10_REV;
167 default:
168 return 0;
169 }
170 }
171
172 GLenum GLPixelUtil::getGLInternalFormat(PixelFormat format, bool hwGamma)
173 {
174 switch (format)
175 {
176 case PF_R8:
177 return GL_R8;
178 case PF_R8I:
179 return GL_R8I;
180 case PF_R8U:
181 return GL_R8UI;
182 case PF_R8S:
183 return GL_R8_SNORM;
184 case PF_RG8:
185 return GL_RG8;
186 case PF_RG8I:
187 return GL_RG8I;
188 case PF_RG8U:
189 return GL_RG8UI;
190 case PF_RG8S:
191 return GL_RG8_SNORM;
192 case PF_RGB8:
193 case PF_BGR8:
194 if (hwGamma)
195 return GL_SRGB8;
196 else
197 return GL_RGB8;
198 case PF_BGRA8:
199 case PF_RGBA8:
200 if (hwGamma)
201 return GL_SRGB8_ALPHA8;
202 else
203 return GL_RGBA8;
204 case PF_RGBA8I:
205 return GL_RGBA8I;
206 case PF_RGBA8U:
207 return GL_RGBA8UI;
208 case PF_RGBA8S:
209 return GL_RGBA8_SNORM;
210 case PF_R16F:
211 return GL_R16F;
212 case PF_R16I:
213 return GL_R16I;
214 case PF_R16U:
215 return GL_R16UI;
216 case PF_R16S:
217 return GL_R16_SNORM;
218 case PF_R16:
219 return GL_R16;
220 case PF_RG16F:
221 return GL_RG16F;
222 case PF_RG16I:
223 return GL_RG16I;
224 case PF_RG16U:
225 return GL_RG16UI;
226 case PF_RG16S:
227 return GL_RG16_SNORM;
228 case PF_RG16:
229 return GL_RG16;
230 case PF_RGBA16F:
231 return GL_RGBA16F;
232 case PF_RGBA16I:
233 return GL_RGBA16I;
234 case PF_RGBA16U:
235 return GL_RGBA16UI;
236 case PF_RGBA16S:
237 return GL_RGBA16_SNORM;
238 case PF_RGBA16:
239 return GL_RGBA16;
240 case PF_R32F:
241 return GL_R32F;
242 case PF_R32I:
243 return GL_R32I;
244 case PF_R32U:
245 return GL_R32UI;
246 case PF_RG32F:
247 return GL_RG32F;
248 case PF_RG32I:
249 return GL_RG32I;
250 case PF_RG32U:
251 return GL_RG32UI;
252 case PF_RGB32F:
253 return GL_RGB32F;
254 case PF_RGB32I:
255 return GL_RGB32I;
256 case PF_RGB32U:
257 return GL_RGB32UI;
258 case PF_RGBA32F:
259 return GL_RGBA32F;
260 case PF_RGBA32I:
261 return GL_RGBA32I;
262 case PF_RGBA32U:
263 return GL_RGBA32UI;
264#if BS_OPENGL_4_1
265 case PF_BC1a:
266 case PF_BC1:
267 if (hwGamma)
268 return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
269 else
270 return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
271 case PF_BC2:
272 if (hwGamma)
273 return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
274 else
275 return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
276 case PF_BC3:
277 if (hwGamma)
278 return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
279 else
280 return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
281 case PF_BC4:
282 return GL_COMPRESSED_RED_RGTC1;
283 case PF_BC5:
284 return GL_COMPRESSED_RG_RGTC2;
285#endif
286#if BS_OPENGL_4_2
287 case PF_BC6H:
288 return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
289 case PF_BC7:
290 if (hwGamma)
291 return GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
292 else
293 return GL_COMPRESSED_RGBA_BPTC_UNORM;
294#endif
295 case PF_D16:
296 return GL_DEPTH_COMPONENT16;
297 case PF_D32:
298 return GL_DEPTH_COMPONENT32F;
299 case PF_D24S8:
300 return GL_DEPTH24_STENCIL8;
301 case PF_D32_S8X24:
302 return GL_DEPTH32F_STENCIL8;
303 case PF_RG11B10F:
304 return GL_R11F_G11F_B10F;
305 case PF_RGB10A2:
306 return GL_RGB10_A2;
307 default:
308 return GL_NONE;
309 }
310 }
311
312 GLenum GLPixelUtil::getDepthStencilTypeFromPF(PixelFormat format)
313 {
314 switch(format)
315 {
316 case PF_D32_S8X24:
317 return GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
318 case PF_D24S8:
319 return GL_UNSIGNED_INT_24_8;
320 case PF_D32:
321 return GL_FLOAT;
322 case PF_D16:
323 return GL_UNSIGNED_SHORT;
324 default:
325 break;
326 }
327
328 LOGERR("Invalid depth stencil format");
329 return PF_D32_S8X24;
330 }
331
332 GLenum GLPixelUtil::getDepthStencilFormatFromPF(PixelFormat format)
333 {
334 switch (format)
335 {
336 case PF_D32_S8X24:
337 return GL_DEPTH_STENCIL;
338 case PF_D24S8:
339 return GL_DEPTH_STENCIL;
340 case PF_D32:
341 return GL_DEPTH_COMPONENT;
342 case PF_D16:
343 return GL_DEPTH_COMPONENT;
344 default:
345 break;
346 }
347
348 LOGERR("Invalid depth stencil format");
349 return GL_DEPTH_STENCIL;
350 }
351
352 GLenum GLPixelUtil::getBufferFormat(GpuBufferFormat format)
353 {
354 static bool lookupInitialized = false;
355
356 static GLenum lookup[BF_COUNT];
357 if (!lookupInitialized)
358 {
359 lookup[BF_16X1F] = GL_R16F;
360 lookup[BF_16X2F] = GL_RG16F;
361 lookup[BF_16X4F] = GL_RGBA16F;
362 lookup[BF_32X1F] = GL_R32F;
363 lookup[BF_32X2F] = GL_RG32F;
364 lookup[BF_32X3F] = GL_RGB32F;
365 lookup[BF_32X4F] = GL_RGBA32F;
366 lookup[BF_8X1] = GL_R8;
367 lookup[BF_8X2] = GL_RG8;
368 lookup[BF_8X4] = GL_RGBA8;
369 lookup[BF_16X1] = GL_R16;
370 lookup[BF_16X2] = GL_RG16;
371 lookup[BF_16X4] = GL_RGBA16;
372 lookup[BF_8X1S] = GL_R8I;
373 lookup[BF_8X2S] = GL_RG8I;
374 lookup[BF_8X4S] = GL_RGBA8I;
375 lookup[BF_16X1S] = GL_R16I;
376 lookup[BF_16X2S] = GL_RG16I;
377 lookup[BF_16X4S] = GL_RGBA16I;
378 lookup[BF_32X1S] = GL_R32I;
379 lookup[BF_32X2S] = GL_RG32I;
380 lookup[BF_32X3S] = GL_RGB32I;
381 lookup[BF_32X4S] = GL_RGBA32I;
382 lookup[BF_8X1U] = GL_R8UI;
383 lookup[BF_8X2U] = GL_RG8UI;
384 lookup[BF_8X4U] = GL_RGBA8UI;
385 lookup[BF_16X1U] = GL_R16UI;
386 lookup[BF_16X2U] = GL_RG16UI;
387 lookup[BF_16X4U] = GL_RGBA16UI;
388 lookup[BF_32X1U] = GL_R32UI;
389 lookup[BF_32X2U] = GL_RG32UI;
390 lookup[BF_32X3U] = GL_RGB32UI;
391 lookup[BF_32X4U] = GL_RGBA32UI;
392
393 lookupInitialized = true;
394 }
395
396 if (format >= BF_COUNT)
397 return GL_NONE;
398
399 return lookup[(UINT32)format];
400 }
401}}