• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
getParentResource(Texture * texture)29 	static sw::Resource *getParentResource(Texture *texture)
30 	{
31 		if(texture)
32 		{
33 			return texture->getResource();
34 		}
35 
36 		return nullptr;
37 	}
38 
Image(Texture * parentTexture,GLsizei width,GLsizei height,GLenum format,GLenum type)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 
Image(Texture * parentTexture,GLsizei width,GLsizei height,sw::Format internalFormat,int multiSampleDepth,bool lockable,bool renderTarget)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 
~Image()54 	Image::~Image()
55 	{
56 		ASSERT(referenceCount == 0);
57 	}
58 
lock(unsigned int left,unsigned int top,sw::Lock lock)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 
getPitch() const64 	unsigned int Image::getPitch() const
65 	{
66 		return getExternalPitchB();
67 	}
68 
unlock()69 	void Image::unlock()
70 	{
71 		unlockExternal();
72 	}
73 
lockInternal(int x,int y,int z,sw::Lock lock,sw::Accessor client)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 
unlockInternal()79 	void Image::unlockInternal()
80 	{
81 		Surface::unlockInternal();
82 	}
83 
getWidth()84 	int Image::getWidth()
85 	{
86 		return width;
87 	}
88 
getHeight()89 	int Image::getHeight()
90 	{
91 		return height;
92 	}
93 
getFormat()94 	GLenum Image::getFormat()
95 	{
96 		return format;
97 	}
98 
getType()99 	GLenum Image::getType()
100 	{
101 		return type;
102 	}
103 
getInternalFormat()104 	sw::Format Image::getInternalFormat()
105 	{
106 		return internalFormat;
107 	}
108 
getMultiSampleDepth()109 	int Image::getMultiSampleDepth()
110 	{
111 		return multiSampleDepth;
112 	}
113 
addRef()114 	void Image::addRef()
115 	{
116 		if(parentTexture)
117 		{
118 			return parentTexture->addRef();
119 		}
120 
121 		sw::atomicIncrement(&referenceCount);
122 	}
123 
release()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 
unbind()142 	void Image::unbind()
143 	{
144 		parentTexture = nullptr;
145 
146 		release();
147 	}
148 
selectInternalFormat(GLenum format,GLenum type)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 
loadImageData(GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLint unpackAlignment,const void * input)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 
loadAlphaImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const359 	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 
loadAlphaFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const370 	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 
loadAlphaHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const387 	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 
loadLuminanceImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const404 	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 
loadLuminanceFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const415 	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 
loadLuminanceHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const432 	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 
loadLuminanceAlphaImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const449 	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 
loadLuminanceAlphaFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const460 	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 
loadLuminanceAlphaHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const477 	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 
loadRGBUByteImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const494 	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 
loadRGB565ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const511 	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 
loadRGBFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const522 	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 
loadRGBHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const539 	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 
loadRGBAUByteImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const556 	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 
loadRGBA4444ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const571 	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 
loadRGBA5551ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const589 	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 
loadRGBAFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const607 	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 
loadRGBAHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const618 	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 
loadBGRAImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const629 	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 
loadD16ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const640 	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 
loadD32ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const654 	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 
loadD24S8ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer)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 
loadCompressedData(GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLsizei imageSize,const void * pixels)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 }