OSDN Git Service

Log the switch value when reaching an UNREACHABLE().
[android-x86/external-swiftshader.git] / src / OpenGL / common / Image.cpp
1 // SwiftShader Software Renderer
2 //
3 // Copyright(c) 2005-2013 TransGaming Inc.
4 //
5 // All rights reserved. No part of this software may be copied, distributed, transmitted,
6 // transcribed, stored in a retrieval system, translated into any human or computer
7 // language by any means, or disclosed to third parties without the explicit written
8 // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9 // or implied, including but not limited to any patent rights, are granted to you.
10 //
11
12 #include "Image.hpp"
13
14 #include "Renderer/Blitter.hpp"
15 #include "../libEGL/Texture.hpp"
16 #include "../common/debug.h"
17 #include "Common/Thread.hpp"
18
19 #include <GLES/glext.h>
20 #include <GLES2/gl2ext.h>
21 #include <GLES3/gl3.h>
22
23 #include <string.h>
24
25 namespace
26 {
27         enum DataType
28         {
29                 Alpha,
30                 AlphaFloat,
31                 AlphaHalfFloat,
32                 Luminance,
33                 LuminanceFloat,
34                 LuminanceHalfFloat,
35                 LuminanceAlpha,
36                 LuminanceAlphaFloat,
37                 LuminanceAlphaHalfFloat,
38                 UByteRGB,
39                 RGB565,
40                 FloatRGB,
41                 HalfFloatRGB,
42                 UByte4,
43                 RGBA4444,
44                 RGBA5551,
45                 Float4,
46                 HalfFloat4,
47                 D16,
48                 D24,
49                 D32,
50                 S8,
51         };
52
53         template<DataType dataType>
54         void LoadImageRow(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
55         {
56                 UNIMPLEMENTED();
57         }
58
59         template<>
60         void LoadImageRow<Alpha>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
61         {
62                 memcpy(dest + xoffset, source, width);
63         }
64
65         template<>
66         void LoadImageRow<AlphaFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
67         {
68                 const float *sourceF = reinterpret_cast<const float*>(source);
69                 float *destF = reinterpret_cast<float*>(dest + (xoffset * 16));
70
71                 for(int x = 0; x < width; x++)
72                 {
73                         destF[4 * x + 0] = 0;
74                         destF[4 * x + 1] = 0;
75                         destF[4 * x + 2] = 0;
76                         destF[4 * x + 3] = sourceF[x];
77                 }
78         }
79
80         template<>
81         void LoadImageRow<AlphaHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
82         {
83                 const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
84                 unsigned short *destH = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
85
86                 for(int x = 0; x < width; x++)
87                 {
88                         destH[4 * x + 0] = 0;
89                         destH[4 * x + 1] = 0;
90                         destH[4 * x + 2] = 0;
91                         destH[4 * x + 3] = sourceH[x];
92                 }
93         }
94
95         template<>
96         void LoadImageRow<Luminance>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
97         {
98                 memcpy(dest + xoffset, source, width);
99         }
100
101         template<>
102         void LoadImageRow<LuminanceFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
103         {
104                 const float *sourceF = reinterpret_cast<const float*>(source);
105                 float *destF = reinterpret_cast<float*>(dest + xoffset * 16);
106
107                 for(int x = 0; x < width; x++)
108                 {
109                         destF[4 * x + 0] = sourceF[x];
110                         destF[4 * x + 1] = sourceF[x];
111                         destF[4 * x + 2] = sourceF[x];
112                         destF[4 * x + 3] = 1.0f;
113                 }
114         }
115
116         template<>
117         void LoadImageRow<LuminanceHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
118         {
119                 const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
120                 unsigned short *destH = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
121
122                 for(int x = 0; x < width; x++)
123                 {
124                         destH[4 * x + 0] = sourceH[x];
125                         destH[4 * x + 1] = sourceH[x];
126                         destH[4 * x + 2] = sourceH[x];
127                         destH[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
128                 }
129         }
130
131         template<>
132         void LoadImageRow<LuminanceAlpha>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
133         {
134                 memcpy(dest + xoffset * 2, source, width * 2);
135         }
136
137         template<>
138         void LoadImageRow<LuminanceAlphaFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
139         {
140                 const float *sourceF = reinterpret_cast<const float*>(source);
141                 float *destF = reinterpret_cast<float*>(dest + xoffset * 16);
142
143                 for(int x = 0; x < width; x++)
144                 {
145                         destF[4 * x + 0] = sourceF[2 * x + 0];
146                         destF[4 * x + 1] = sourceF[2 * x + 0];
147                         destF[4 * x + 2] = sourceF[2 * x + 0];
148                         destF[4 * x + 3] = sourceF[2 * x + 1];
149                 }
150         }
151
152         template<>
153         void LoadImageRow<LuminanceAlphaHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
154         {
155                 const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
156                 unsigned short *destH = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
157
158                 for(int x = 0; x < width; x++)
159                 {
160                         destH[4 * x + 0] = sourceH[2 * x + 0];
161                         destH[4 * x + 1] = sourceH[2 * x + 0];
162                         destH[4 * x + 2] = sourceH[2 * x + 0];
163                         destH[4 * x + 3] = sourceH[2 * x + 1];
164                 }
165         }
166
167         template<>
168         void LoadImageRow<UByteRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
169         {
170                 unsigned char *destB = dest + xoffset * 4;
171
172                 for(int x = 0; x < width; x++)
173                 {
174                         destB[4 * x + 0] = source[x * 3 + 0];
175                         destB[4 * x + 1] = source[x * 3 + 1];
176                         destB[4 * x + 2] = source[x * 3 + 2];
177                         destB[4 * x + 3] = 0xFF;
178                 }
179         }
180
181         template<>
182         void LoadImageRow<RGB565>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
183         {
184                 const unsigned short *source565 = reinterpret_cast<const unsigned short*>(source);
185                 unsigned char *destB = dest + xoffset * 4;
186
187                 for(int x = 0; x < width; x++)
188                 {
189                         unsigned short rgba = source565[x];
190                         destB[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
191                         destB[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
192                         destB[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
193                         destB[4 * x + 3] = 0xFF;
194                 }
195         }
196
197         template<>
198         void LoadImageRow<FloatRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
199         {
200                 const float *sourceF = reinterpret_cast<const float*>(source);
201                 float *destF = reinterpret_cast<float*>(dest + xoffset * 16);
202
203                 for(int x = 0; x < width; x++)
204                 {
205                         destF[4 * x + 0] = sourceF[x * 3 + 0];
206                         destF[4 * x + 1] = sourceF[x * 3 + 1];
207                         destF[4 * x + 2] = sourceF[x * 3 + 2];
208                         destF[4 * x + 3] = 1.0f;
209                 }
210         }
211
212         template<>
213         void LoadImageRow<HalfFloatRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
214         {
215                 const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
216                 unsigned short *destH = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
217
218                 for(int x = 0; x < width; x++)
219                 {
220                         destH[4 * x + 0] = sourceH[x * 3 + 0];
221                         destH[4 * x + 1] = sourceH[x * 3 + 1];
222                         destH[4 * x + 2] = sourceH[x * 3 + 2];
223                         destH[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
224                 }
225         }
226
227         template<>
228         void LoadImageRow<UByte4>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
229         {
230                 memcpy(dest + xoffset * 4, source, width * 4);
231         }
232
233         template<>
234         void LoadImageRow<RGBA4444>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
235         {
236                 const unsigned short *source4444 = reinterpret_cast<const unsigned short*>(source);
237                 unsigned char *dest4444 = dest + xoffset * 4;
238
239                 for(int x = 0; x < width; x++)
240                 {
241                         unsigned short rgba = source4444[x];
242                         dest4444[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
243                         dest4444[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
244                         dest4444[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
245                         dest4444[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
246                 }
247         }
248
249         template<>
250         void LoadImageRow<RGBA5551>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
251         {
252                 const unsigned short *source5551 = reinterpret_cast<const unsigned short*>(source);
253                 unsigned char *dest5551 = dest + xoffset * 4;
254
255                 for(int x = 0; x < width; x++)
256                 {
257                         unsigned short rgba = source5551[x];
258                         dest5551[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
259                         dest5551[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
260                         dest5551[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
261                         dest5551[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
262                 }
263         }
264
265         template<>
266         void LoadImageRow<Float4>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
267         {
268                 memcpy(dest + xoffset * 16, source, width * 16);
269         }
270
271         template<>
272         void LoadImageRow<HalfFloat4>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
273         {
274                 memcpy(dest + xoffset * 8, source, width * 8);
275         }
276
277         template<>
278         void LoadImageRow<D16>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
279         {
280                 const unsigned short *sourceD16 = reinterpret_cast<const unsigned short*>(source);
281                 float *destF = reinterpret_cast<float*>(dest + xoffset * 4);
282
283                 for(int x = 0; x < width; x++)
284                 {
285                         destF[x] = (float)sourceD16[x] / 0xFFFF;
286                 }
287         }
288
289         template<>
290         void LoadImageRow<D24>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
291         {
292                 const unsigned int *sourceD24 = reinterpret_cast<const unsigned int*>(source);
293                 float *destF = reinterpret_cast<float*>(dest + xoffset * 4);
294
295                 for(int x = 0; x < width; x++)
296                 {
297                         destF[x] = (float)(sourceD24[x] & 0xFFFFFF00) / 0xFFFFFF00;
298                 }
299         }
300
301         template<>
302         void LoadImageRow<D32>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
303         {
304                 const unsigned int *sourceD32 = reinterpret_cast<const unsigned int*>(source);
305                 float *destF = reinterpret_cast<float*>(dest + xoffset * 4);
306
307                 for(int x = 0; x < width; x++)
308                 {
309                         destF[x] = (float)sourceD32[x] / 0xFFFFFFFF;
310                 }
311         }
312
313         template<>
314         void LoadImageRow<S8>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
315         {
316                 const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
317                 unsigned char *destI = dest + xoffset;
318
319                 for(int x = 0; x < width; x++)
320                 {
321                         destI[x] = static_cast<unsigned char>(sourceI[x] & 0x000000FF);   // FIXME: Quad layout
322                 }
323         }
324
325         template<DataType dataType>
326         void LoadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, int destPitch, GLsizei destHeight, const void *input, void *buffer)
327         {
328                 for(int z = 0; z < depth; ++z)
329                 {
330                         const unsigned char *inputStart = static_cast<const unsigned char*>(input) + (z * inputPitch * inputHeight);
331                         unsigned char *destStart = static_cast<unsigned char*>(buffer) + ((zoffset + z) * destPitch * destHeight);
332                         for(int y = 0; y < height; ++y)
333                         {
334                                 const unsigned char *source = inputStart + y * inputPitch;
335                                 unsigned char *dest = destStart + (y + yoffset) * destPitch;
336
337                                 LoadImageRow<dataType>(source, dest, xoffset, width);
338                         }
339                 }
340         }
341 }
342
343 namespace egl
344 {
345         sw::Format ConvertFormatType(GLenum format, GLenum type)
346         {
347                 switch(format)
348                 {
349                 case GL_LUMINANCE:
350                         switch(type)
351                         {
352                         case GL_UNSIGNED_BYTE:  return sw::FORMAT_L8;
353                         case GL_HALF_FLOAT:     return sw::FORMAT_L16F;
354                         case GL_HALF_FLOAT_OES: return sw::FORMAT_L16F;
355                         case GL_FLOAT:          return sw::FORMAT_L32F;
356                         default: UNREACHABLE(type);
357                         }
358                         break;
359                 case GL_LUMINANCE_ALPHA:
360                         switch(type)
361                         {
362                         case GL_UNSIGNED_BYTE:  return sw::FORMAT_A8L8;
363                         case GL_HALF_FLOAT:     return sw::FORMAT_A16L16F;
364                         case GL_HALF_FLOAT_OES: return sw::FORMAT_A16L16F;
365                         case GL_FLOAT:          return sw::FORMAT_A32L32F;
366                         default: UNREACHABLE(type);
367                         }
368                         break;
369                 case GL_RGBA:
370                         switch(type)
371                         {
372                         case GL_UNSIGNED_BYTE:          return sw::FORMAT_A8B8G8R8;
373                         case GL_UNSIGNED_SHORT_4_4_4_4: return sw::FORMAT_R4G4B4A4;
374                         case GL_UNSIGNED_SHORT_5_5_5_1: return sw::FORMAT_R5G5B5A1;
375                         case GL_HALF_FLOAT:             return sw::FORMAT_A16B16G16R16F;
376                         case GL_HALF_FLOAT_OES:         return sw::FORMAT_A16B16G16R16F;
377                         case GL_FLOAT:                  return sw::FORMAT_A32B32G32R32F;
378                         default: UNREACHABLE(type);
379                         }
380                         break;
381                 case GL_BGRA_EXT:
382                         switch(type)
383                         {
384                         case GL_UNSIGNED_BYTE:          return sw::FORMAT_A8R8G8B8;
385                         default: UNREACHABLE(type);
386                         }
387                         break;
388                 case GL_RGB:
389                         switch(type)
390                         {
391                         case GL_UNSIGNED_BYTE:          return sw::FORMAT_B8G8R8;
392                         case GL_UNSIGNED_SHORT_5_6_5:   return sw::FORMAT_R5G6B5;
393                         case GL_HALF_FLOAT:             return sw::FORMAT_B16G16R16F;
394                         case GL_HALF_FLOAT_OES:         return sw::FORMAT_B16G16R16F;
395                         case GL_FLOAT:                  return sw::FORMAT_B32G32R32F;
396                         default: UNREACHABLE(type);
397                         }
398                         break;
399                 case GL_ALPHA:
400                         switch(type)
401                         {
402                         case GL_UNSIGNED_BYTE:          return sw::FORMAT_A8;
403                         case GL_HALF_FLOAT:             return sw::FORMAT_A16F;
404                         case GL_HALF_FLOAT_OES:         return sw::FORMAT_A16F;
405                         case GL_FLOAT:                  return sw::FORMAT_A32F;
406                         default: UNREACHABLE(type);
407                         }
408                         break;
409                 default:
410                         UNREACHABLE(format);
411                 }
412
413                 return sw::FORMAT_NULL;
414         }
415
416         sw::Format SelectInternalFormat(GLenum format, GLenum type)
417         {
418                 if(format == GL_ETC1_RGB8_OES)
419                 {
420                         return sw::FORMAT_ETC1;
421                 }
422                 else
423                 #if S3TC_SUPPORT
424                 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
425                    format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
426                 {
427                         return sw::FORMAT_DXT1;
428                 }
429                 else if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE)
430                 {
431                         return sw::FORMAT_DXT3;
432                 }
433                 else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)
434                 {
435                         return sw::FORMAT_DXT5;
436                 }
437                 else
438                 #endif
439                 if(type == GL_FLOAT)
440                 {
441                         return sw::FORMAT_A32B32G32R32F;
442                 }
443                 else if(type == GL_HALF_FLOAT || type == GL_HALF_FLOAT_OES)
444                 {
445                         return sw::FORMAT_A16B16G16R16F;
446                 }
447                 else if(type == GL_UNSIGNED_BYTE)
448                 {
449                         if(format == GL_LUMINANCE)
450                         {
451                                 return sw::FORMAT_L8;
452                         }
453                         else if(format == GL_LUMINANCE_ALPHA)
454                         {
455                                 return sw::FORMAT_A8L8;
456                         }
457                         else if(format == GL_RGBA)
458                         {
459                                 return sw::FORMAT_A8B8G8R8;
460                         }
461                         else if(format == GL_BGRA_EXT)
462                         {
463                                 return sw::FORMAT_A8R8G8B8;
464                         }
465                         else if(format == GL_RGB)
466                         {
467                                 return sw::FORMAT_X8B8G8R8;
468                         }
469                         else if(format == GL_ALPHA)
470                         {
471                                 return sw::FORMAT_A8;
472                         }
473                         else UNREACHABLE(format);
474                 }
475                 else if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT)
476                 {
477                         if(format == GL_DEPTH_COMPONENT)
478                         {
479                                 return sw::FORMAT_D32FS8_TEXTURE;
480                         }
481                         else UNREACHABLE(format);
482                 }
483                 else if(type == GL_UNSIGNED_INT_24_8_OES)
484                 {
485                         if(format == GL_DEPTH_STENCIL_OES)
486                         {
487                                 return sw::FORMAT_D32FS8_TEXTURE;
488                         }
489                         else UNREACHABLE(format);
490                 }
491                 else if(type == GL_UNSIGNED_SHORT_4_4_4_4)
492                 {
493                         return sw::FORMAT_A8R8G8B8;
494                 }
495                 else if(type == GL_UNSIGNED_SHORT_5_5_5_1)
496                 {
497                         return sw::FORMAT_A8R8G8B8;
498                 }
499                 else if(type == GL_UNSIGNED_SHORT_5_6_5)
500                 {
501                         return sw::FORMAT_X8R8G8B8;
502                 }
503                 else UNREACHABLE(type);
504
505                 return sw::FORMAT_A8B8G8R8;
506         }
507
508         // Returns the size, in bytes, of a single texel in an Image
509         int ComputePixelSize(GLenum format, GLenum type)
510         {
511                 switch(type)
512                 {
513                 case GL_UNSIGNED_BYTE:
514                         switch(format)
515                         {
516                         case GL_ALPHA:           return sizeof(unsigned char);
517                         case GL_LUMINANCE:       return sizeof(unsigned char);
518                         case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
519                         case GL_RGB:             return sizeof(unsigned char) * 3;
520                         case GL_RGBA:            return sizeof(unsigned char) * 4;
521                         case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
522                         default: UNREACHABLE(format);
523                         }
524                         break;
525                 case GL_UNSIGNED_SHORT_4_4_4_4:
526                 case GL_UNSIGNED_SHORT_5_5_5_1:
527                 case GL_UNSIGNED_SHORT_5_6_5:
528                 case GL_UNSIGNED_SHORT:
529                         return sizeof(unsigned short);
530                 case GL_UNSIGNED_INT:
531                 case GL_UNSIGNED_INT_24_8_OES:
532                         return sizeof(unsigned int);
533                 case GL_FLOAT:
534                         switch(format)
535                         {
536                         case GL_ALPHA:           return sizeof(float);
537                         case GL_LUMINANCE:       return sizeof(float);
538                         case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
539                         case GL_RGB:             return sizeof(float) * 3;
540                         case GL_RGBA:            return sizeof(float) * 4;
541                         default: UNREACHABLE(format);
542                         }
543                         break;
544                 case GL_HALF_FLOAT:
545                 case GL_HALF_FLOAT_OES:
546                         switch(format)
547                         {
548                         case GL_ALPHA:           return sizeof(unsigned short);
549                         case GL_LUMINANCE:       return sizeof(unsigned short);
550                         case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
551                         case GL_RGB:             return sizeof(unsigned short) * 3;
552                         case GL_RGBA:            return sizeof(unsigned short) * 4;
553                         default: UNREACHABLE(format);
554                         }
555                         break;
556                 default: UNREACHABLE(type);
557                 }
558
559                 return 0;
560         }
561
562         GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
563         {
564                 ASSERT(alignment > 0 && sw::isPow2(alignment));
565
566                 GLsizei rawPitch = ComputePixelSize(format, type) * width;
567                 return (rawPitch + alignment - 1) & ~(alignment - 1);
568         }
569
570
571         GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
572         {
573                 return ComputeCompressedSize(width, 1, format);
574         }
575
576         GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
577         {
578                 switch(format)
579                 {
580                 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
581                 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
582         case GL_ETC1_RGB8_OES:
583                 case GL_COMPRESSED_R11_EAC:
584                 case GL_COMPRESSED_SIGNED_R11_EAC:
585                 case GL_COMPRESSED_RGB8_ETC2:
586                 case GL_COMPRESSED_SRGB8_ETC2:
587                 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
588                 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
589                         return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
590                 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
591                 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
592                 case GL_COMPRESSED_RG11_EAC:
593                 case GL_COMPRESSED_SIGNED_RG11_EAC:
594                 case GL_COMPRESSED_RGBA8_ETC2_EAC:
595                 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
596                         return 16 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
597                 default:
598                         return 0;
599                 }
600         }
601
602         Image::~Image()
603         {
604                 ASSERT(referenceCount == 0);
605         }
606
607         void Image::addRef()
608         {
609                 if(parentTexture)
610                 {
611                         return parentTexture->addRef();
612                 }
613                 int newCount = sw::atomicIncrement(&referenceCount);
614                 LOGLOCK("%s image=%p referenceCount=%d", __FUNCTION__, this, newCount);
615         }
616
617         void Image::release()
618         {
619                 if(parentTexture)
620                 {
621                         return parentTexture->release();
622                 }
623
624                 int newCount = sw::atomicDecrement(&referenceCount);
625                 LOGLOCK("%s image=%p referenceCount=%d", __FUNCTION__, this, newCount);
626                 if (newCount == 0)
627                 {
628                         ASSERT(!shared);   // Should still hold a reference if eglDestroyImage hasn't been called
629                         delete this;
630                 }
631         }
632
633         void Image::unbind(const egl::Texture *parent)
634         {
635                 if(parentTexture == parent)
636                 {
637                         parentTexture = 0;
638                 }
639
640                 release();
641         }
642
643         void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const UnpackInfo& unpackInfo, const void *input)
644         {
645                 GLsizei inputPitch  = (unpackInfo.rowLength == 0) ? ComputePitch(width, format, type, unpackInfo.alignment) : unpackInfo.rowLength;
646                 GLsizei inputHeight = (unpackInfo.imageHeight == 0) ? height : unpackInfo.imageHeight;
647                 input = ((char*)input) + (unpackInfo.skipImages * inputHeight + unpackInfo.skipRows) * inputPitch + unpackInfo.skipPixels;
648
649                 if(SelectInternalFormat(format, type) == internalFormat)
650                 {
651                         void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
652
653                         if(buffer)
654                         {
655                                 switch(type)
656                                 {
657                                 case GL_UNSIGNED_BYTE:
658                                         switch(format)
659                                         {
660                                         case GL_ALPHA:
661                                                 LoadImageData<Alpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
662                                                 break;
663                                         case GL_LUMINANCE:
664                                                 LoadImageData<Luminance>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
665                                                 break;
666                                         case GL_LUMINANCE_ALPHA:
667                                                 LoadImageData<LuminanceAlpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
668                                                 break;
669                                         case GL_RGB:
670                                                 LoadImageData<UByteRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
671                                                 break;
672                                         case GL_RGBA:
673                                         case GL_BGRA_EXT:
674                                                 LoadImageData<UByte4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
675                                                 break;
676                                         default: UNREACHABLE(format);
677                                         }
678                                         break;
679                                 case GL_UNSIGNED_SHORT_5_6_5:
680                                         switch(format)
681                                         {
682                                         case GL_RGB:
683                                                 LoadImageData<RGB565>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
684                                                 break;
685                                         default: UNREACHABLE(format);
686                                         }
687                                         break;
688                                 case GL_UNSIGNED_SHORT_4_4_4_4:
689                                         switch(format)
690                                         {
691                                         case GL_RGBA:
692                                                 LoadImageData<RGBA4444>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
693                                                 break;
694                                         default: UNREACHABLE(format);
695                                         }
696                                         break;
697                                 case GL_UNSIGNED_SHORT_5_5_5_1:
698                                         switch(format)
699                                         {
700                                         case GL_RGBA:
701                                                 LoadImageData<RGBA5551>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
702                                                 break;
703                                         default: UNREACHABLE(format);
704                                         }
705                                         break;
706                                 case GL_FLOAT:
707                                         switch(format)
708                                         {
709                                         // float textures are converted to RGBA, not BGRA
710                                         case GL_ALPHA:
711                                                 LoadImageData<AlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
712                                                 break;
713                                         case GL_LUMINANCE:
714                                                 LoadImageData<LuminanceFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
715                                                 break;
716                                         case GL_LUMINANCE_ALPHA:
717                                                 LoadImageData<LuminanceAlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
718                                                 break;
719                                         case GL_RGB:
720                                                 LoadImageData<FloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
721                                                 break;
722                                         case GL_RGBA:
723                                                 LoadImageData<Float4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
724                                                 break;
725                                         default: UNREACHABLE(format);
726                                         }
727                                         break;
728                                 case GL_HALF_FLOAT:
729                                 case GL_HALF_FLOAT_OES:
730                                         switch(format)
731                                         {
732                                         case GL_ALPHA:
733                                                 LoadImageData<AlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
734                                                 break;
735                                         case GL_LUMINANCE:
736                                                 LoadImageData<LuminanceHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
737                                                 break;
738                                         case GL_LUMINANCE_ALPHA:
739                                                 LoadImageData<LuminanceAlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
740                                                 break;
741                                         case GL_RGB:
742                                                 LoadImageData<HalfFloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
743                                                 break;
744                                         case GL_RGBA:
745                                                 LoadImageData<HalfFloat4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
746                                                 break;
747                                         default: UNREACHABLE(format);
748                                         }
749                                         break;
750                                 case GL_UNSIGNED_SHORT:
751                                         LoadImageData<D16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
752                                         break;
753                                 case GL_UNSIGNED_INT:
754                                         LoadImageData<D32>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
755                                         break;
756                                 case GL_UNSIGNED_INT_24_8_OES:
757                                         loadD24S8ImageData(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, input, buffer);
758                                         break;
759                                 default: UNREACHABLE(type);
760                                 }
761                         }
762
763                         unlock();
764                 }
765                 else
766                 {
767                         sw::Surface source(width, height, depth, ConvertFormatType(format, type), const_cast<void*>(input), inputPitch, inputPitch * inputHeight);
768                         sw::Rect sourceRect(0, 0, width, height);
769                         sw::Rect destRect(xoffset, yoffset, xoffset + width, yoffset + height);
770                         sw::blitter.blit(&source, sourceRect, this, destRect, false);
771                 }
772         }
773
774         void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer)
775         {
776                 LoadImageData<D24>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
777
778                 unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, sw::PUBLIC));
779
780                 if(stencil)
781                 {
782                         LoadImageData<S8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getStencilPitchB(), getHeight(), input, stencil);
783
784                         unlockStencil();
785                 }
786         }
787
788         void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
789         {
790                 if(zoffset != 0 || depth != 1)
791                 {
792                         UNIMPLEMENTED();   // FIXME
793                 }
794
795                 int inputPitch = ComputeCompressedPitch(width, format);
796                 int rows = imageSize / inputPitch;
797                 void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
798
799                 if(buffer)
800                 {
801                         for(int i = 0; i < rows; i++)
802                         {
803                                 memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
804                         }
805                 }
806
807                 unlock();
808         }
809 }