OSDN Git Service

Pixel store parameters
[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 "../libEGL/Texture.hpp"
15 #include "../common/debug.h"
16 #include "Common/Thread.hpp"
17
18 #define GL_GLEXT_PROTOTYPES
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 *dest565 = dest + xoffset * 4;
186
187                 for(int x = 0; x < width; x++)
188                 {
189                         unsigned short rgba = source565[x];
190                         dest565[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
191                         dest565[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
192                         dest565[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
193                         dest565[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         // Returns the size, in bytes, of a single texel in an Image
346         int ComputePixelSize(GLenum format, GLenum type)
347         {
348                 switch(type)
349                 {
350                 case GL_UNSIGNED_BYTE:
351                         switch(format)
352                         {
353                         case GL_ALPHA:           return sizeof(unsigned char);
354                         case GL_LUMINANCE:       return sizeof(unsigned char);
355                         case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
356                         case GL_RGB:             return sizeof(unsigned char) * 3;
357                         case GL_RGBA:            return sizeof(unsigned char) * 4;
358                         case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
359                         default: UNREACHABLE();
360                         }
361                         break;
362                 case GL_UNSIGNED_SHORT_4_4_4_4:
363                 case GL_UNSIGNED_SHORT_5_5_5_1:
364                 case GL_UNSIGNED_SHORT_5_6_5:
365                 case GL_UNSIGNED_SHORT:
366                         return sizeof(unsigned short);
367                 case GL_UNSIGNED_INT:
368                 case GL_UNSIGNED_INT_24_8_OES:
369                         return sizeof(unsigned int);
370                 case GL_FLOAT:
371                         switch(format)
372                         {
373                         case GL_ALPHA:           return sizeof(float);
374                         case GL_LUMINANCE:       return sizeof(float);
375                         case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
376                         case GL_RGB:             return sizeof(float) * 3;
377                         case GL_RGBA:            return sizeof(float) * 4;
378                         default: UNREACHABLE();
379                         }
380                         break;
381                 case GL_HALF_FLOAT_OES:
382                         switch(format)
383                         {
384                         case GL_ALPHA:           return sizeof(unsigned short);
385                         case GL_LUMINANCE:       return sizeof(unsigned short);
386                         case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
387                         case GL_RGB:             return sizeof(unsigned short) * 3;
388                         case GL_RGBA:            return sizeof(unsigned short) * 4;
389                         default: UNREACHABLE();
390                         }
391                         break;
392                 default: UNREACHABLE();
393                 }
394
395                 return 0;
396         }
397
398         GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
399         {
400                 ASSERT(alignment > 0 && sw::isPow2(alignment));
401
402                 GLsizei rawPitch = ComputePixelSize(format, type) * width;
403                 return (rawPitch + alignment - 1) & ~(alignment - 1);
404         }
405
406
407         GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
408         {
409                 return ComputeCompressedSize(width, 1, format);
410         }
411
412         GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
413         {
414                 switch(format)
415                 {
416                 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
417                 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
418         case GL_ETC1_RGB8_OES:
419                 case GL_COMPRESSED_R11_EAC:
420                 case GL_COMPRESSED_SIGNED_R11_EAC:
421                 case GL_COMPRESSED_RGB8_ETC2:
422                 case GL_COMPRESSED_SRGB8_ETC2:
423                 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
424                 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
425                         return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
426                 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
427                 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
428                 case GL_COMPRESSED_RG11_EAC:
429                 case GL_COMPRESSED_SIGNED_RG11_EAC:
430                 case GL_COMPRESSED_RGBA8_ETC2_EAC:
431                 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
432                         return 16 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
433                 default:
434                         return 0;
435                 }
436         }
437
438         Image::~Image()
439         {
440                 ASSERT(referenceCount == 0);
441         }
442
443         void Image::addRef()
444         {
445                 if(parentTexture)
446                 {
447                         return parentTexture->addRef();
448                 }
449                 int newCount = sw::atomicIncrement(&referenceCount);
450                 LOGLOCK("%s image=%p referenceCount=%d", __FUNCTION__, this, newCount);
451         }
452
453         void Image::release()
454         {
455                 if(parentTexture)
456                 {
457                         return parentTexture->release();
458                 }
459
460                 int newCount = sw::atomicDecrement(&referenceCount);
461                 LOGLOCK("%s image=%p referenceCount=%d", __FUNCTION__, this, newCount);
462                 if (newCount == 0)
463                 {
464                         ASSERT(!shared);   // Should still hold a reference if eglDestroyImage hasn't been called
465                         delete this;
466                 }
467         }
468
469         void Image::unbind(const egl::Texture *parent)
470         {
471                 if(parentTexture == parent)
472                 {
473                         parentTexture = 0;
474                 }
475
476                 release();
477         }
478
479         sw::Format Image::selectInternalFormat(GLenum format, GLenum type)
480         {
481                 if(format == GL_ETC1_RGB8_OES)
482                 {
483                         return sw::FORMAT_ETC1;
484                 }
485                 else
486                 #if S3TC_SUPPORT
487                 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
488                    format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
489                 {
490                         return sw::FORMAT_DXT1;
491                 }
492                 else if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE)
493                 {
494                         return sw::FORMAT_DXT3;
495                 }
496                 else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)
497                 {
498                         return sw::FORMAT_DXT5;
499                 }
500                 else
501                 #endif
502                 if(type == GL_FLOAT)
503                 {
504                         return sw::FORMAT_A32B32G32R32F;
505                 }
506                 else if(type == GL_HALF_FLOAT_OES)
507                 {
508                         return sw::FORMAT_A16B16G16R16F;
509                 }
510                 else if(type == GL_UNSIGNED_BYTE)
511                 {
512                         if(format == GL_LUMINANCE)
513                         {
514                                 return sw::FORMAT_L8;
515                         }
516                         else if(format == GL_LUMINANCE_ALPHA)
517                         {
518                                 return sw::FORMAT_A8L8;
519                         }
520                         else if(format == GL_RGBA)
521                         {
522                                 return sw::FORMAT_A8B8G8R8;
523                         }
524                         else if(format == GL_BGRA_EXT)
525                         {
526                                 return sw::FORMAT_A8R8G8B8;
527                         }
528                         else if(format == GL_RGB)
529                         {
530                                 return sw::FORMAT_X8B8G8R8;
531                         }
532                         else if(format == GL_ALPHA)
533                         {
534                                 return sw::FORMAT_A8;
535                         }
536                         else UNREACHABLE();
537                 }
538                 else if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT)
539                 {
540                         if(format == GL_DEPTH_COMPONENT)
541                         {
542                                 return sw::FORMAT_D32FS8_TEXTURE;
543                         }
544                         else UNREACHABLE();
545                 }
546                 else if(type == GL_UNSIGNED_INT_24_8_OES)
547                 {
548                         if(format == GL_DEPTH_STENCIL_OES)
549                         {
550                                 return sw::FORMAT_D32FS8_TEXTURE;
551                         }
552                         else UNREACHABLE();
553                 }
554                 else if(type == GL_UNSIGNED_SHORT_4_4_4_4)
555                 {
556                         return sw::FORMAT_A8R8G8B8;
557                 }
558                 else if(type == GL_UNSIGNED_SHORT_5_5_5_1)
559                 {
560                         return sw::FORMAT_A8R8G8B8;
561                 }
562                 else if(type == GL_UNSIGNED_SHORT_5_6_5)
563                 {
564                         return sw::FORMAT_X8R8G8B8;
565                 }
566                 else UNREACHABLE();
567
568                 return sw::FORMAT_A8B8G8R8;
569         }
570
571         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)
572         {
573                 GLsizei inputPitch  = (unpackInfo.rowLength == 0) ? ComputePitch(width, format, type, unpackInfo.alignment) : unpackInfo.rowLength;
574                 GLsizei inputHeight = (unpackInfo.imageHeight == 0) ? height : unpackInfo.imageHeight;
575                 input = ((char*)input) + (unpackInfo.skipImages * inputHeight + unpackInfo.skipRows) * inputPitch + unpackInfo.skipPixels;
576                 void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
577
578                 if(buffer)
579                 {
580                         switch(type)
581                         {
582                         case GL_UNSIGNED_BYTE:
583                                 switch(format)
584                                 {
585                                 case GL_ALPHA:
586                                         LoadImageData<Alpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
587                                         break;
588                                 case GL_LUMINANCE:
589                                         LoadImageData<Luminance>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
590                                         break;
591                                 case GL_LUMINANCE_ALPHA:
592                                         LoadImageData<LuminanceAlpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
593                                         break;
594                                 case GL_RGB:
595                                         LoadImageData<UByteRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
596                                         break;
597                                 case GL_RGBA:
598                                 case GL_BGRA_EXT:
599                                         LoadImageData<UByte4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
600                                         break;
601                                 default: UNREACHABLE();
602                                 }
603                                 break;
604                         case GL_UNSIGNED_SHORT_5_6_5:
605                                 switch(format)
606                                 {
607                                 case GL_RGB:
608                                         LoadImageData<RGB565>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
609                                         break;
610                                 default: UNREACHABLE();
611                                 }
612                                 break;
613                         case GL_UNSIGNED_SHORT_4_4_4_4:
614                                 switch(format)
615                                 {
616                                 case GL_RGBA:
617                                         LoadImageData<RGBA4444>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
618                                         break;
619                                 default: UNREACHABLE();
620                                 }
621                                 break;
622                         case GL_UNSIGNED_SHORT_5_5_5_1:
623                                 switch(format)
624                                 {
625                                 case GL_RGBA:
626                                         LoadImageData<RGBA5551>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
627                                         break;
628                                 default: UNREACHABLE();
629                                 }
630                                 break;
631                         case GL_FLOAT:
632                                 switch(format)
633                                 {
634                                 // float textures are converted to RGBA, not BGRA
635                                 case GL_ALPHA:
636                                         LoadImageData<AlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
637                                         break;
638                                 case GL_LUMINANCE:
639                                         LoadImageData<LuminanceFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
640                                         break;
641                                 case GL_LUMINANCE_ALPHA:
642                                         LoadImageData<LuminanceAlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
643                                         break;
644                                 case GL_RGB:
645                                         LoadImageData<FloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
646                                         break;
647                                 case GL_RGBA:
648                                         LoadImageData<Float4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
649                                         break;
650                                 default: UNREACHABLE();
651                                 }
652                                 break;
653                         case GL_HALF_FLOAT_OES:
654                                 switch(format)
655                                 {
656                                 case GL_ALPHA:
657                                         LoadImageData<AlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
658                                         break;
659                                 case GL_LUMINANCE:
660                                         LoadImageData<LuminanceHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
661                                         break;
662                                 case GL_LUMINANCE_ALPHA:
663                                         LoadImageData<LuminanceAlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
664                                         break;
665                                 case GL_RGB:
666                                         LoadImageData<HalfFloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
667                                         break;
668                                 case GL_RGBA:
669                                         LoadImageData<HalfFloat4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
670                                         break;
671                                 default: UNREACHABLE();
672                                 }
673                                 break;
674                         case GL_UNSIGNED_SHORT:
675                                 LoadImageData<D16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
676                                 break;
677                         case GL_UNSIGNED_INT:
678                                 LoadImageData<D32>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
679                                 break;
680                         case GL_UNSIGNED_INT_24_8_OES:
681                                 loadD24S8ImageData(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, input, buffer);
682                                 break;
683                         default: UNREACHABLE();
684                         }
685                 }
686
687                 unlock();
688         }
689
690         void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer)
691         {
692                 LoadImageData<D24>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
693
694                 unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, sw::PUBLIC));
695
696                 if(stencil)
697                 {
698                         LoadImageData<S8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getStencilPitchB(), getHeight(), input, stencil);
699
700                         unlockStencil();
701                 }
702         }
703
704         void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
705         {
706                 if(zoffset != 0 || depth != 1)
707                 {
708                         UNIMPLEMENTED();   // FIXME
709                 }
710
711                 int inputPitch = ComputeCompressedPitch(width, format);
712                 int rows = imageSize / inputPitch;
713                 void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
714
715                 if(buffer)
716                 {
717                         for(int i = 0; i < rows; i++)
718                         {
719                                 memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
720                         }
721                 }
722
723                 unlock();
724         }
725 }