Home | History | Annotate | Download | only in libGL
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "Image.hpp"
     16 
     17 #include "Texture.h"
     18 #include "utilities.h"
     19 #include "../common/debug.h"
     20 #include "Common/Thread.hpp"
     21 
     22 #define _GDI32_
     23 #include <windows.h>
     24 #include <GL/GL.h>
     25 #include <GL/glext.h>
     26 
     27 namespace gl
     28 {
     29 	static sw::Resource *getParentResource(Texture *texture)
     30 	{
     31 		if(texture)
     32 		{
     33 			return texture->getResource();
     34 		}
     35 
     36 		return nullptr;
     37 	}
     38 
     39 	Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
     40 		: sw::Surface(getParentResource(parentTexture), width, height, 1, 0, 1, selectInternalFormat(format, type), true, true)
     41 		, parentTexture(parentTexture), width(width), height(height), format(format), type(type)
     42 		, internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1)
     43 	{
     44 		referenceCount = 1;
     45 	}
     46 
     47 	Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget)
     48 		: sw::Surface(getParentResource(parentTexture), width, height, 1, 0, multiSampleDepth, internalFormat, lockable, renderTarget)
     49 		, parentTexture(parentTexture), width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), multiSampleDepth(multiSampleDepth)
     50 	{
     51 		referenceCount = 1;
     52 	}
     53 
     54 	Image::~Image()
     55 	{
     56 		ASSERT(referenceCount == 0);
     57 	}
     58 
     59 	void *Image::lock(unsigned int left, unsigned int top, sw::Lock lock)
     60 	{
     61 		return lockExternal(left, top, 0, lock, sw::PUBLIC);
     62 	}
     63 
     64 	unsigned int Image::getPitch() const
     65 	{
     66 		return getExternalPitchB();
     67 	}
     68 
     69 	void Image::unlock()
     70 	{
     71 		unlockExternal();
     72 	}
     73 
     74 	void *Image::lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
     75 	{
     76 		return Surface::lockInternal(x, y, z, lock, client);
     77 	}
     78 
     79 	void Image::unlockInternal()
     80 	{
     81 		Surface::unlockInternal();
     82 	}
     83 
     84 	int Image::getWidth()
     85 	{
     86 		return width;
     87 	}
     88 
     89 	int Image::getHeight()
     90 	{
     91 		return height;
     92 	}
     93 
     94 	GLenum Image::getFormat()
     95 	{
     96 		return format;
     97 	}
     98 
     99 	GLenum Image::getType()
    100 	{
    101 		return type;
    102 	}
    103 
    104 	sw::Format Image::getInternalFormat()
    105 	{
    106 		return internalFormat;
    107 	}
    108 
    109 	int Image::getMultiSampleDepth()
    110 	{
    111 		return multiSampleDepth;
    112 	}
    113 
    114 	void Image::addRef()
    115 	{
    116 		if(parentTexture)
    117 		{
    118 			return parentTexture->addRef();
    119 		}
    120 
    121 		sw::atomicIncrement(&referenceCount);
    122 	}
    123 
    124 	void Image::release()
    125 	{
    126 		if(parentTexture)
    127 		{
    128 			return parentTexture->release();
    129 		}
    130 
    131 		if(referenceCount > 0)
    132 		{
    133 			sw::atomicDecrement(&referenceCount);
    134 		}
    135 
    136 		if(referenceCount == 0)
    137 		{
    138 			delete this;
    139 		}
    140 	}
    141 
    142 	void Image::unbind()
    143 	{
    144 		parentTexture = nullptr;
    145 
    146 		release();
    147 	}
    148 
    149 	sw::Format Image::selectInternalFormat(GLenum format, GLenum type)
    150 	{
    151 		if(type == GL_NONE && format == GL_NONE)
    152 		{
    153 			return sw::FORMAT_NULL;
    154 		}
    155 		else if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
    156 		        format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
    157 		{
    158 			return sw::FORMAT_DXT1;
    159 		}
    160 		else if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
    161 		{
    162 			return sw::FORMAT_DXT3;
    163 		}
    164 		else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
    165 		{
    166 			return sw::FORMAT_DXT5;
    167 		}
    168 		else if(type == GL_FLOAT)
    169 		{
    170 			return sw::FORMAT_A32B32G32R32F;
    171 		}
    172 		else if(type == GL_HALF_FLOAT)
    173 		{
    174 			return sw::FORMAT_A16B16G16R16F;
    175 		}
    176 		else if(type == GL_UNSIGNED_BYTE)
    177 		{
    178 			if(format == GL_LUMINANCE)
    179 			{
    180 				return sw::FORMAT_L8;
    181 			}
    182 			else if(format == GL_LUMINANCE_ALPHA)
    183 			{
    184 				return sw::FORMAT_A8L8;
    185 			}
    186 			else if(format == GL_RGBA || format == GL_BGRA_EXT)
    187 			{
    188 				return sw::FORMAT_A8R8G8B8;
    189 			}
    190 			else if(format == GL_RGB)
    191 			{
    192 				return sw::FORMAT_X8R8G8B8;
    193 			}
    194 			else if(format == GL_ALPHA)
    195 			{
    196 				return sw::FORMAT_A8;
    197 			}
    198 			else UNREACHABLE(format);
    199 		}
    200 		else if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT)
    201 		{
    202 			if(format == GL_DEPTH_COMPONENT)
    203 			{
    204 				return sw::FORMAT_D32FS8_TEXTURE;
    205 			}
    206 			else UNREACHABLE(format);
    207 		}
    208 		else if(type == GL_UNSIGNED_INT_24_8_EXT)
    209 		{
    210 			if(format == GL_DEPTH_STENCIL_EXT)
    211 			{
    212 				return sw::FORMAT_D32FS8_TEXTURE;
    213 			}
    214 			else UNREACHABLE(format);
    215 		}
    216 		else if(type == GL_UNSIGNED_SHORT_4_4_4_4)
    217 		{
    218 			return sw::FORMAT_A8R8G8B8;
    219 		}
    220 		else if(type == GL_UNSIGNED_SHORT_5_5_5_1)
    221 		{
    222 			return sw::FORMAT_A8R8G8B8;
    223 		}
    224 		else if(type == GL_UNSIGNED_SHORT_5_6_5)
    225 		{
    226 			return sw::FORMAT_R5G6B5;
    227 		}
    228 		else if(type == GL_UNSIGNED_INT_8_8_8_8_REV)
    229 		{
    230 			return sw::FORMAT_A8R8G8B8;
    231 		}
    232 
    233 		else UNREACHABLE(type);
    234 
    235 		return sw::FORMAT_A8R8G8B8;
    236 	}
    237 
    238 	void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
    239 	{
    240 		GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
    241 		void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
    242 
    243 		if(buffer)
    244 		{
    245 			switch(type)
    246 			{
    247 			case GL_UNSIGNED_BYTE:
    248 			case GL_UNSIGNED_INT_8_8_8_8_REV:
    249 				switch(format)
    250 				{
    251 				case GL_ALPHA:
    252 					loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    253 					break;
    254 				case GL_LUMINANCE:
    255 					loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    256 					break;
    257 				case GL_LUMINANCE_ALPHA:
    258 					loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    259 					break;
    260 				case GL_RGB:
    261 					loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    262 					break;
    263 				case GL_RGBA:
    264 					loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    265 					break;
    266 				case GL_BGRA_EXT:
    267 					loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    268 					break;
    269 				default: UNREACHABLE(format);
    270 				}
    271 				break;
    272 			case GL_UNSIGNED_SHORT_5_6_5:
    273 				switch(format)
    274 				{
    275 				case GL_RGB:
    276 					loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    277 					break;
    278 				default: UNREACHABLE(format);
    279 				}
    280 				break;
    281 			case GL_UNSIGNED_SHORT_4_4_4_4:
    282 				switch(format)
    283 				{
    284 				case GL_RGBA:
    285 					loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    286 					break;
    287 				default: UNREACHABLE(format);
    288 				}
    289 				break;
    290 			case GL_UNSIGNED_SHORT_5_5_5_1:
    291 				switch(format)
    292 				{
    293 				case GL_RGBA:
    294 					loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    295 					break;
    296 				default: UNREACHABLE(format);
    297 				}
    298 				break;
    299 			case GL_FLOAT:
    300 				switch(format)
    301 				{
    302 				// float textures are converted to RGBA, not BGRA
    303 				case GL_ALPHA:
    304 					loadAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    305 					break;
    306 				case GL_LUMINANCE:
    307 					loadLuminanceFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    308 					break;
    309 				case GL_LUMINANCE_ALPHA:
    310 					loadLuminanceAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    311 					break;
    312 				case GL_RGB:
    313 					loadRGBFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    314 					break;
    315 				case GL_RGBA:
    316 					loadRGBAFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    317 					break;
    318 				default: UNREACHABLE(format);
    319 				}
    320 				break;
    321 			case GL_HALF_FLOAT:
    322 				switch(format)
    323 				{
    324 				// float textures are converted to RGBA, not BGRA
    325 				case GL_ALPHA:
    326 					loadAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    327 					break;
    328 				case GL_LUMINANCE:
    329 					loadLuminanceHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    330 					break;
    331 				case GL_LUMINANCE_ALPHA:
    332 					loadLuminanceAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    333 					break;
    334 				case GL_RGB:
    335 					loadRGBHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    336 					break;
    337 				case GL_RGBA:
    338 					loadRGBAHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    339 					break;
    340 				default: UNREACHABLE(format);
    341 				}
    342 				break;
    343 			case GL_UNSIGNED_SHORT:
    344 				loadD16ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    345 				break;
    346 			case GL_UNSIGNED_INT:
    347 				loadD32ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    348 				break;
    349 			case GL_UNSIGNED_INT_24_8_EXT:
    350 				loadD24S8ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
    351 				break;
    352 			default: UNREACHABLE(type);
    353 			}
    354 		}
    355 
    356 		unlock();
    357 	}
    358 
    359 	void Image::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    360 	{
    361 		for(int y = 0; y < height; y++)
    362 		{
    363 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
    364 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset;
    365 
    366 			memcpy(dest, source, width);
    367 		}
    368 	}
    369 
    370 	void Image::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    371 	{
    372 		for(int y = 0; y < height; y++)
    373 		{
    374 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    375 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
    376 
    377 			for(int x = 0; x < width; x++)
    378 			{
    379 				dest[4 * x + 0] = 0;
    380 				dest[4 * x + 1] = 0;
    381 				dest[4 * x + 2] = 0;
    382 				dest[4 * x + 3] = source[x];
    383 			}
    384 		}
    385 	}
    386 
    387 	void Image::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    388 	{
    389 		for(int y = 0; y < height; y++)
    390 		{
    391 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    392 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
    393 
    394 			for(int x = 0; x < width; x++)
    395 			{
    396 				dest[4 * x + 0] = 0;
    397 				dest[4 * x + 1] = 0;
    398 				dest[4 * x + 2] = 0;
    399 				dest[4 * x + 3] = source[x];
    400 			}
    401 		}
    402 	}
    403 
    404 	void Image::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    405 	{
    406 		for(int y = 0; y < height; y++)
    407 		{
    408 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
    409 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset;
    410 
    411 			memcpy(dest, source, width);
    412 		}
    413 	}
    414 
    415 	void Image::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    416 	{
    417 		for(int y = 0; y < height; y++)
    418 		{
    419 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    420 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
    421 
    422 			for(int x = 0; x < width; x++)
    423 			{
    424 				dest[4 * x + 0] = source[x];
    425 				dest[4 * x + 1] = source[x];
    426 				dest[4 * x + 2] = source[x];
    427 				dest[4 * x + 3] = 1.0f;
    428 			}
    429 		}
    430 	}
    431 
    432 	void Image::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    433 	{
    434 		for(int y = 0; y < height; y++)
    435 		{
    436 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    437 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
    438 
    439 			for(int x = 0; x < width; x++)
    440 			{
    441 				dest[4 * x + 0] = source[x];
    442 				dest[4 * x + 1] = source[x];
    443 				dest[4 * x + 2] = source[x];
    444 				dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
    445 			}
    446 		}
    447 	}
    448 
    449 	void Image::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    450 	{
    451 		for(int y = 0; y < height; y++)
    452 		{
    453 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
    454 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
    455 
    456 			memcpy(dest, source, width * 2);
    457 		}
    458 	}
    459 
    460 	void Image::loadLuminanceAlphaFloatImageData(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[2*x+0];
    470 				dest[4 * x + 1] = source[2*x+0];
    471 				dest[4 * x + 2] = source[2*x+0];
    472 				dest[4 * x + 3] = source[2*x+1];
    473 			}
    474 		}
    475 	}
    476 
    477 	void Image::loadLuminanceAlphaHalfFloatImageData(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[2*x+0];
    487 				dest[4 * x + 1] = source[2*x+0];
    488 				dest[4 * x + 2] = source[2*x+0];
    489 				dest[4 * x + 3] = source[2*x+1];
    490 			}
    491 		}
    492 	}
    493 
    494 	void Image::loadRGBUByteImageData(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 char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
    499 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
    500 
    501 			for(int x = 0; x < width; x++)
    502 			{
    503 				dest[4 * x + 0] = source[x * 3 + 2];
    504 				dest[4 * x + 1] = source[x * 3 + 1];
    505 				dest[4 * x + 2] = source[x * 3 + 0];
    506 				dest[4 * x + 3] = 0xFF;
    507 			}
    508 		}
    509 	}
    510 
    511 	void Image::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    512 	{
    513 		for(int y = 0; y < height; y++)
    514 		{
    515 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    516 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
    517 
    518 			memcpy(dest, source, width * 2);
    519 		}
    520 	}
    521 
    522 	void Image::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    523 	{
    524 		for(int y = 0; y < height; y++)
    525 		{
    526 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    527 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
    528 
    529 			for(int x = 0; x < width; x++)
    530 			{
    531 				dest[4 * x + 0] = source[x * 3 + 0];
    532 				dest[4 * x + 1] = source[x * 3 + 1];
    533 				dest[4 * x + 2] = source[x * 3 + 2];
    534 				dest[4 * x + 3] = 1.0f;
    535 			}
    536 		}
    537 	}
    538 
    539 	void Image::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    540 	{
    541 		for(int y = 0; y < height; y++)
    542 		{
    543 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    544 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
    545 
    546 			for(int x = 0; x < width; x++)
    547 			{
    548 				dest[4 * x + 0] = source[x * 3 + 0];
    549 				dest[4 * x + 1] = source[x * 3 + 1];
    550 				dest[4 * x + 2] = source[x * 3 + 2];
    551 				dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
    552 			}
    553 		}
    554 	}
    555 
    556 	void Image::loadRGBAUByteImageData(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 int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    561 			unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
    562 
    563 			for(int x = 0; x < width; x++)
    564 			{
    565 				unsigned int rgba = source[x];
    566 				dest[x] = (rgba & 0xFF00FF00) | ((rgba << 16) & 0x00FF0000) | ((rgba >> 16) & 0x000000FF);
    567 			}
    568 		}
    569 	}
    570 
    571 	void Image::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    572 	{
    573 		for(int y = 0; y < height; y++)
    574 		{
    575 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    576 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
    577 
    578 			for(int x = 0; x < width; x++)
    579 			{
    580 				unsigned short rgba = source[x];
    581 				dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
    582 				dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
    583 				dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
    584 				dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
    585 			}
    586 		}
    587 	}
    588 
    589 	void Image::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    590 	{
    591 		for(int y = 0; y < height; y++)
    592 		{
    593 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    594 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
    595 
    596 			for(int x = 0; x < width; x++)
    597 			{
    598 				unsigned short rgba = source[x];
    599 				dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
    600 				dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
    601 				dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
    602 				dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
    603 			}
    604 		}
    605 	}
    606 
    607 	void Image::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    608 	{
    609 		for(int y = 0; y < height; y++)
    610 		{
    611 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    612 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
    613 
    614 			memcpy(dest, source, width * 16);
    615 		}
    616 	}
    617 
    618 	void Image::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    619 	{
    620 		for(int y = 0; y < height; y++)
    621 		{
    622 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
    623 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8;
    624 
    625 			memcpy(dest, source, width * 8);
    626 		}
    627 	}
    628 
    629 	void Image::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    630 	{
    631 		for(int y = 0; y < height; y++)
    632 		{
    633 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
    634 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
    635 
    636 			memcpy(dest, source, width*4);
    637 		}
    638 	}
    639 
    640 	void Image::loadD16ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    641 	{
    642 		for(int y = 0; y < height; y++)
    643 		{
    644 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    645 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
    646 
    647 			for(int x = 0; x < width; x++)
    648 			{
    649 				dest[x] = (float)source[x] / 0xFFFF;
    650 			}
    651 		}
    652 	}
    653 
    654 	void Image::loadD32ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
    655 	{
    656 		for(int y = 0; y < height; y++)
    657 		{
    658 			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    659 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
    660 
    661 			for(int x = 0; x < width; x++)
    662 			{
    663 				dest[x] = (float)source[x] / 0xFFFFFFFF;
    664 			}
    665 		}
    666 	}
    667 
    668 	void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer)
    669 	{
    670 		for(int y = 0; y < height; y++)
    671 		{
    672 			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    673 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
    674 
    675 			for(int x = 0; x < width; x++)
    676 			{
    677 				dest[x] = (float)(source[x] & 0xFFFFFF00) / 0xFFFFFF00;
    678 			}
    679 		}
    680 
    681 		unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, 0, 0, sw::PUBLIC));
    682 
    683 		if(stencil)
    684 		{
    685 			for(int y = 0; y < height; y++)
    686 			{
    687 				const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
    688 				unsigned char *dest = static_cast<unsigned char*>(stencil) + (y + yoffset) * getStencilPitchB() + xoffset;
    689 
    690 				for(int x = 0; x < width; x++)
    691 				{
    692 					dest[x] = static_cast<unsigned char>(source[x] & 0x000000FF);   // FIXME: Quad layout
    693 				}
    694 			}
    695 
    696 			unlockStencil();
    697 		}
    698 	}
    699 
    700 	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
    701 	{
    702 		int inputPitch = ComputeCompressedPitch(width, format);
    703 		int rows = imageSize / inputPitch;
    704 		void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
    705 
    706 		if(buffer)
    707 		{
    708 			for(int i = 0; i < rows; i++)
    709 			{
    710 				memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
    711 			}
    712 		}
    713 
    714 		unlock();
    715 	}
    716 }