1// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "Image.hpp"
16
17#include "../libEGL/Texture.hpp"
18#include "../common/debug.h"
19#include "Common/Math.hpp"
20#include "Common/Thread.hpp"
21
22#include <GLES3/gl3.h>
23
24#include <string.h>
25#include <algorithm>
26
27#if defined(__APPLE__)
28#include <CoreFoundation/CoreFoundation.h>
29#include <IOSurface/IOSurface.h>
30#endif
31
32namespace gl
33{
34 bool IsUnsizedInternalFormat(GLint internalformat)
35 {
36 switch(internalformat)
37 {
38 case GL_ALPHA:
39 case GL_LUMINANCE:
40 case GL_LUMINANCE_ALPHA:
41 case GL_RED:
42 case GL_RG:
43 case GL_RGB:
44 case GL_RGBA:
45 case GL_RED_INTEGER:
46 case GL_RG_INTEGER:
47 case GL_RGB_INTEGER:
48 case GL_RGBA_INTEGER:
49 case GL_BGRA_EXT:
50 case GL_DEPTH_COMPONENT:
51 case GL_DEPTH_STENCIL:
52 // GL_EXT_sRGB
53 // case GL_SRGB_EXT:
54 // case GL_SRGB_ALPHA_EXT:
55 return true;
56 default:
57 return false;
58 }
59 }
60
61 GLenum GetBaseInternalFormat(GLint internalformat)
62 {
63 switch(internalformat)
64 {
65 // [OpenGL ES 3.0 Table 3.13]
66 case GL_R8: return GL_RED;
67 case GL_R8_SNORM: return GL_RED;
68 case GL_RG8: return GL_RG;
69 case GL_RG8_SNORM: return GL_RG;
70 case GL_RGB8: return GL_RGB;
71 case GL_RGB8_SNORM: return GL_RGB;
72 case GL_RGB565: return GL_RGB;
73 case GL_RGBA4: return GL_RGBA;
74 case GL_RGB5_A1: return GL_RGBA;
75 case GL_RGBA8: return GL_RGBA;
76 case GL_RGBA8_SNORM: return GL_RGBA;
77 case GL_RGB10_A2: return GL_RGBA;
78 case GL_RGB10_A2UI: return GL_RGBA;
79 case GL_SRGB8: return GL_RGB;
80 case GL_SRGB8_ALPHA8: return GL_RGBA;
81 case GL_R16F: return GL_RED;
82 case GL_RG16F: return GL_RG;
83 case GL_RGB16F: return GL_RGB;
84 case GL_RGBA16F: return GL_RGBA;
85 case GL_R32F: return GL_RED;
86 case GL_RG32F: return GL_RG;
87 case GL_RGB32F: return GL_RGB;
88 case GL_RGBA32F: return GL_RGBA;
89 case GL_R11F_G11F_B10F: return GL_RGB;
90 case GL_RGB9_E5: return GL_RGB;
91 case GL_R8I: return GL_RED;
92 case GL_R8UI: return GL_RED;
93 case GL_R16I: return GL_RED;
94 case GL_R16UI: return GL_RED;
95 case GL_R32I: return GL_RED;
96 case GL_R32UI: return GL_RED;
97 case GL_RG8I: return GL_RG;
98 case GL_RG8UI: return GL_RG;
99 case GL_RG16I: return GL_RG;
100 case GL_RG16UI: return GL_RG;
101 case GL_RG32I: return GL_RG;
102 case GL_RG32UI: return GL_RG;
103 case GL_RGB8I: return GL_RGB;
104 case GL_RGB8UI: return GL_RGB;
105 case GL_RGB16I: return GL_RGB;
106 case GL_RGB16UI: return GL_RGB;
107 case GL_RGB32I: return GL_RGB;
108 case GL_RGB32UI: return GL_RGB;
109 case GL_RGBA8I: return GL_RGBA;
110 case GL_RGBA8UI: return GL_RGBA;
111 case GL_RGBA16I: return GL_RGBA;
112 case GL_RGBA16UI: return GL_RGBA;
113 case GL_RGBA32I: return GL_RGBA;
114 case GL_RGBA32UI: return GL_RGBA;
115
116 // GL_EXT_texture_storage
117 case GL_ALPHA8_EXT: return GL_ALPHA;
118 case GL_LUMINANCE8_EXT: return GL_LUMINANCE;
119 case GL_LUMINANCE8_ALPHA8_EXT: return GL_LUMINANCE_ALPHA;
120 case GL_ALPHA32F_EXT: return GL_ALPHA;
121 case GL_LUMINANCE32F_EXT: return GL_LUMINANCE;
122 case GL_LUMINANCE_ALPHA32F_EXT: return GL_LUMINANCE_ALPHA;
123 case GL_ALPHA16F_EXT: return GL_ALPHA;
124 case GL_LUMINANCE16F_EXT: return GL_LUMINANCE;
125 case GL_LUMINANCE_ALPHA16F_EXT: return GL_LUMINANCE_ALPHA;
126
127 case GL_BGRA8_EXT: return GL_BGRA_EXT; // GL_APPLE_texture_format_BGRA8888
128
129 case GL_DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT;
130 case GL_DEPTH_COMPONENT32_OES: return GL_DEPTH_COMPONENT;
131 case GL_DEPTH_COMPONENT32F: return GL_DEPTH_COMPONENT;
132 case GL_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT;
133 case GL_DEPTH32F_STENCIL8: return GL_DEPTH_STENCIL;
134 case GL_DEPTH24_STENCIL8: return GL_DEPTH_STENCIL;
135 case GL_STENCIL_INDEX8: return GL_STENCIL_INDEX_OES;
136 default:
137 UNREACHABLE(internalformat);
138 break;
139 }
140
141 return GL_NONE;
142 }
143
144 GLint GetSizedInternalFormat(GLint internalformat, GLenum type)
145 {
146 if(!IsUnsizedInternalFormat(internalformat))
147 {
148 return internalformat;
149 }
150
151 switch(internalformat)
152 {
153 case GL_RGBA:
154 switch(type)
155 {
156 case GL_UNSIGNED_BYTE: return GL_RGBA8;
157 case GL_BYTE: return GL_RGBA8_SNORM;
158 case GL_UNSIGNED_SHORT_4_4_4_4: return GL_RGBA4;
159 case GL_UNSIGNED_SHORT_5_5_5_1: return GL_RGB5_A1;
160 case GL_UNSIGNED_INT_2_10_10_10_REV: return GL_RGB10_A2;
161 case GL_FLOAT: return GL_RGBA32F;
162 case GL_HALF_FLOAT: return GL_RGBA16F;
163 case GL_HALF_FLOAT_OES: return GL_RGBA16F;
164 default: UNREACHABLE(type); return GL_NONE;
165 }
166 case GL_RGBA_INTEGER:
167 switch(type)
168 {
169 case GL_UNSIGNED_BYTE: return GL_RGBA8UI;
170 case GL_BYTE: return GL_RGBA8I;
171 case GL_UNSIGNED_SHORT: return GL_RGBA16UI;
172 case GL_SHORT: return GL_RGBA16I;
173 case GL_UNSIGNED_INT: return GL_RGBA32UI;
174 case GL_INT: return GL_RGBA32I;
175 case GL_UNSIGNED_INT_2_10_10_10_REV: return GL_RGB10_A2UI;
176 default: UNREACHABLE(type); return GL_NONE;
177 }
178 case GL_RGB:
179 switch(type)
180 {
181 case GL_UNSIGNED_BYTE: return GL_RGB8;
182 case GL_BYTE: return GL_RGB8_SNORM;
183 case GL_UNSIGNED_SHORT_5_6_5: return GL_RGB565;
184 case GL_UNSIGNED_INT_10F_11F_11F_REV: return GL_R11F_G11F_B10F;
185 case GL_UNSIGNED_INT_5_9_9_9_REV: return GL_RGB9_E5;
186 case GL_FLOAT: return GL_RGB32F;
187 case GL_HALF_FLOAT: return GL_RGB16F;
188 case GL_HALF_FLOAT_OES: return GL_RGB16F;
189 default: UNREACHABLE(type); return GL_NONE;
190 }
191 case GL_RGB_INTEGER:
192 switch(type)
193 {
194 case GL_UNSIGNED_BYTE: return GL_RGB8UI;
195 case GL_BYTE: return GL_RGB8I;
196 case GL_UNSIGNED_SHORT: return GL_RGB16UI;
197 case GL_SHORT: return GL_RGB16I;
198 case GL_UNSIGNED_INT: return GL_RGB32UI;
199 case GL_INT: return GL_RGB32I;
200 default: UNREACHABLE(type); return GL_NONE;
201 }
202 case GL_RG:
203 switch(type)
204 {
205 case GL_UNSIGNED_BYTE: return GL_RG8;
206 case GL_BYTE: return GL_RG8_SNORM;
207 case GL_FLOAT: return GL_RG32F;
208 case GL_HALF_FLOAT: return GL_RG16F;
209 case GL_HALF_FLOAT_OES: return GL_RG16F;
210 default: UNREACHABLE(type); return GL_NONE;
211 }
212 case GL_RG_INTEGER:
213 switch(type)
214 {
215 case GL_UNSIGNED_BYTE: return GL_RG8UI;
216 case GL_BYTE: return GL_RG8I;
217 case GL_UNSIGNED_SHORT: return GL_RG16UI;
218 case GL_SHORT: return GL_RG16I;
219 case GL_UNSIGNED_INT: return GL_RG32UI;
220 case GL_INT: return GL_RG32I;
221 default: UNREACHABLE(type); return GL_NONE;
222 }
223 case GL_RED:
224 switch(type)
225 {
226 case GL_UNSIGNED_BYTE: return GL_R8;
227 case GL_BYTE: return GL_R8_SNORM;
228 case GL_FLOAT: return GL_R32F;
229 case GL_HALF_FLOAT: return GL_R16F;
230 case GL_HALF_FLOAT_OES: return GL_R16F;
231 default: UNREACHABLE(type); return GL_NONE;
232 }
233 case GL_RED_INTEGER:
234 switch(type)
235 {
236 case GL_UNSIGNED_BYTE: return GL_R8UI;
237 case GL_BYTE: return GL_R8I;
238 case GL_UNSIGNED_SHORT: return GL_R16UI;
239 case GL_SHORT: return GL_R16I;
240 case GL_UNSIGNED_INT: return GL_R32UI;
241 case GL_INT: return GL_R32I;
242 default: UNREACHABLE(type); return GL_NONE;
243 }
244 case GL_LUMINANCE_ALPHA:
245 switch(type)
246 {
247 case GL_UNSIGNED_BYTE: return GL_LUMINANCE8_ALPHA8_EXT;
248 case GL_FLOAT: return GL_LUMINANCE_ALPHA32F_EXT;
249 case GL_HALF_FLOAT: return GL_LUMINANCE_ALPHA16F_EXT;
250 case GL_HALF_FLOAT_OES: return GL_LUMINANCE_ALPHA16F_EXT;
251 default: UNREACHABLE(type); return GL_NONE;
252 }
253 case GL_LUMINANCE:
254 switch(type)
255 {
256 case GL_UNSIGNED_BYTE: return GL_LUMINANCE8_EXT;
257 case GL_FLOAT: return GL_LUMINANCE32F_EXT;
258 case GL_HALF_FLOAT: return GL_LUMINANCE16F_EXT;
259 case GL_HALF_FLOAT_OES: return GL_LUMINANCE16F_EXT;
260 default: UNREACHABLE(type); return GL_NONE;
261 }
262 case GL_ALPHA:
263 switch(type)
264 {
265 case GL_UNSIGNED_BYTE: return GL_ALPHA8_EXT;
266 case GL_FLOAT: return GL_ALPHA32F_EXT;
267 case GL_HALF_FLOAT: return GL_ALPHA16F_EXT;
268 case GL_HALF_FLOAT_OES: return GL_ALPHA16F_EXT;
269 default: UNREACHABLE(type); return GL_NONE;
270 }
271 case GL_BGRA_EXT:
272 switch(type)
273 {
274 case GL_UNSIGNED_BYTE: return GL_BGRA8_EXT;
275 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: // Only valid for glReadPixels calls.
276 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: // Only valid for glReadPixels calls.
277 default: UNREACHABLE(type); return GL_NONE;
278 }
279 case GL_DEPTH_COMPONENT:
280 switch(type)
281 {
282 case GL_UNSIGNED_SHORT: return GL_DEPTH_COMPONENT16;
283 case GL_UNSIGNED_INT: return GL_DEPTH_COMPONENT32_OES;
284 case GL_FLOAT: return GL_DEPTH_COMPONENT32F;
285 default: UNREACHABLE(type); return GL_NONE;
286 }
287 case GL_DEPTH_STENCIL:
288 switch(type)
289 {
290 case GL_UNSIGNED_INT_24_8: return GL_DEPTH24_STENCIL8;
291 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return GL_DEPTH32F_STENCIL8;
292 default: UNREACHABLE(type); return GL_NONE;
293 }
294
295 // GL_OES_texture_stencil8
296 // case GL_STENCIL_INDEX_OES / GL_UNSIGNED_BYTE: return GL_STENCIL_INDEX8;
297
298 // GL_EXT_sRGB
299 // case GL_SRGB_EXT / GL_UNSIGNED_BYTE: return GL_SRGB8;
300 // case GL_SRGB_ALPHA_EXT / GL_UNSIGNED_BYTE: return GL_SRGB8_ALPHA8;
301
302 default:
303 UNREACHABLE(internalformat);
304 }
305
306 return GL_NONE;
307 }
308
309 sw::Format SelectInternalFormat(GLint format)
310 {
311 switch(format)
312 {
313 case GL_RGBA4: return sw::FORMAT_A8B8G8R8;
314 case GL_RGB5_A1: return sw::FORMAT_A8B8G8R8;
315 case GL_RGBA8: return sw::FORMAT_A8B8G8R8;
316 case GL_RGB565: return sw::FORMAT_R5G6B5;
317 case GL_RGB8: return sw::FORMAT_X8B8G8R8;
318
319 case GL_DEPTH_COMPONENT32F: return sw::FORMAT_D32F_LOCKABLE;
320 case GL_DEPTH_COMPONENT16: return sw::FORMAT_D32F_LOCKABLE;
321 case GL_DEPTH_COMPONENT24: return sw::FORMAT_D32F_LOCKABLE;
322 case GL_DEPTH_COMPONENT32_OES: return sw::FORMAT_D32F_LOCKABLE;
323 case GL_DEPTH24_STENCIL8: return sw::FORMAT_D32FS8_TEXTURE;
324 case GL_DEPTH32F_STENCIL8: return sw::FORMAT_D32FS8_TEXTURE;
325 case GL_STENCIL_INDEX8: return sw::FORMAT_S8;
326
327 case GL_R8: return sw::FORMAT_R8;
328 case GL_RG8: return sw::FORMAT_G8R8;
329 case GL_R8I: return sw::FORMAT_R8I;
330 case GL_RG8I: return sw::FORMAT_G8R8I;
331 case GL_RGB8I: return sw::FORMAT_X8B8G8R8I;
332 case GL_RGBA8I: return sw::FORMAT_A8B8G8R8I;
333 case GL_R8UI: return sw::FORMAT_R8UI;
334 case GL_RG8UI: return sw::FORMAT_G8R8UI;
335 case GL_RGB8UI: return sw::FORMAT_X8B8G8R8UI;
336 case GL_RGBA8UI: return sw::FORMAT_A8B8G8R8UI;
337 case GL_R16I: return sw::FORMAT_R16I;
338 case GL_RG16I: return sw::FORMAT_G16R16I;
339 case GL_RGB16I: return sw::FORMAT_X16B16G16R16I;
340 case GL_RGBA16I: return sw::FORMAT_A16B16G16R16I;
341 case GL_R16UI: return sw::FORMAT_R16UI;
342 case GL_RG16UI: return sw::FORMAT_G16R16UI;
343 case GL_RGB16UI: return sw::FORMAT_X16B16G16R16UI;
344 case GL_RGBA16UI: return sw::FORMAT_A16B16G16R16UI;
345 case GL_R32I: return sw::FORMAT_R32I;
346 case GL_RG32I: return sw::FORMAT_G32R32I;
347 case GL_RGB32I: return sw::FORMAT_X32B32G32R32I;
348 case GL_RGBA32I: return sw::FORMAT_A32B32G32R32I;
349 case GL_R32UI: return sw::FORMAT_R32UI;
350 case GL_RG32UI: return sw::FORMAT_G32R32UI;
351 case GL_RGB32UI: return sw::FORMAT_X32B32G32R32UI;
352 case GL_RGBA32UI: return sw::FORMAT_A32B32G32R32UI;
353 case GL_R16F: return sw::FORMAT_R16F;
354 case GL_RG16F: return sw::FORMAT_G16R16F;
355 case GL_R11F_G11F_B10F: return sw::FORMAT_X16B16G16R16F_UNSIGNED;
356 case GL_RGB16F: return sw::FORMAT_X16B16G16R16F;
357 case GL_RGBA16F: return sw::FORMAT_A16B16G16R16F;
358 case GL_R32F: return sw::FORMAT_R32F;
359 case GL_RG32F: return sw::FORMAT_G32R32F;
360 case GL_RGB32F: return sw::FORMAT_X32B32G32R32F;
361 case GL_RGBA32F: return sw::FORMAT_A32B32G32R32F;
362 case GL_RGB10_A2: return sw::FORMAT_A2B10G10R10;
363 case GL_RGB10_A2UI: return sw::FORMAT_A2B10G10R10UI;
364 case GL_SRGB8: return sw::FORMAT_SRGB8_X8;
365 case GL_SRGB8_ALPHA8: return sw::FORMAT_SRGB8_A8;
366
367 case GL_ETC1_RGB8_OES: return sw::FORMAT_ETC1;
368 case GL_COMPRESSED_R11_EAC: return sw::FORMAT_R11_EAC;
369 case GL_COMPRESSED_SIGNED_R11_EAC: return sw::FORMAT_SIGNED_R11_EAC;
370 case GL_COMPRESSED_RG11_EAC: return sw::FORMAT_RG11_EAC;
371 case GL_COMPRESSED_SIGNED_RG11_EAC: return sw::FORMAT_SIGNED_RG11_EAC;
372 case GL_COMPRESSED_RGB8_ETC2: return sw::FORMAT_RGB8_ETC2;
373 case GL_COMPRESSED_SRGB8_ETC2: return sw::FORMAT_SRGB8_ETC2;
374 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: return sw::FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
375 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: return sw::FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
376 case GL_COMPRESSED_RGBA8_ETC2_EAC: return sw::FORMAT_RGBA8_ETC2_EAC;
377 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: return sw::FORMAT_SRGB8_ALPHA8_ETC2_EAC;
378 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: return sw::FORMAT_RGBA_ASTC_4x4_KHR;
379 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: return sw::FORMAT_RGBA_ASTC_5x4_KHR;
380 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: return sw::FORMAT_RGBA_ASTC_5x5_KHR;
381 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: return sw::FORMAT_RGBA_ASTC_6x5_KHR;
382 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: return sw::FORMAT_RGBA_ASTC_6x6_KHR;
383 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: return sw::FORMAT_RGBA_ASTC_8x5_KHR;
384 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: return sw::FORMAT_RGBA_ASTC_8x6_KHR;
385 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: return sw::FORMAT_RGBA_ASTC_8x8_KHR;
386 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: return sw::FORMAT_RGBA_ASTC_10x5_KHR;
387 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: return sw::FORMAT_RGBA_ASTC_10x6_KHR;
388 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: return sw::FORMAT_RGBA_ASTC_10x8_KHR;
389 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: return sw::FORMAT_RGBA_ASTC_10x10_KHR;
390 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: return sw::FORMAT_RGBA_ASTC_12x10_KHR;
391 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: return sw::FORMAT_RGBA_ASTC_12x12_KHR;
392 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR;
393 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR;
394 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR;
395 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_6x5_KHR;
396 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR;
397 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR;
398 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR;
399 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR;
400 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR;
401 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR;
402 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR;
403 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR;
404 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR;
405 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR;
406 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return sw::FORMAT_DXT1;
407 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return sw::FORMAT_DXT1;
408 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: return sw::FORMAT_DXT3;
409 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return sw::FORMAT_DXT5;
410
411 case GL_ALPHA32F_EXT: return sw::FORMAT_A32F;
412 case GL_LUMINANCE32F_EXT: return sw::FORMAT_L32F;
413 case GL_LUMINANCE_ALPHA32F_EXT: return sw::FORMAT_A32L32F;
414 case GL_RGB9_E5: return sw::FORMAT_X16B16G16R16F_UNSIGNED;
415 case GL_ALPHA16F_EXT: return sw::FORMAT_A16F;
416 case GL_LUMINANCE16F_EXT: return sw::FORMAT_L16F;
417 case GL_LUMINANCE_ALPHA16F_EXT: return sw::FORMAT_A16L16F;
418 case GL_R8_SNORM: return sw::FORMAT_R8_SNORM;
419 case GL_RG8_SNORM: return sw::FORMAT_G8R8_SNORM;
420 case GL_RGB8_SNORM: return sw::FORMAT_X8B8G8R8_SNORM;
421 case GL_RGBA8_SNORM: return sw::FORMAT_A8B8G8R8_SNORM;
422 case GL_LUMINANCE8_EXT: return sw::FORMAT_L8;
423 case GL_LUMINANCE8_ALPHA8_EXT: return sw::FORMAT_A8L8;
424 case GL_BGRA8_EXT: return sw::FORMAT_A8R8G8B8;
425 case GL_ALPHA8_EXT: return sw::FORMAT_A8;
426
427 case SW_YV12_BT601: return sw::FORMAT_YV12_BT601;
428 case SW_YV12_BT709: return sw::FORMAT_YV12_BT709;
429 case SW_YV12_JFIF: return sw::FORMAT_YV12_JFIF;
430
431 default:
432 UNREACHABLE(format); // Not a sized internal format.
433 return sw::FORMAT_NULL;
434 }
435 }
436
437 // Returns the size, in bytes, of a single client-side pixel.
438 // OpenGL ES 3.0.5 table 3.2.
439 GLsizei ComputePixelSize(GLenum format, GLenum type)
440 {
441 switch(format)
442 {
443 case GL_RED:
444 case GL_RED_INTEGER:
445 case GL_ALPHA:
446 case GL_LUMINANCE:
447 switch(type)
448 {
449 case GL_BYTE: return 1;
450 case GL_UNSIGNED_BYTE: return 1;
451 case GL_FLOAT: return 4;
452 case GL_HALF_FLOAT: return 2;
453 case GL_HALF_FLOAT_OES: return 2;
454 case GL_SHORT: return 2;
455 case GL_UNSIGNED_SHORT: return 2;
456 case GL_INT: return 4;
457 case GL_UNSIGNED_INT: return 4;
458 default: UNREACHABLE(type);
459 }
460 break;
461 case GL_RG:
462 case GL_RG_INTEGER:
463 case GL_LUMINANCE_ALPHA:
464 switch(type)
465 {
466 case GL_BYTE: return 2;
467 case GL_UNSIGNED_BYTE: return 2;
468 case GL_FLOAT: return 8;
469 case GL_HALF_FLOAT: return 4;
470 case GL_HALF_FLOAT_OES: return 4;
471 case GL_SHORT: return 4;
472 case GL_UNSIGNED_SHORT: return 4;
473 case GL_INT: return 8;
474 case GL_UNSIGNED_INT: return 8;
475 default: UNREACHABLE(type);
476 }
477 break;
478 case GL_RGB:
479 case GL_RGB_INTEGER:
480 switch(type)
481 {
482 case GL_BYTE: return 3;
483 case GL_UNSIGNED_BYTE: return 3;
484 case GL_UNSIGNED_SHORT_5_6_5: return 2;
485 case GL_UNSIGNED_INT_10F_11F_11F_REV: return 4;
486 case GL_UNSIGNED_INT_5_9_9_9_REV: return 4;
487 case GL_FLOAT: return 12;
488 case GL_HALF_FLOAT: return 6;
489 case GL_HALF_FLOAT_OES: return 6;
490 case GL_SHORT: return 6;
491 case GL_UNSIGNED_SHORT: return 6;
492 case GL_INT: return 12;
493 case GL_UNSIGNED_INT: return 12;
494 default: UNREACHABLE(type);
495 }
496 break;
497 case GL_RGBA:
498 case GL_RGBA_INTEGER:
499 case GL_BGRA_EXT:
500 switch(type)
501 {
502 case GL_BYTE: return 4;
503 case GL_UNSIGNED_BYTE: return 4;
504 case GL_UNSIGNED_SHORT_4_4_4_4: return 2;
505 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: return 2;
506 case GL_UNSIGNED_SHORT_5_5_5_1: return 2;
507 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: return 2;
508 case GL_UNSIGNED_INT_2_10_10_10_REV: return 4;
509 case GL_FLOAT: return 16;
510 case GL_HALF_FLOAT: return 8;
511 case GL_HALF_FLOAT_OES: return 8;
512 case GL_SHORT: return 8;
513 case GL_UNSIGNED_SHORT: return 8;
514 case GL_INT: return 16;
515 case GL_UNSIGNED_INT: return 16;
516 default: UNREACHABLE(type);
517 }
518 break;
519 case GL_DEPTH_COMPONENT:
520 switch(type)
521 {
522 case GL_FLOAT: return 4;
523 case GL_UNSIGNED_SHORT: return 2;
524 case GL_UNSIGNED_INT: return 4;
525 default: UNREACHABLE(type);
526 }
527 break;
528 case GL_DEPTH_STENCIL:
529 switch(type)
530 {
531 case GL_UNSIGNED_INT_24_8: return 4;
532 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return 8;
533 default: UNREACHABLE(type);
534 }
535 break;
536 default:
537 UNREACHABLE(format);
538 }
539
540 return 0;
541 }
542
543 GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
544 {
545 ASSERT(alignment > 0 && sw::isPow2(alignment));
546
547 GLsizei rawPitch = ComputePixelSize(format, type) * width;
548 return (rawPitch + alignment - 1) & ~(alignment - 1);
549 }
550
551 size_t ComputePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, const gl::PixelStorageModes &storageModes)
552 {
553 GLsizei pitchB = ComputePitch(width, format, type, storageModes.alignment);
554 return (storageModes.skipImages * height + storageModes.skipRows) * pitchB + storageModes.skipPixels * ComputePixelSize(format, type);
555 }
556
557 inline GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
558 {
559 return ComputeCompressedSize(width, 1, format);
560 }
561
562 inline int GetNumCompressedBlocks(int w, int h, int blockSizeX, int blockSizeY)
563 {
564 return ((w + blockSizeX - 1) / blockSizeX) * ((h + blockSizeY - 1) / blockSizeY);
565 }
566
567 GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
568 {
569 switch(format)
570 {
571 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
572 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
573 case GL_ETC1_RGB8_OES:
574 case GL_COMPRESSED_R11_EAC:
575 case GL_COMPRESSED_SIGNED_R11_EAC:
576 case GL_COMPRESSED_RGB8_ETC2:
577 case GL_COMPRESSED_SRGB8_ETC2:
578 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
579 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
580 return 8 * GetNumCompressedBlocks(width, height, 4, 4);
581 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
582 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
583 case GL_COMPRESSED_RG11_EAC:
584 case GL_COMPRESSED_SIGNED_RG11_EAC:
585 case GL_COMPRESSED_RGBA8_ETC2_EAC:
586 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
587 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
588 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
589 return 16 * GetNumCompressedBlocks(width, height, 4, 4);
590 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
591 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
592 return 16 * GetNumCompressedBlocks(width, height, 5, 4);
593 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
594 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
595 return 16 * GetNumCompressedBlocks(width, height, 5, 5);
596 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
597 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
598 return 16 * GetNumCompressedBlocks(width, height, 6, 5);
599 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
600 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
601 return 16 * GetNumCompressedBlocks(width, height, 6, 6);
602 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
603 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
604 return 16 * GetNumCompressedBlocks(width, height, 8, 5);
605 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
606 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
607 return 16 * GetNumCompressedBlocks(width, height, 8, 6);
608 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
609 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
610 return 16 * GetNumCompressedBlocks(width, height, 8, 8);
611 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
612 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
613 return 16 * GetNumCompressedBlocks(width, height, 10, 5);
614 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
615 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
616 return 16 * GetNumCompressedBlocks(width, height, 10, 6);
617 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
618 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
619 return 16 * GetNumCompressedBlocks(width, height, 10, 8);
620 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
621 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
622 return 16 * GetNumCompressedBlocks(width, height, 10, 10);
623 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
624 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
625 return 16 * GetNumCompressedBlocks(width, height, 12, 10);
626 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
627 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
628 return 16 * GetNumCompressedBlocks(width, height, 12, 12);
629 default:
630 UNREACHABLE(format);
631 return 0;
632 }
633 }
634}
635
636namespace egl
637{
638 // We assume the data can be indexed with a signed 32-bit offset, including any padding,
639 // so we must keep the image size reasonable. 1 GiB ought to be enough for anybody.
640 enum { IMPLEMENTATION_MAX_IMAGE_SIZE_BYTES = 0x40000000 };
641
642 enum TransferType
643 {
644 Bytes,
645 RGB8toRGBX8,
646 RGB16toRGBX16,
647 RGB32toRGBX32,
648 RGB32FtoRGBX32F,
649 RGB16FtoRGBX16F,
650 RGBA4toRGBA8,
651 RGBA5_A1toRGBA8,
652 R11G11B10FtoRGBX16F,
653 RGB9_E5FtoRGBX16F,
654 D16toD32F,
655 D24X8toD32F,
656 D32toD32F,
657 D32FtoD32F_CLAMPED,
658 D32FX32toD32F,
659 X24S8toS8,
660 X56S8toS8,
661 RGBA1010102toRGBA8,
662 RGB8toRGB565,
663 R32FtoR16F,
664 RG32FtoRG16F,
665 RGB32FtoRGB16F,
666 RGB32FtoRGB16F_UNSIGNED,
667 RGBA32FtoRGBA16F
668 };
669
670 template<TransferType transferType>
671 void TransferRow(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes);
672
673 template<>
674 void TransferRow<Bytes>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
675 {
676 memcpy(dest, source, width * bytes);
677 }
678
679 template<>
680 void TransferRow<RGB8toRGBX8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
681 {
682 unsigned char *destB = dest;
683
684 for(int x = 0; x < width; x++)
685 {
686 destB[4 * x + 0] = source[x * 3 + 0];
687 destB[4 * x + 1] = source[x * 3 + 1];
688 destB[4 * x + 2] = source[x * 3 + 2];
689 destB[4 * x + 3] = 0xFF;
690 }
691 }
692
693 template<>
694 void TransferRow<RGB16toRGBX16>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
695 {
696 const unsigned short *sourceS = reinterpret_cast<const unsigned short*>(source);
697 unsigned short *destS = reinterpret_cast<unsigned short*>(dest);
698
699 for(int x = 0; x < width; x++)
700 {
701 destS[4 * x + 0] = sourceS[x * 3 + 0];
702 destS[4 * x + 1] = sourceS[x * 3 + 1];
703 destS[4 * x + 2] = sourceS[x * 3 + 2];
704 destS[4 * x + 3] = 0xFFFF;
705 }
706 }
707
708 template<>
709 void TransferRow<RGB32toRGBX32>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
710 {
711 const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
712 unsigned int *destI = reinterpret_cast<unsigned int*>(dest);
713
714 for(int x = 0; x < width; x++)
715 {
716 destI[4 * x + 0] = sourceI[x * 3 + 0];
717 destI[4 * x + 1] = sourceI[x * 3 + 1];
718 destI[4 * x + 2] = sourceI[x * 3 + 2];
719 destI[4 * x + 3] = 0xFFFFFFFF;
720 }
721 }
722
723 template<>
724 void TransferRow<RGB32FtoRGBX32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
725 {
726 const float *sourceF = reinterpret_cast<const float*>(source);
727 float *destF = reinterpret_cast<float*>(dest);
728
729 for(int x = 0; x < width; x++)
730 {
731 destF[4 * x + 0] = sourceF[x * 3 + 0];
732 destF[4 * x + 1] = sourceF[x * 3 + 1];
733 destF[4 * x + 2] = sourceF[x * 3 + 2];
734 destF[4 * x + 3] = 1.0f;
735 }
736 }
737
738 template<>
739 void TransferRow<RGB16FtoRGBX16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
740 {
741 const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
742 unsigned short *destH = reinterpret_cast<unsigned short*>(dest);
743
744 for(int x = 0; x < width; x++)
745 {
746 destH[4 * x + 0] = sourceH[x * 3 + 0];
747 destH[4 * x + 1] = sourceH[x * 3 + 1];
748 destH[4 * x + 2] = sourceH[x * 3 + 2];
749 destH[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16-bit floating-point representation of 1.0
750 }
751 }
752
753 template<>
754 void TransferRow<RGBA4toRGBA8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
755 {
756 const unsigned short *source4444 = reinterpret_cast<const unsigned short*>(source);
757 unsigned char *dest4444 = dest;
758
759 for(int x = 0; x < width; x++)
760 {
761 unsigned short rgba = source4444[x];
762 dest4444[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
763 dest4444[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
764 dest4444[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
765 dest4444[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
766 }
767 }
768
769 template<>
770 void TransferRow<RGBA5_A1toRGBA8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
771 {
772 const unsigned short *source5551 = reinterpret_cast<const unsigned short*>(source);
773 unsigned char *dest8888 = dest;
774
775 for(int x = 0; x < width; x++)
776 {
777 unsigned short rgba = source5551[x];
778 dest8888[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
779 dest8888[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
780 dest8888[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
781 dest8888[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
782 }
783 }
784
785 template<>
786 void TransferRow<RGBA1010102toRGBA8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
787 {
788 const unsigned int *source1010102 = reinterpret_cast<const unsigned int*>(source);
789 unsigned char *dest8888 = dest;
790
791 for(int x = 0; x < width; x++)
792 {
793 unsigned int rgba = source1010102[x];
794 dest8888[4 * x + 0] = sw::unorm<8>((rgba & 0x000003FF) * (1.0f / 0x000003FF));
795 dest8888[4 * x + 1] = sw::unorm<8>((rgba & 0x000FFC00) * (1.0f / 0x000FFC00));
796 dest8888[4 * x + 2] = sw::unorm<8>((rgba & 0x3FF00000) * (1.0f / 0x3FF00000));
797 dest8888[4 * x + 3] = sw::unorm<8>((rgba & 0xC0000000) * (1.0f / 0xC0000000));
798 }
799 }
800
801 template<>
802 void TransferRow<RGB8toRGB565>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
803 {
804 unsigned short *dest565 = reinterpret_cast<unsigned short*>(dest);
805
806 for(int x = 0; x < width; x++)
807 {
808 float r = source[3 * x + 0] * (1.0f / 0xFF);
809 float g = source[3 * x + 1] * (1.0f / 0xFF);
810 float b = source[3 * x + 2] * (1.0f / 0xFF);
811 dest565[x] = (sw::unorm<5>(r) << 11) | (sw::unorm<6>(g) << 5) | (sw::unorm<5>(b) << 0);
812 }
813 }
814
815 template<>
816 void TransferRow<R11G11B10FtoRGBX16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
817 {
818 const sw::R11G11B10F *sourceRGB = reinterpret_cast<const sw::R11G11B10F*>(source);
819 sw::half *destF = reinterpret_cast<sw::half*>(dest);
820
821 for(int x = 0; x < width; x++, sourceRGB++, destF += 4)
822 {
823 sourceRGB->toRGB16F(destF);
824 destF[3] = 1.0f;
825 }
826 }
827
828 template<>
829 void TransferRow<RGB9_E5FtoRGBX16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
830 {
831 const sw::RGB9E5 *sourceRGB = reinterpret_cast<const sw::RGB9E5*>(source);
832 sw::half *destF = reinterpret_cast<sw::half*>(dest);
833
834 for(int x = 0; x < width; x++, sourceRGB++, destF += 4)
835 {
836 sourceRGB->toRGB16F(destF);
837 destF[3] = 1.0f;
838 }
839 }
840
841 template<>
842 void TransferRow<R32FtoR16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
843 {
844 const float *source32F = reinterpret_cast<const float*>(source);
845 sw::half *dest16F = reinterpret_cast<sw::half*>(dest);
846
847 for(int x = 0; x < width; x++)
848 {
849 dest16F[x] = source32F[x];
850 }
851 }
852
853 template<>
854 void TransferRow<RG32FtoRG16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
855 {
856 const float *source32F = reinterpret_cast<const float*>(source);
857 sw::half *dest16F = reinterpret_cast<sw::half*>(dest);
858
859 for(int x = 0; x < width; x++)
860 {
861 dest16F[2 * x + 0] = source32F[2 * x + 0];
862 dest16F[2 * x + 1] = source32F[2 * x + 1];
863 }
864 }
865
866 template<>
867 void TransferRow<RGB32FtoRGB16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
868 {
869 const float *source32F = reinterpret_cast<const float*>(source);
870 sw::half *dest16F = reinterpret_cast<sw::half*>(dest);
871
872 for(int x = 0; x < width; x++)
873 {
874 dest16F[4 * x + 0] = source32F[3 * x + 0];
875 dest16F[4 * x + 1] = source32F[3 * x + 1];
876 dest16F[4 * x + 2] = source32F[3 * x + 2];
877 dest16F[4 * x + 3] = 1.0f;
878 }
879 }
880
881 template<>
882 void TransferRow<RGB32FtoRGB16F_UNSIGNED>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
883 {
884 const float *source32F = reinterpret_cast<const float*>(source);
885 sw::half *dest16F = reinterpret_cast<sw::half*>(dest);
886
887 for(int x = 0; x < width; x++)
888 {
889 dest16F[4 * x + 0] = std::max(source32F[3 * x + 0], 0.0f);
890 dest16F[4 * x + 1] = std::max(source32F[3 * x + 1], 0.0f);
891 dest16F[4 * x + 2] = std::max(source32F[3 * x + 2], 0.0f);
892 dest16F[4 * x + 3] = 1.0f;
893 }
894 }
895
896 template<>
897 void TransferRow<RGBA32FtoRGBA16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
898 {
899 const float *source32F = reinterpret_cast<const float*>(source);
900 sw::half *dest16F = reinterpret_cast<sw::half*>(dest);
901
902 for(int x = 0; x < width; x++)
903 {
904 dest16F[4 * x + 0] = source32F[4 * x + 0];
905 dest16F[4 * x + 1] = source32F[4 * x + 1];
906 dest16F[4 * x + 2] = source32F[4 * x + 2];
907 dest16F[4 * x + 3] = source32F[4 * x + 3];
908 }
909 }
910
911 template<>
912 void TransferRow<D16toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
913 {
914 const unsigned short *sourceD16 = reinterpret_cast<const unsigned short*>(source);
915 float *destF = reinterpret_cast<float*>(dest);
916
917 for(int x = 0; x < width; x++)
918 {
919 destF[x] = (float)sourceD16[x] / 0xFFFF;
920 }
921 }
922
923 template<>
924 void TransferRow<D24X8toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
925 {
926 const unsigned int *sourceD24 = reinterpret_cast<const unsigned int*>(source);
927 float *destF = reinterpret_cast<float*>(dest);
928
929 for(int x = 0; x < width; x++)
930 {
931 destF[x] = (float)(sourceD24[x] & 0xFFFFFF00) / 0xFFFFFF00;
932 }
933 }
934
935 template<>
936 void TransferRow<D32toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
937 {
938 const unsigned int *sourceD32 = reinterpret_cast<const unsigned int*>(source);
939 float *destF = reinterpret_cast<float*>(dest);
940
941 for(int x = 0; x < width; x++)
942 {
943 destF[x] = (float)sourceD32[x] / 0xFFFFFFFF;
944 }
945 }
946
947 template<>
948 void TransferRow<D32FtoD32F_CLAMPED>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
949 {
950 const float *sourceF = reinterpret_cast<const float*>(source);
951 float *destF = reinterpret_cast<float*>(dest);
952
953 for(int x = 0; x < width; x++)
954 {
955 destF[x] = sw::clamp(sourceF[x], 0.0f, 1.0f);
956 }
957 }
958
959 template<>
960 void TransferRow<D32FX32toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
961 {
962 struct D32FS8 { float depth32f; unsigned int stencil24_8; };
963 const D32FS8 *sourceD32FS8 = reinterpret_cast<const D32FS8*>(source);
964 float *destF = reinterpret_cast<float*>(dest);
965
966 for(int x = 0; x < width; x++)
967 {
968 destF[x] = sw::clamp(sourceD32FS8[x].depth32f, 0.0f, 1.0f);
969 }
970 }
971
972 template<>
973 void TransferRow<X24S8toS8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
974 {
975 const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
976 unsigned char *destI = dest;
977
978 for(int x = 0; x < width; x++)
979 {
980 destI[x] = static_cast<unsigned char>(sourceI[x] & 0x000000FF); // FIXME: Quad layout
981 }
982 }
983
984 template<>
985 void TransferRow<X56S8toS8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
986 {
987 struct D32FS8 { float depth32f; unsigned int stencil24_8; };
988 const D32FS8 *sourceD32FS8 = reinterpret_cast<const D32FS8*>(source);
989 unsigned char *destI = dest;
990
991 for(int x = 0; x < width; x++)
992 {
993 destI[x] = static_cast<unsigned char>(sourceD32FS8[x].stencil24_8 & 0x000000FF); // FIXME: Quad layout
994 }
995 }
996
997 struct Rectangle
998 {
999 GLsizei bytes;
1000 GLsizei width;
1001 GLsizei height;
1002 GLsizei depth;
1003 int inputPitch;
1004 int inputHeight;
1005 int destPitch;
1006 GLsizei destSlice;
1007 };
1008
1009 template<TransferType transferType>
1010 void Transfer(void *buffer, const void *input, const Rectangle &rect)
1011 {
1012 for(int z = 0; z < rect.depth; z++)
1013 {
1014 const unsigned char *inputStart = static_cast<const unsigned char*>(input) + (z * rect.inputPitch * rect.inputHeight);
1015 unsigned char *destStart = static_cast<unsigned char*>(buffer) + (z * rect.destSlice);
1016 for(int y = 0; y < rect.height; y++)
1017 {
1018 const unsigned char *source = inputStart + y * rect.inputPitch;
1019 unsigned char *dest = destStart + y * rect.destPitch;
1020
1021 TransferRow<transferType>(dest, source, rect.width, rect.bytes);
1022 }
1023 }
1024 }
1025
1026 class ImageImplementation : public Image
1027 {
1028 public:
1029 ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLint internalformat)
1030 : Image(parentTexture, width, height, internalformat) {}
1031 ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLint internalformat)
1032 : Image(parentTexture, width, height, depth, border, internalformat) {}
1033 ImageImplementation(GLsizei width, GLsizei height, GLint internalformat, int pitchP)
1034 : Image(width, height, internalformat, pitchP) {}
1035 ImageImplementation(GLsizei width, GLsizei height, GLint internalformat, int multiSampleDepth, bool lockable)
1036 : Image(width, height, internalformat, multiSampleDepth, lockable) {}
1037
1038 ~ImageImplementation() override
1039 {
1040 sync(); // Wait for any threads that use this image to finish.
1041 }
1042
1043 void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override
1044 {
1045 return Image::lockInternal(x, y, z, lock, client);
1046 }
1047
1048 void unlockInternal() override
1049 {
1050 return Image::unlockInternal();
1051 }
1052
1053 void release() override
1054 {
1055 return Image::release();
1056 }
1057 };
1058
1059 Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLint internalformat)
1060 {
1061 if(size(width, height, 1, 0, 1, internalformat) > IMPLEMENTATION_MAX_IMAGE_SIZE_BYTES)
1062 {
1063 return nullptr;
1064 }
1065
1066 return new ImageImplementation(parentTexture, width, height, internalformat);
1067 }
1068
1069 Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLint internalformat)
1070 {
1071 if(size(width, height, depth, border, 1, internalformat) > IMPLEMENTATION_MAX_IMAGE_SIZE_BYTES)
1072 {
1073 return nullptr;
1074 }
1075
1076 return new ImageImplementation(parentTexture, width, height, depth, border, internalformat);
1077 }
1078
1079 Image *Image::create(GLsizei width, GLsizei height, GLint internalformat, int pitchP)
1080 {
1081 if(size(pitchP, height, 1, 0, 1, internalformat) > IMPLEMENTATION_MAX_IMAGE_SIZE_BYTES)
1082 {
1083 return nullptr;
1084 }
1085
1086 return new ImageImplementation(width, height, internalformat, pitchP);
1087 }
1088
1089 Image *Image::create(GLsizei width, GLsizei height, GLint internalformat, int multiSampleDepth, bool lockable)
1090 {
1091 if(size(width, height, 1, 0, multiSampleDepth, internalformat) > IMPLEMENTATION_MAX_IMAGE_SIZE_BYTES)
1092 {
1093 return nullptr;
1094 }
1095
1096 return new ImageImplementation(width, height, internalformat, multiSampleDepth, lockable);
1097 }
1098
1099 size_t Image::size(int width, int height, int depth, int border, int samples, GLint internalformat)
1100 {
1101 return sw::Surface::size(width, height, depth, border, samples, gl::SelectInternalFormat(internalformat));
1102 }
1103
1104 int ClientBuffer::getWidth() const
1105 {
1106 return width;
1107 }
1108
1109 int ClientBuffer::getHeight() const
1110 {
1111 return height;
1112 }
1113
1114 sw::Format ClientBuffer::getFormat() const
1115 {
1116 return format;
1117 }
1118
1119 size_t ClientBuffer::getPlane() const
1120 {
1121 return plane;
1122 }
1123
1124 int ClientBuffer::pitchP() const
1125 {
1126#if defined(__APPLE__)
1127 if(buffer)
1128 {
1129 IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
1130 int pitchB = static_cast<int>(IOSurfaceGetBytesPerRowOfPlane(ioSurface, plane));
1131 int bytesPerPixel = sw::Surface::bytes(format);
1132 ASSERT((pitchB % bytesPerPixel) == 0);
1133 return pitchB / bytesPerPixel;
1134 }
1135
1136 return 0;
1137#else
1138 return sw::Surface::pitchP(width, 0, format, false);
1139#endif
1140 }
1141
1142 void ClientBuffer::retain()
1143 {
1144#if defined(__APPLE__)
1145 if(buffer)
1146 {
1147 CFRetain(reinterpret_cast<IOSurfaceRef>(buffer));
1148 }
1149#endif
1150 }
1151
1152 void ClientBuffer::release()
1153 {
1154#if defined(__APPLE__)
1155 if(buffer)
1156 {
1157 CFRelease(reinterpret_cast<IOSurfaceRef>(buffer));
1158 buffer = nullptr;
1159 }
1160#endif
1161 }
1162
1163 void* ClientBuffer::lock(int x, int y, int z)
1164 {
1165#if defined(__APPLE__)
1166 if(buffer)
1167 {
1168 IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
1169 IOSurfaceLock(ioSurface, 0, nullptr);
1170 void* pixels = IOSurfaceGetBaseAddressOfPlane(ioSurface, plane);
1171 int bytes = sw::Surface::bytes(format);
1172 int pitchB = static_cast<int>(IOSurfaceGetBytesPerRowOfPlane(ioSurface, plane));
1173 int sliceB = static_cast<int>(IOSurfaceGetHeightOfPlane(ioSurface, plane)) * pitchB;
1174 return (unsigned char*)pixels + x * bytes + y * pitchB + z * sliceB;
1175 }
1176
1177 return nullptr;
1178#else
1179 int bytes = sw::Surface::bytes(format);
1180 int pitchB = sw::Surface::pitchB(width, 0, format, false);
1181 int sliceB = height * pitchB;
1182 return (unsigned char*)buffer + x * bytes + y * pitchB + z * sliceB;
1183#endif
1184 }
1185
1186 void ClientBuffer::unlock()
1187 {
1188#if defined(__APPLE__)
1189 if(buffer)
1190 {
1191 IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
1192 IOSurfaceUnlock(ioSurface, 0, nullptr);
1193 }
1194#endif
1195 }
1196
1197 bool ClientBuffer::requiresSync() const
1198 {
1199#if defined(__APPLE__)
1200 return true;
1201#else
1202 return false;
1203#endif
1204 }
1205
1206 class ClientBufferImage : public egl::Image
1207 {
1208 public:
1209 explicit ClientBufferImage(const ClientBuffer& clientBuffer) :
1210 egl::Image(clientBuffer.getWidth(),
1211 clientBuffer.getHeight(),
1212 getClientBufferInternalFormat(clientBuffer.getFormat()),
1213 clientBuffer.pitchP()),
1214 clientBuffer(clientBuffer)
1215 {
1216 shared = false;
1217 this->clientBuffer.retain();
1218 }
1219
1220 private:
1221 ClientBuffer clientBuffer;
1222
1223 ~ClientBufferImage() override
1224 {
1225 sync(); // Wait for any threads that use this image to finish.
1226
1227 clientBuffer.release();
1228 }
1229
1230 static GLint getClientBufferInternalFormat(sw::Format format)
1231 {
1232 switch(format)
1233 {
1234 case sw::FORMAT_R8: return GL_R8;
1235 case sw::FORMAT_G8R8: return GL_RG8;
1236 case sw::FORMAT_X8R8G8B8: return GL_RGB8;
1237 case sw::FORMAT_A8R8G8B8: return GL_BGRA8_EXT;
1238 case sw::FORMAT_R16UI: return GL_R16UI;
1239 case sw::FORMAT_A16B16G16R16F: return GL_RGBA16F;
1240 default: return GL_NONE;
1241 }
1242 }
1243
1244 void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override
1245 {
1246 LOGLOCK("image=%p op=%s.swsurface lock=%d", this, __FUNCTION__, lock);
1247
1248 // Always do this for reference counting.
1249 void *data = sw::Surface::lockInternal(x, y, z, lock, client);
1250
1251 if(x != 0 || y != 0 || z != 0)
1252 {
1253 LOGLOCK("badness: %s called with unsupported parms: image=%p x=%d y=%d z=%d", __FUNCTION__, this, x, y, z);
1254 }
1255
1256 LOGLOCK("image=%p op=%s.ani lock=%d", this, __FUNCTION__, lock);
1257
1258 // Lock the ClientBuffer and use its address.
1259 data = clientBuffer.lock(x, y, z);
1260
1261 if(lock == sw::LOCK_UNLOCKED)
1262 {
1263 // We're never going to get a corresponding unlock, so unlock
1264 // immediately. This keeps the reference counts sane.
1265 clientBuffer.unlock();
1266 }
1267
1268 return data;
1269 }
1270
1271 void unlockInternal() override
1272 {
1273 LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
1274 clientBuffer.unlock();
1275
1276 LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);
1277 sw::Surface::unlockInternal();
1278 }
1279
1280 void *lock(int x, int y, int z, sw::Lock lock) override
1281 {
1282 LOGLOCK("image=%p op=%s lock=%d", this, __FUNCTION__, lock);
1283 (void)sw::Surface::lockExternal(x, y, z, lock, sw::PUBLIC);
1284
1285 return clientBuffer.lock(x, y, z);
1286 }
1287
1288 void unlock() override
1289 {
1290 LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
1291 clientBuffer.unlock();
1292
1293 LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);
1294 sw::Surface::unlockExternal();
1295 }
1296
1297 bool requiresSync() const override
1298 {
1299 return clientBuffer.requiresSync();
1300 }
1301
1302 void release() override
1303 {
1304 Image::release();
1305 }
1306 };
1307
1308 Image *Image::create(const egl::ClientBuffer& clientBuffer)
1309 {
1310 return new ClientBufferImage(clientBuffer);
1311 }
1312
1313 Image::~Image()
1314 {
1315 // sync() must be called in the destructor of the most derived class to ensure their vtable isn't destroyed
1316 // before all threads are done using this image. Image itself is abstract so it can't be the most derived.
1317 ASSERT(isUnlocked());
1318
1319 if(parentTexture)
1320 {
1321 parentTexture->release();
1322 }
1323
1324 ASSERT(!shared);
1325 }
1326
1327 void *Image::lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
1328 {
1329 return Surface::lockInternal(x, y, z, lock, client);
1330 }
1331
1332 void Image::unlockInternal()
1333 {
1334 Surface::unlockInternal();
1335 }
1336
1337 void Image::release()
1338 {
1339 int refs = dereference();
1340
1341 if(refs > 0)
1342 {
1343 if(parentTexture)
1344 {
1345 parentTexture->sweep();
1346 }
1347 }
1348 else
1349 {
1350 delete this;
1351 }
1352 }
1353
1354 void Image::unbind(const egl::Texture *parent)
1355 {
1356 if(parentTexture == parent)
1357 {
1358 parentTexture = nullptr;
1359 }
1360
1361 release();
1362 }
1363
1364 bool Image::isChildOf(const egl::Texture *parent) const
1365 {
1366 return parentTexture == parent;
1367 }
1368
1369 void Image::loadImageData(GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, GLenum format, GLenum type, const void *input, void *buffer)
1370 {
1371 Rectangle rect;
1372 rect.bytes = gl::ComputePixelSize(format, type);
1373 rect.width = width;
1374 rect.height = height;
1375 rect.depth = depth;
1376 rect.inputPitch = inputPitch;
1377 rect.inputHeight = inputHeight;
1378 rect.destPitch = getPitch();
1379 rect.destSlice = getSlice();
1380
1381 // [OpenGL ES 3.0.5] table 3.2 and 3.3.
1382 switch(format)
1383 {
1384 case GL_RGBA:
1385 switch(type)
1386 {
1387 case GL_UNSIGNED_BYTE:
1388 switch(internalformat)
1389 {
1390 case GL_RGBA8:
1391 case GL_SRGB8_ALPHA8:
1392 return Transfer<Bytes>(buffer, input, rect);
1393 case GL_RGB5_A1:
1394 case GL_RGBA4:
1395 ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_A8B8G8R8);
1396 return Transfer<Bytes>(buffer, input, rect);
1397 default:
1398 UNREACHABLE(internalformat);
1399 }
1400 case GL_BYTE:
1401 ASSERT_OR_RETURN(internalformat == GL_RGBA8_SNORM && getExternalFormat() == sw::FORMAT_A8B8G8R8_SNORM);
1402 return Transfer<Bytes>(buffer, input, rect);
1403 case GL_UNSIGNED_SHORT_4_4_4_4:
1404 ASSERT_OR_RETURN(internalformat == GL_RGBA4 && getExternalFormat() == sw::FORMAT_A8B8G8R8);
1405 return Transfer<RGBA4toRGBA8>(buffer, input, rect);
1406 case GL_UNSIGNED_SHORT_5_5_5_1:
1407 ASSERT_OR_RETURN(internalformat == GL_RGB5_A1 && getExternalFormat() == sw::FORMAT_A8B8G8R8);
1408 return Transfer<RGBA5_A1toRGBA8>(buffer, input, rect);
1409 case GL_UNSIGNED_INT_2_10_10_10_REV:
1410 switch(internalformat)
1411 {
1412 case GL_RGB10_A2:
1413 ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_A2B10G10R10);
1414 return Transfer<Bytes>(buffer, input, rect);
1415 case GL_RGB5_A1:
1416 ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_A8B8G8R8);
1417 return Transfer<RGBA1010102toRGBA8>(buffer, input, rect);
1418 default:
1419 UNREACHABLE(internalformat);
1420 }
1421 case GL_HALF_FLOAT:
1422 case GL_HALF_FLOAT_OES:
1423 ASSERT_OR_RETURN(internalformat == GL_RGBA16F && getExternalFormat() == sw::FORMAT_A16B16G16R16F);
1424 return Transfer<Bytes>(buffer, input, rect);
1425 case GL_FLOAT:
1426 switch(internalformat)
1427 {
1428 case GL_RGBA32F: return Transfer<Bytes>(buffer, input, rect);
1429 case GL_RGBA16F: return Transfer<RGBA32FtoRGBA16F>(buffer, input, rect);
1430 default: UNREACHABLE(internalformat);
1431 }
1432 default:
1433 UNREACHABLE(type);
1434 }
1435 case GL_RGBA_INTEGER:
1436 switch(type)
1437 {
1438 case GL_UNSIGNED_BYTE:
1439 ASSERT_OR_RETURN(internalformat == GL_RGBA8UI && getExternalFormat() == sw::FORMAT_A8B8G8R8UI);
1440 return Transfer<Bytes>(buffer, input, rect);
1441 case GL_BYTE:
1442 ASSERT_OR_RETURN(internalformat == GL_RGBA8I && getExternalFormat() == sw::FORMAT_A8B8G8R8I);
1443 return Transfer<Bytes>(buffer, input, rect);
1444 case GL_UNSIGNED_SHORT:
1445 ASSERT_OR_RETURN(internalformat == GL_RGBA16UI && getExternalFormat() == sw::FORMAT_A16B16G16R16UI);
1446 return Transfer<Bytes>(buffer, input, rect);
1447 case GL_SHORT:
1448 ASSERT_OR_RETURN(internalformat == GL_RGBA16I && getExternalFormat() == sw::FORMAT_A16B16G16R16I);
1449 return Transfer<Bytes>(buffer, input, rect);
1450 case GL_UNSIGNED_INT:
1451 ASSERT_OR_RETURN(internalformat == GL_RGBA32UI && getExternalFormat() == sw::FORMAT_A32B32G32R32UI);
1452 return Transfer<Bytes>(buffer, input, rect);
1453 case GL_INT:
1454 ASSERT_OR_RETURN(internalformat == GL_RGBA32I && getExternalFormat() == sw::FORMAT_A32B32G32R32I);
1455 return Transfer<Bytes>(buffer, input, rect);
1456 case GL_UNSIGNED_INT_2_10_10_10_REV:
1457 ASSERT_OR_RETURN(internalformat == GL_RGB10_A2UI && getExternalFormat() == sw::FORMAT_A2B10G10R10UI);
1458 return Transfer<Bytes>(buffer, input, rect);
1459 default:
1460 UNREACHABLE(type);
1461 }
1462 case GL_BGRA_EXT:
1463 switch(type)
1464 {
1465 case GL_UNSIGNED_BYTE:
1466 ASSERT_OR_RETURN(internalformat == GL_BGRA8_EXT && getExternalFormat() == sw::FORMAT_A8R8G8B8);
1467 return Transfer<Bytes>(buffer, input, rect);
1468 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: // Only valid for glReadPixels calls.
1469 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: // Only valid for glReadPixels calls.
1470 default:
1471 UNREACHABLE(type);
1472 }
1473 case GL_RGB:
1474 switch(type)
1475 {
1476 case GL_UNSIGNED_BYTE:
1477 switch(internalformat)
1478 {
1479 case GL_RGB8: return Transfer<RGB8toRGBX8>(buffer, input, rect);
1480 case GL_SRGB8: return Transfer<RGB8toRGBX8>(buffer, input, rect);
1481 case GL_RGB565: return Transfer<RGB8toRGB565>(buffer, input, rect);
1482 default: UNREACHABLE(internalformat);
1483 }
1484 case GL_BYTE:
1485 ASSERT_OR_RETURN(internalformat == GL_RGB8_SNORM && getExternalFormat() == sw::FORMAT_X8B8G8R8_SNORM);
1486 return Transfer<RGB8toRGBX8>(buffer, input, rect);
1487 case GL_UNSIGNED_SHORT_5_6_5:
1488 ASSERT_OR_RETURN(internalformat == GL_RGB565 && getExternalFormat() == sw::FORMAT_R5G6B5);
1489 return Transfer<Bytes>(buffer, input, rect);
1490 case GL_UNSIGNED_INT_10F_11F_11F_REV:
1491 ASSERT_OR_RETURN(internalformat == GL_R11F_G11F_B10F && getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
1492 return Transfer<R11G11B10FtoRGBX16F>(buffer, input, rect);
1493 case GL_UNSIGNED_INT_5_9_9_9_REV:
1494 ASSERT_OR_RETURN(internalformat == GL_RGB9_E5 && getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
1495 return Transfer<RGB9_E5FtoRGBX16F>(buffer, input, rect);
1496 case GL_HALF_FLOAT:
1497 case GL_HALF_FLOAT_OES:
1498 switch(internalformat)
1499 {
1500 case GL_RGB16F:
1501 ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F);
1502 return Transfer<RGB16FtoRGBX16F>(buffer, input, rect);
1503 case GL_R11F_G11F_B10F:
1504 case GL_RGB9_E5:
1505 ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
1506 return Transfer<RGB16FtoRGBX16F>(buffer, input, rect);
1507 default:
1508 UNREACHABLE(internalformat);
1509 }
1510 case GL_FLOAT:
1511 switch(internalformat)
1512 {
1513 case GL_RGB32F:
1514 ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X32B32G32R32F);
1515 return Transfer<RGB32FtoRGBX32F>(buffer, input, rect);
1516 case GL_RGB16F:
1517 ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F);
1518 return Transfer<RGB32FtoRGB16F>(buffer, input, rect);
1519 case GL_R11F_G11F_B10F:
1520 case GL_RGB9_E5:
1521 ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
1522 return Transfer<RGB32FtoRGB16F_UNSIGNED>(buffer, input, rect);
1523 default:
1524 UNREACHABLE(internalformat);
1525 }
1526 default:
1527 UNREACHABLE(type);
1528 }
1529 case GL_RGB_INTEGER:
1530 switch(type)
1531 {
1532 case GL_UNSIGNED_BYTE:
1533 ASSERT_OR_RETURN(internalformat == GL_RGB8UI && getExternalFormat() == sw::FORMAT_X8B8G8R8UI);
1534 return Transfer<RGB8toRGBX8>(buffer, input, rect);
1535 case GL_BYTE:
1536 ASSERT_OR_RETURN(internalformat == GL_RGB8I && getExternalFormat() == sw::FORMAT_X8B8G8R8I);
1537 return Transfer<RGB8toRGBX8>(buffer, input, rect);
1538 case GL_UNSIGNED_SHORT:
1539 ASSERT_OR_RETURN(internalformat == GL_RGB16UI && getExternalFormat() == sw::FORMAT_X16B16G16R16UI);
1540 return Transfer<RGB16toRGBX16>(buffer, input, rect);
1541 case GL_SHORT:
1542 ASSERT_OR_RETURN(internalformat == GL_RGB16I && getExternalFormat() == sw::FORMAT_X16B16G16R16I);
1543 return Transfer<RGB16toRGBX16>(buffer, input, rect);
1544 case GL_UNSIGNED_INT:
1545 ASSERT_OR_RETURN(internalformat == GL_RGB32UI && getExternalFormat() == sw::FORMAT_X32B32G32R32UI);
1546 return Transfer<RGB32toRGBX32>(buffer, input, rect);
1547 case GL_INT:
1548 ASSERT_OR_RETURN(internalformat == GL_RGB32I && getExternalFormat() == sw::FORMAT_X32B32G32R32I);
1549 return Transfer<RGB32toRGBX32>(buffer, input, rect);
1550 default:
1551 UNREACHABLE(type);
1552 }
1553 case GL_RG:
1554 switch(type)
1555 {
1556 case GL_UNSIGNED_BYTE:
1557 case GL_BYTE:
1558 case GL_HALF_FLOAT:
1559 case GL_HALF_FLOAT_OES:
1560 return Transfer<Bytes>(buffer, input, rect);
1561 case GL_FLOAT:
1562 switch(internalformat)
1563 {
1564 case GL_RG32F: return Transfer<Bytes>(buffer, input, rect);
1565 case GL_RG16F: return Transfer<RG32FtoRG16F>(buffer, input, rect);
1566 default: UNREACHABLE(internalformat);
1567 }
1568 default:
1569 UNREACHABLE(type);
1570 }
1571 case GL_RG_INTEGER:
1572 switch(type)
1573 {
1574 case GL_UNSIGNED_BYTE:
1575 ASSERT_OR_RETURN(internalformat == GL_RG8UI && getExternalFormat() == sw::FORMAT_G8R8UI);
1576 return Transfer<Bytes>(buffer, input, rect);
1577 case GL_BYTE:
1578 ASSERT_OR_RETURN(internalformat == GL_RG8I && getExternalFormat() == sw::FORMAT_G8R8I);
1579 return Transfer<Bytes>(buffer, input, rect);
1580 case GL_UNSIGNED_SHORT:
1581 ASSERT_OR_RETURN(internalformat == GL_RG16UI && getExternalFormat() == sw::FORMAT_G16R16UI);
1582 return Transfer<Bytes>(buffer, input, rect);
1583 case GL_SHORT:
1584 ASSERT_OR_RETURN(internalformat == GL_RG16I && getExternalFormat() == sw::FORMAT_G16R16I);
1585 return Transfer<Bytes>(buffer, input, rect);
1586 case GL_UNSIGNED_INT:
1587 ASSERT_OR_RETURN(internalformat == GL_RG32UI && getExternalFormat() == sw::FORMAT_G32R32UI);
1588 return Transfer<Bytes>(buffer, input, rect);
1589 case GL_INT:
1590 ASSERT_OR_RETURN(internalformat == GL_RG32I && getExternalFormat() == sw::FORMAT_G32R32I);
1591 return Transfer<Bytes>(buffer, input, rect);
1592 default:
1593 UNREACHABLE(type);
1594 }
1595 case GL_RED:
1596 switch(type)
1597 {
1598 case GL_UNSIGNED_BYTE:
1599 case GL_BYTE:
1600 case GL_HALF_FLOAT:
1601 case GL_HALF_FLOAT_OES:
1602 return Transfer<Bytes>(buffer, input, rect);
1603 case GL_FLOAT:
1604 switch(internalformat)
1605 {
1606 case GL_R32F: return Transfer<Bytes>(buffer, input, rect);
1607 case GL_R16F: return Transfer<R32FtoR16F>(buffer, input, rect);
1608 default: UNREACHABLE(internalformat);
1609 }
1610 default:
1611 UNREACHABLE(type);
1612 }
1613 case GL_RED_INTEGER:
1614 switch(type)
1615 {
1616 case GL_UNSIGNED_BYTE:
1617 ASSERT_OR_RETURN(internalformat == GL_R8UI && getExternalFormat() == sw::FORMAT_R8UI);
1618 return Transfer<Bytes>(buffer, input, rect);
1619 case GL_BYTE:
1620 ASSERT_OR_RETURN(internalformat == GL_R8I && getExternalFormat() == sw::FORMAT_R8I);
1621 return Transfer<Bytes>(buffer, input, rect);
1622 case GL_UNSIGNED_SHORT:
1623 ASSERT_OR_RETURN(internalformat == GL_R16UI && getExternalFormat() == sw::FORMAT_R16UI);
1624 return Transfer<Bytes>(buffer, input, rect);
1625 case GL_SHORT:
1626 ASSERT_OR_RETURN(internalformat == GL_R16I && getExternalFormat() == sw::FORMAT_R16I);
1627 return Transfer<Bytes>(buffer, input, rect);
1628 case GL_UNSIGNED_INT:
1629 ASSERT_OR_RETURN(internalformat == GL_R32UI && getExternalFormat() == sw::FORMAT_R32UI);
1630 return Transfer<Bytes>(buffer, input, rect);
1631 case GL_INT:
1632 ASSERT_OR_RETURN(internalformat == GL_R32I && getExternalFormat() == sw::FORMAT_R32I);
1633 return Transfer<Bytes>(buffer, input, rect);
1634 default:
1635 UNREACHABLE(type);
1636 }
1637 case GL_DEPTH_COMPONENT:
1638 switch(type)
1639 {
1640 case GL_UNSIGNED_SHORT: return Transfer<D16toD32F>(buffer, input, rect);
1641 case GL_UNSIGNED_INT: return Transfer<D32toD32F>(buffer, input, rect);
1642 case GL_FLOAT: return Transfer<D32FtoD32F_CLAMPED>(buffer, input, rect);
1643 case GL_DEPTH_COMPONENT24: // Only valid for glRenderbufferStorage calls.
1644 case GL_DEPTH_COMPONENT32_OES: // Only valid for glRenderbufferStorage calls.
1645 default: UNREACHABLE(type);
1646 }
1647 case GL_DEPTH_STENCIL:
1648 switch(type)
1649 {
1650 case GL_UNSIGNED_INT_24_8: return Transfer<D24X8toD32F>(buffer, input, rect);
1651 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return Transfer<D32FX32toD32F>(buffer, input, rect);
1652 default: UNREACHABLE(type);
1653 }
1654 case GL_LUMINANCE_ALPHA:
1655 switch(type)
1656 {
1657 case GL_UNSIGNED_BYTE:
1658 return Transfer<Bytes>(buffer, input, rect);
1659 case GL_FLOAT:
1660 switch(internalformat)
1661 {
1662 case GL_LUMINANCE_ALPHA32F_EXT: return Transfer<Bytes>(buffer, input, rect);
1663 case GL_LUMINANCE_ALPHA16F_EXT: return Transfer<RG32FtoRG16F>(buffer, input, rect);
1664 default: UNREACHABLE(internalformat);
1665 }
1666 case GL_HALF_FLOAT:
1667 case GL_HALF_FLOAT_OES:
1668 ASSERT_OR_RETURN(internalformat == GL_LUMINANCE_ALPHA16F_EXT);
1669 return Transfer<Bytes>(buffer, input, rect);
1670 default:
1671 UNREACHABLE(type);
1672 }
1673 case GL_LUMINANCE:
1674 case GL_ALPHA:
1675 switch(type)
1676 {
1677 case GL_UNSIGNED_BYTE:
1678 return Transfer<Bytes>(buffer, input, rect);
1679 case GL_FLOAT:
1680 switch(internalformat)
1681 {
1682 case GL_LUMINANCE32F_EXT: return Transfer<Bytes>(buffer, input, rect);
1683 case GL_LUMINANCE16F_EXT: return Transfer<R32FtoR16F>(buffer, input, rect);
1684 case GL_ALPHA32F_EXT: return Transfer<Bytes>(buffer, input, rect);
1685 case GL_ALPHA16F_EXT: return Transfer<R32FtoR16F>(buffer, input, rect);
1686 default: UNREACHABLE(internalformat);
1687 }
1688 case GL_HALF_FLOAT:
1689 case GL_HALF_FLOAT_OES:
1690 ASSERT_OR_RETURN(internalformat == GL_LUMINANCE16F_EXT || internalformat == GL_ALPHA16F_EXT);
1691 return Transfer<Bytes>(buffer, input, rect);
1692 default:
1693 UNREACHABLE(type);
1694 }
1695 default:
1696 UNREACHABLE(format);
1697 }
1698 }
1699
1700 void Image::loadStencilData(GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, GLenum format, GLenum type, const void *input, void *buffer)
1701 {
1702 Rectangle rect;
1703 rect.bytes = gl::ComputePixelSize(format, type);
1704 rect.width = width;
1705 rect.height = height;
1706 rect.depth = depth;
1707 rect.inputPitch = inputPitch;
1708 rect.inputHeight = inputHeight;
1709 rect.destPitch = getStencilPitchB();
1710 rect.destSlice = getStencilSliceB();
1711
1712 switch(type)
1713 {
1714 case GL_UNSIGNED_INT_24_8: return Transfer<X24S8toS8>(buffer, input, rect);
1715 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return Transfer<X56S8toS8>(buffer, input, rect);
1716 default: UNREACHABLE(format);
1717 }
1718 }
1719
1720 void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
1721 {
1722 GLsizei inputWidth = (unpackParameters.rowLength == 0) ? width : unpackParameters.rowLength;
1723 GLsizei inputPitch = gl::ComputePitch(inputWidth, format, type, unpackParameters.alignment);
1724 GLsizei inputHeight = (unpackParameters.imageHeight == 0) ? height : unpackParameters.imageHeight;
1725 char *input = ((char*)pixels) + gl::ComputePackingOffset(format, type, inputWidth, inputHeight, unpackParameters);
1726
1727 void *buffer = lock(xoffset, yoffset, zoffset, sw::LOCK_WRITEONLY);
1728
1729 if(buffer)
1730 {
1731 loadImageData(width, height, depth, inputPitch, inputHeight, format, type, input, buffer);
1732 }
1733
1734 unlock();
1735
1736 if(hasStencil())
1737 {
1738 unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(xoffset, yoffset, zoffset, sw::PUBLIC));
1739
1740 if(stencil)
1741 {
1742 loadStencilData(width, height, depth, inputPitch, inputHeight, format, type, input, stencil);
1743 }
1744
1745 unlockStencil();
1746 }
1747 }
1748
1749 void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
1750 {
1751 int inputPitch = gl::ComputeCompressedPitch(width, internalformat);
1752 int inputSlice = imageSize / depth;
1753 int rows = inputSlice / inputPitch;
1754
1755 void *buffer = lock(xoffset, yoffset, zoffset, sw::LOCK_WRITEONLY);
1756
1757 if(buffer)
1758 {
1759 for(int z = 0; z < depth; z++)
1760 {
1761 for(int y = 0; y < rows; y++)
1762 {
1763 GLbyte *dest = (GLbyte*)buffer + y * getPitch() + z * getSlice();
1764 GLbyte *source = (GLbyte*)pixels + y * inputPitch + z * inputSlice;
1765 memcpy(dest, source, inputPitch);
1766 }
1767 }
1768 }
1769
1770 unlock();
1771 }
1772}
1773