OSDN Git Service

Implement support for YV12 texture sampling.
[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 if(format == SW_YV12_BT601)
474                         {
475                                 return sw::FORMAT_YV12_BT601;
476                         }
477                         else if(format == SW_YV12_BT709)
478                         {
479                                 return sw::FORMAT_YV12_BT709;
480                         }
481                         else if(format == SW_YV12_JFIF)
482                         {
483                                 return sw::FORMAT_YV12_JFIF;
484                         }
485                         else UNREACHABLE(format);
486                 }
487                 else if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT)
488                 {
489                         if(format == GL_DEPTH_COMPONENT)
490                         {
491                                 return sw::FORMAT_D32FS8_TEXTURE;
492                         }
493                         else UNREACHABLE(format);
494                 }
495                 else if(type == GL_UNSIGNED_INT_24_8_OES)
496                 {
497                         if(format == GL_DEPTH_STENCIL_OES)
498                         {
499                                 return sw::FORMAT_D32FS8_TEXTURE;
500                         }
501                         else UNREACHABLE(format);
502                 }
503                 else if(type == GL_UNSIGNED_SHORT_4_4_4_4)
504                 {
505                         return sw::FORMAT_A8R8G8B8;
506                 }
507                 else if(type == GL_UNSIGNED_SHORT_5_5_5_1)
508                 {
509                         return sw::FORMAT_A8R8G8B8;
510                 }
511                 else if(type == GL_UNSIGNED_SHORT_5_6_5)
512                 {
513                         return sw::FORMAT_X8R8G8B8;
514                 }
515                 else UNREACHABLE(type);
516
517                 return sw::FORMAT_A8B8G8R8;
518         }
519
520         // Returns the size, in bytes, of a single texel in an Image
521         static int ComputePixelSize(GLenum format, GLenum type)
522         {
523                 switch(type)
524                 {
525                 case GL_UNSIGNED_BYTE:
526                         switch(format)
527                         {
528                         case GL_ALPHA:           return sizeof(unsigned char);
529                         case GL_LUMINANCE:       return sizeof(unsigned char);
530                         case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
531                         case GL_RGB:             return sizeof(unsigned char) * 3;
532                         case GL_RGBA:            return sizeof(unsigned char) * 4;
533                         case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
534                         default: UNREACHABLE(format);
535                         }
536                         break;
537                 case GL_UNSIGNED_SHORT_4_4_4_4:
538                 case GL_UNSIGNED_SHORT_5_5_5_1:
539                 case GL_UNSIGNED_SHORT_5_6_5:
540                 case GL_UNSIGNED_SHORT:
541                         return sizeof(unsigned short);
542                 case GL_UNSIGNED_INT:
543                 case GL_UNSIGNED_INT_24_8_OES:
544                         return sizeof(unsigned int);
545                 case GL_FLOAT:
546                         switch(format)
547                         {
548                         case GL_ALPHA:           return sizeof(float);
549                         case GL_LUMINANCE:       return sizeof(float);
550                         case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
551                         case GL_RGB:             return sizeof(float) * 3;
552                         case GL_RGBA:            return sizeof(float) * 4;
553                         default: UNREACHABLE(format);
554                         }
555                         break;
556                 case GL_HALF_FLOAT:
557                 case GL_HALF_FLOAT_OES:
558                         switch(format)
559                         {
560                         case GL_ALPHA:           return sizeof(unsigned short);
561                         case GL_LUMINANCE:       return sizeof(unsigned short);
562                         case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
563                         case GL_RGB:             return sizeof(unsigned short) * 3;
564                         case GL_RGBA:            return sizeof(unsigned short) * 4;
565                         default: UNREACHABLE(format);
566                         }
567                         break;
568                 default: UNREACHABLE(type);
569                 }
570
571                 return 0;
572         }
573
574         GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
575         {
576                 ASSERT(alignment > 0 && sw::isPow2(alignment));
577
578                 GLsizei rawPitch = ComputePixelSize(format, type) * width;
579                 return (rawPitch + alignment - 1) & ~(alignment - 1);
580         }
581
582
583         GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
584         {
585                 return ComputeCompressedSize(width, 1, format);
586         }
587
588         GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
589         {
590                 switch(format)
591                 {
592                 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
593                 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
594         case GL_ETC1_RGB8_OES:
595                 case GL_COMPRESSED_R11_EAC:
596                 case GL_COMPRESSED_SIGNED_R11_EAC:
597                 case GL_COMPRESSED_RGB8_ETC2:
598                 case GL_COMPRESSED_SRGB8_ETC2:
599                 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
600                 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
601                         return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
602                 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
603                 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
604                 case GL_COMPRESSED_RG11_EAC:
605                 case GL_COMPRESSED_SIGNED_RG11_EAC:
606                 case GL_COMPRESSED_RGBA8_ETC2_EAC:
607                 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
608                         return 16 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
609                 default:
610                         return 0;
611                 }
612         }
613
614         Image::~Image()
615         {
616                 ASSERT(referenceCount == 0);
617         }
618
619         void Image::addRef()
620         {
621                 if(parentTexture)
622                 {
623                         return parentTexture->addRef();
624                 }
625                 int newCount = sw::atomicIncrement(&referenceCount);
626                 LOGLOCK("%s image=%p referenceCount=%d", __FUNCTION__, this, newCount);
627         }
628
629         void Image::release()
630         {
631                 if(parentTexture)
632                 {
633                         return parentTexture->release();
634                 }
635
636                 int newCount = sw::atomicDecrement(&referenceCount);
637                 LOGLOCK("%s image=%p referenceCount=%d", __FUNCTION__, this, newCount);
638                 if (newCount == 0)
639                 {
640                         ASSERT(!shared);   // Should still hold a reference if eglDestroyImage hasn't been called
641                         delete this;
642                 }
643         }
644
645         void Image::unbind(const egl::Texture *parent)
646         {
647                 if(parentTexture == parent)
648                 {
649                         parentTexture = 0;
650                 }
651
652                 release();
653         }
654
655         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)
656         {
657                 GLsizei inputPitch  = (unpackInfo.rowLength == 0) ? ComputePitch(width, format, type, unpackInfo.alignment) : unpackInfo.rowLength;
658                 GLsizei inputHeight = (unpackInfo.imageHeight == 0) ? height : unpackInfo.imageHeight;
659                 input = ((char*)input) + (unpackInfo.skipImages * inputHeight + unpackInfo.skipRows) * inputPitch + unpackInfo.skipPixels;
660
661                 if(SelectInternalFormat(format, type) == internalFormat)
662                 {
663                         void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
664
665                         if(buffer)
666                         {
667                                 switch(type)
668                                 {
669                                 case GL_UNSIGNED_BYTE:
670                                         switch(format)
671                                         {
672                                         case GL_ALPHA:
673                                                 LoadImageData<Alpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
674                                                 break;
675                                         case GL_LUMINANCE:
676                                                 LoadImageData<Luminance>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
677                                                 break;
678                                         case GL_LUMINANCE_ALPHA:
679                                                 LoadImageData<LuminanceAlpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
680                                                 break;
681                                         case GL_RGB:
682                                                 LoadImageData<UByteRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
683                                                 break;
684                                         case GL_RGBA:
685                                         case GL_BGRA_EXT:
686                                                 LoadImageData<UByte4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
687                                                 break;
688                                         default: UNREACHABLE(format);
689                                         }
690                                         break;
691                                 case GL_UNSIGNED_SHORT_5_6_5:
692                                         switch(format)
693                                         {
694                                         case GL_RGB:
695                                                 LoadImageData<RGB565>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
696                                                 break;
697                                         default: UNREACHABLE(format);
698                                         }
699                                         break;
700                                 case GL_UNSIGNED_SHORT_4_4_4_4:
701                                         switch(format)
702                                         {
703                                         case GL_RGBA:
704                                                 LoadImageData<RGBA4444>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
705                                                 break;
706                                         default: UNREACHABLE(format);
707                                         }
708                                         break;
709                                 case GL_UNSIGNED_SHORT_5_5_5_1:
710                                         switch(format)
711                                         {
712                                         case GL_RGBA:
713                                                 LoadImageData<RGBA5551>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
714                                                 break;
715                                         default: UNREACHABLE(format);
716                                         }
717                                         break;
718                                 case GL_FLOAT:
719                                         switch(format)
720                                         {
721                                         // float textures are converted to RGBA, not BGRA
722                                         case GL_ALPHA:
723                                                 LoadImageData<AlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
724                                                 break;
725                                         case GL_LUMINANCE:
726                                                 LoadImageData<LuminanceFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
727                                                 break;
728                                         case GL_LUMINANCE_ALPHA:
729                                                 LoadImageData<LuminanceAlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
730                                                 break;
731                                         case GL_RGB:
732                                                 LoadImageData<FloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
733                                                 break;
734                                         case GL_RGBA:
735                                                 LoadImageData<Float4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
736                                                 break;
737                                         default: UNREACHABLE(format);
738                                         }
739                                         break;
740                                 case GL_HALF_FLOAT:
741                                 case GL_HALF_FLOAT_OES:
742                                         switch(format)
743                                         {
744                                         case GL_ALPHA:
745                                                 LoadImageData<AlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
746                                                 break;
747                                         case GL_LUMINANCE:
748                                                 LoadImageData<LuminanceHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
749                                                 break;
750                                         case GL_LUMINANCE_ALPHA:
751                                                 LoadImageData<LuminanceAlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
752                                                 break;
753                                         case GL_RGB:
754                                                 LoadImageData<HalfFloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
755                                                 break;
756                                         case GL_RGBA:
757                                                 LoadImageData<HalfFloat4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
758                                                 break;
759                                         default: UNREACHABLE(format);
760                                         }
761                                         break;
762                                 case GL_UNSIGNED_SHORT:
763                                         LoadImageData<D16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
764                                         break;
765                                 case GL_UNSIGNED_INT:
766                                         LoadImageData<D32>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
767                                         break;
768                                 case GL_UNSIGNED_INT_24_8_OES:
769                                         loadD24S8ImageData(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, input, buffer);
770                                         break;
771                                 default: UNREACHABLE(type);
772                                 }
773                         }
774
775                         unlock();
776                 }
777                 else
778                 {
779                         sw::Surface source(width, height, depth, ConvertFormatType(format, type), const_cast<void*>(input), inputPitch, inputPitch * inputHeight);
780                         sw::Rect sourceRect(0, 0, width, height);
781                         sw::Rect destRect(xoffset, yoffset, xoffset + width, yoffset + height);
782                         sw::blitter.blit(&source, sourceRect, this, destRect, false);
783                 }
784         }
785
786         void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer)
787         {
788                 LoadImageData<D24>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
789
790                 unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, sw::PUBLIC));
791
792                 if(stencil)
793                 {
794                         LoadImageData<S8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getStencilPitchB(), getHeight(), input, stencil);
795
796                         unlockStencil();
797                 }
798         }
799
800         void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
801         {
802                 if(zoffset != 0 || depth != 1)
803                 {
804                         UNIMPLEMENTED();   // FIXME
805                 }
806
807                 int inputPitch = ComputeCompressedPitch(width, format);
808                 int rows = imageSize / inputPitch;
809                 void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
810
811                 if(buffer)
812                 {
813                         for(int i = 0; i < rows; i++)
814                         {
815                                 memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
816                         }
817                 }
818
819                 unlock();
820         }
821 }