OSDN Git Service

Implement a Radiance prototype.
[android-x86/external-swiftshader.git] / src / Radiance / libRAD / 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 "Texture.h"
15 #include "utilities.h"
16 #include "../common/debug.h"
17 #include "Common/Thread.hpp"
18
19 #include <GLES2/gl2ext.h>
20
21 namespace es2
22 {
23         static sw::Resource *getParentResource(Texture *texture)
24         {
25                 if(texture)
26                 {
27                         return texture->getResource();
28                 }
29
30                 return 0;
31         }
32
33         Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
34                 : parentTexture(parentTexture)
35                 , egl::Image(getParentResource(parentTexture), width, height, format, type, selectInternalFormat(format, type))
36         {
37                 referenceCount = 1;
38         }
39
40         Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget)
41                 : parentTexture(parentTexture)
42                 , egl::Image(getParentResource(parentTexture), width, height, multiSampleDepth, internalFormat, lockable, renderTarget)
43         {
44                 referenceCount = 1;
45         }
46
47         Image::~Image()
48         {
49                 ASSERT(referenceCount == 0);
50         }
51
52         void Image::addRef()
53         {
54                 if(parentTexture)
55                 {
56                         parentTexture->addRef();
57                 }
58
59                 sw::atomicIncrement(&referenceCount);
60         }
61
62         void Image::release()
63         {
64                 if(parentTexture)
65                 {
66                         parentTexture->release();
67                 }
68
69                 if(referenceCount > 0)
70                 {
71                         sw::atomicDecrement(&referenceCount);
72                 }
73
74                 if(referenceCount == 0)
75                 {
76                         delete this;
77                 }
78         }
79
80         void Image::unbind()
81         {
82                 parentTexture = 0;
83
84                 release();
85         }
86
87         sw::Format Image::selectInternalFormat(GLenum format, GLenum type)
88         {
89                 #if S3TC_SUPPORT
90                 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
91                    format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
92                 {
93                         return sw::FORMAT_DXT1;
94                 }
95                 else if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE)
96                 {
97                         return sw::FORMAT_DXT3;
98                 }
99                 else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)
100                 {
101                         return sw::FORMAT_DXT5;
102                 }
103                 else
104                 #endif
105                 if(type == GL_FLOAT)
106                 {
107                         return sw::FORMAT_A32B32G32R32F;
108                 }
109                 else if(type == GL_HALF_FLOAT_OES)
110                 {
111                         return sw::FORMAT_A16B16G16R16F;
112                 }
113                 else if(type == GL_UNSIGNED_BYTE)
114                 {
115                         if(format == GL_LUMINANCE)
116                         {
117                                 return sw::FORMAT_L8;
118                         }
119                         else if(format == GL_LUMINANCE_ALPHA)
120                         {
121                                 return sw::FORMAT_A8L8;
122                         }
123                         else if(format == GL_RGBA || format == GL_BGRA_EXT)
124                         {
125                                 return sw::FORMAT_A8R8G8B8;
126                         }
127                         else if(format == GL_RGB)
128                         {
129                                 return sw::FORMAT_X8R8G8B8;
130                         }
131                         else if(format == GL_ALPHA)
132                         {
133                                 return sw::FORMAT_A8;
134                         }
135                         else UNREACHABLE();
136                 }
137                 else if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT)
138                 {
139                         if(format == GL_DEPTH_COMPONENT)
140                         {
141                                 return sw::FORMAT_D32FS8_TEXTURE;
142                         }
143                         else UNREACHABLE();
144                 }
145                 else if(type == GL_UNSIGNED_INT_24_8_OES)
146                 {
147                         if(format == GL_DEPTH_STENCIL_OES)
148                         {
149                                 return sw::FORMAT_D32FS8_TEXTURE;
150                         }
151                         else UNREACHABLE();
152                 }
153                 else if(type == GL_UNSIGNED_SHORT_4_4_4_4)
154                 {
155                         return sw::FORMAT_A8R8G8B8;
156                 }
157                 else if(type == GL_UNSIGNED_SHORT_5_5_5_1)
158                 {
159                         return sw::FORMAT_A8R8G8B8;
160                 }
161                 else if(type == GL_UNSIGNED_SHORT_5_6_5)
162                 {
163                         return sw::FORMAT_X8R8G8B8;
164                 }
165                 else UNREACHABLE();
166
167                 return sw::FORMAT_A8R8G8B8;
168         }
169
170         void Image::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
171         {
172                 GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
173                 void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
174                 
175                 if(buffer)
176                 {
177                         switch(type)
178                         {
179                         case GL_UNSIGNED_BYTE:
180                                 switch(format)
181                                 {
182                                 case GL_ALPHA:
183                                         loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
184                                         break;
185                                 case GL_LUMINANCE:
186                                         loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
187                                         break;
188                                 case GL_LUMINANCE_ALPHA:
189                                         loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
190                                         break;
191                                 case GL_RGB:
192                                         loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
193                                         break;
194                                 case GL_RGBA:
195                                         loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
196                                         break;
197                                 case GL_BGRA_EXT:
198                                         loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
199                                         break;
200                                 default: UNREACHABLE();
201                                 }
202                                 break;
203                         case GL_UNSIGNED_SHORT_5_6_5:
204                                 switch(format)
205                                 {
206                                 case GL_RGB:
207                                         loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
208                                         break;
209                                 default: UNREACHABLE();
210                                 }
211                                 break;
212                         case GL_UNSIGNED_SHORT_4_4_4_4:
213                                 switch(format)
214                                 {
215                                 case GL_RGBA:
216                                         loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
217                                         break;
218                                 default: UNREACHABLE();
219                                 }
220                                 break;
221                         case GL_UNSIGNED_SHORT_5_5_5_1:
222                                 switch(format)
223                                 {
224                                 case GL_RGBA:
225                                         loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
226                                         break;
227                                 default: UNREACHABLE();
228                                 }
229                                 break;
230                         case GL_FLOAT:
231                                 switch(format)
232                                 {
233                                 // float textures are converted to RGBA, not BGRA
234                                 case GL_ALPHA:
235                                         loadAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
236                                         break;
237                                 case GL_LUMINANCE:
238                                         loadLuminanceFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
239                                         break;
240                                 case GL_LUMINANCE_ALPHA:
241                                         loadLuminanceAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
242                                         break;
243                                 case GL_RGB:
244                                         loadRGBFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
245                                         break;
246                                 case GL_RGBA:
247                                         loadRGBAFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
248                                         break;
249                                 default: UNREACHABLE();
250                                 }
251                                 break;
252                           case GL_HALF_FLOAT_OES:
253                                 switch(format)
254                                 {
255                                 // float textures are converted to RGBA, not BGRA
256                                 case GL_ALPHA:
257                                         loadAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
258                                         break;
259                                 case GL_LUMINANCE:
260                                         loadLuminanceHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
261                                         break;
262                                 case GL_LUMINANCE_ALPHA:
263                                         loadLuminanceAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
264                                         break;
265                                 case GL_RGB:
266                                         loadRGBHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
267                                         break;
268                                 case GL_RGBA:
269                                         loadRGBAHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
270                                         break;
271                                 default: UNREACHABLE();
272                                 }
273                                 break;
274                         case GL_UNSIGNED_SHORT:
275                                 loadD16ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
276                                 break;
277                         case GL_UNSIGNED_INT:
278                                 loadD32ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
279                                 break;
280                         case GL_UNSIGNED_INT_24_8_OES:
281                                 loadD24S8ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
282                                 break;
283                         default: UNREACHABLE();
284                         }
285                 }
286
287                 unlock();
288         }
289
290         void Image::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
291         {
292                 for(int y = 0; y < height; y++)
293                 {
294                         const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
295                         unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset;
296
297                         memcpy(dest, source, width);
298                 }
299         }
300
301         void Image::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
302         {
303                 for(int y = 0; y < height; y++)
304                 {
305                         const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
306                         float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
307                         
308                         for(int x = 0; x < width; x++)
309                         {
310                                 dest[4 * x + 0] = 0;
311                                 dest[4 * x + 1] = 0;
312                                 dest[4 * x + 2] = 0;
313                                 dest[4 * x + 3] = source[x];
314                         }
315                 }
316         }
317
318         void Image::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
319         {
320                 for(int y = 0; y < height; y++)
321                 {
322                         const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
323                         unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
324                         
325                         for(int x = 0; x < width; x++)
326                         {
327                                 dest[4 * x + 0] = 0;
328                                 dest[4 * x + 1] = 0;
329                                 dest[4 * x + 2] = 0;
330                                 dest[4 * x + 3] = source[x];
331                         }
332                 }
333         }
334
335         void Image::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
336         {
337                 for(int y = 0; y < height; y++)
338                 {
339                         const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
340                         unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset;
341
342                         memcpy(dest, source, width);
343                 }
344         }
345
346         void Image::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
347         {
348                 for(int y = 0; y < height; y++)
349                 {
350                         const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
351                         float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
352                         
353                         for(int x = 0; x < width; x++)
354                         {
355                                 dest[4 * x + 0] = source[x];
356                                 dest[4 * x + 1] = source[x];
357                                 dest[4 * x + 2] = source[x];
358                                 dest[4 * x + 3] = 1.0f;
359                         }
360                 }
361         }
362
363         void Image::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
364         {
365                 for(int y = 0; y < height; y++)
366                 {
367                         const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
368                         unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
369                         
370                         for(int x = 0; x < width; x++)
371                         {
372                                 dest[4 * x + 0] = source[x];
373                                 dest[4 * x + 1] = source[x];
374                                 dest[4 * x + 2] = source[x];
375                                 dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
376                         }
377                 }
378         }
379
380         void Image::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
381         {
382                 for(int y = 0; y < height; y++)
383                 {
384                         const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
385                         unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
386         
387                         memcpy(dest, source, width * 2);
388                 }
389         }
390
391         void Image::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
392         {
393                 for(int y = 0; y < height; y++)
394                 {
395                         const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
396                         float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
397                         
398                         for(int x = 0; x < width; x++)
399                         {
400                                 dest[4 * x + 0] = source[2*x+0];
401                                 dest[4 * x + 1] = source[2*x+0];
402                                 dest[4 * x + 2] = source[2*x+0];
403                                 dest[4 * x + 3] = source[2*x+1];
404                         }
405                 }
406         }
407
408         void Image::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
409         {
410                 for(int y = 0; y < height; y++)
411                 {
412                         const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
413                         unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
414                         
415                         for(int x = 0; x < width; x++)
416                         {
417                                 dest[4 * x + 0] = source[2*x+0];
418                                 dest[4 * x + 1] = source[2*x+0];
419                                 dest[4 * x + 2] = source[2*x+0];
420                                 dest[4 * x + 3] = source[2*x+1];
421                         }
422                 }
423         }
424
425         void Image::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
426         {
427                 for(int y = 0; y < height; y++)
428                 {
429                         const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
430                         unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
431                         
432                         for(int x = 0; x < width; x++)
433                         {
434                                 dest[4 * x + 0] = source[x * 3 + 2];
435                                 dest[4 * x + 1] = source[x * 3 + 1];
436                                 dest[4 * x + 2] = source[x * 3 + 0];
437                                 dest[4 * x + 3] = 0xFF;
438                         }
439                 }
440         }
441
442         void Image::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
443         {
444                 for(int y = 0; y < height; y++)
445                 {
446                         const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
447                         unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
448                         
449                         for(int x = 0; x < width; x++)
450                         {
451                                 unsigned short rgba = source[x];
452                                 dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
453                                 dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
454                                 dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
455                                 dest[4 * x + 3] = 0xFF;
456                         }
457                 }
458         }
459
460         void Image::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
461         {
462                 for(int y = 0; y < height; y++)
463                 {
464                         const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
465                         float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
466                         
467                         for(int x = 0; x < width; x++)
468                         {
469                                 dest[4 * x + 0] = source[x * 3 + 0];
470                                 dest[4 * x + 1] = source[x * 3 + 1];
471                                 dest[4 * x + 2] = source[x * 3 + 2];
472                                 dest[4 * x + 3] = 1.0f;
473                         }
474                 }
475         }
476
477         void Image::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
478         {
479                 for(int y = 0; y < height; y++)
480                 {
481                         const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
482                         unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
483                         
484                         for(int x = 0; x < width; x++)
485                         {
486                                 dest[4 * x + 0] = source[x * 3 + 0];
487                                 dest[4 * x + 1] = source[x * 3 + 1];
488                                 dest[4 * x + 2] = source[x * 3 + 2];
489                                 dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
490                         }
491                 }
492         }
493
494         void Image::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
495         {
496                 for(int y = 0; y < height; y++)
497                 {
498                         const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
499                         unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
500
501                         for(int x = 0; x < width; x++)
502                         {
503                                 unsigned int rgba = source[x];
504                                 dest[x] = (rgba & 0xFF00FF00) | ((rgba << 16) & 0x00FF0000) | ((rgba >> 16) & 0x000000FF);
505                         }
506                 }
507         }
508
509         void Image::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
510         {
511                 for(int y = 0; y < height; y++)
512                 {
513                         const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
514                         unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
515                         
516                         for(int x = 0; x < width; x++)
517                         {
518                                 unsigned short rgba = source[x];
519                                 dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
520                                 dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
521                                 dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
522                                 dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
523                         }
524                 }
525         }
526
527         void Image::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
528         {
529                 for(int y = 0; y < height; y++)
530                 {
531                         const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
532                         unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
533                         
534                         for(int x = 0; x < width; x++)
535                         {
536                                 unsigned short rgba = source[x];
537                                 dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
538                                 dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
539                                 dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
540                                 dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
541                         }
542                 }
543         }
544
545         void Image::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
546         {
547                 for(int y = 0; y < height; y++)
548                 {
549                         const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
550                         float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
551                         
552                         memcpy(dest, source, width * 16);
553                 }
554         }
555
556         void Image::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
557         {
558                 for(int y = 0; y < height; y++)
559                 {
560                         const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
561                         unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8;
562                         
563                         memcpy(dest, source, width * 8);
564                 }
565         }
566
567         void Image::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
568         {
569                 for(int y = 0; y < height; y++)
570                 {
571                         const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
572                         unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
573                         
574                         memcpy(dest, source, width*4);
575                 }
576         }
577
578         void Image::loadD16ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
579         {
580                 for(int y = 0; y < height; y++)
581                 {
582                         const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
583                         float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
584
585                         for(int x = 0; x < width; x++)
586                         {
587                                 dest[x] = (float)source[x] / 0xFFFF;
588                         }
589                 }
590         }
591
592         void Image::loadD32ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
593         {
594                 for(int y = 0; y < height; y++)
595                 {
596                         const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
597                         float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
598
599                         for(int x = 0; x < width; x++)
600                         {
601                                 dest[x] = (float)source[x] / 0xFFFFFFFF;
602                         }
603                 }
604         }
605
606         void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer)
607         {
608                 for(int y = 0; y < height; y++)
609                 {
610                         const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
611                         float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
612
613                         for(int x = 0; x < width; x++)
614                         {
615                                 dest[x] = (float)(source[x] & 0xFFFFFF00) / 0xFFFFFF00;
616                         }
617                 }
618
619                 unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, sw::PUBLIC));
620
621                 if(stencil)
622                 {
623                         for(int y = 0; y < height; y++)
624                         {
625                                 const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
626                                 unsigned char *dest = static_cast<unsigned char*>(stencil) + (y + yoffset) * getStencilPitchB() + xoffset;
627
628                                 for(int x = 0; x < width; x++)
629                                 {
630                                         dest[x] = static_cast<unsigned char>(source[x] & 0x000000FF);   // FIXME: Quad layout
631                                 }
632                         }
633
634                         unlockStencil();
635                 }
636         }
637
638         void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
639         {
640                 int inputPitch = ComputeCompressedPitch(width, format);
641                 int rows = imageSize / inputPitch;
642                 void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
643
644         if(buffer)
645         {
646                         for(int i = 0; i < rows; i++)
647                         {
648                                 memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
649                         }
650         }
651
652                 unlock();
653         }
654 }