• 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 0;
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 		: parentTexture(parentTexture), width(width), height(height), format(format), type(type)
41 		, internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1)
42 		, sw::Surface(getParentResource(parentTexture), width, height, 1, selectInternalFormat(format, type), true, true)
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 		: parentTexture(parentTexture), width(width), height(height), internalFormat(internalFormat), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), multiSampleDepth(multiSampleDepth)
49 		, sw::Surface(getParentResource(parentTexture), width, height, multiSampleDepth, internalFormat, lockable, renderTarget)
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 
getWidth()74 	int Image::getWidth()
75 	{
76 		return width;
77 	}
78 
getHeight()79 	int Image::getHeight()
80 	{
81 		return height;
82 	}
83 
getFormat()84 	GLenum Image::getFormat()
85 	{
86 		return format;
87 	}
88 
getType()89 	GLenum Image::getType()
90 	{
91 		return type;
92 	}
93 
getInternalFormat()94 	sw::Format Image::getInternalFormat()
95 	{
96 		return internalFormat;
97 	}
98 
getMultiSampleDepth()99 	int Image::getMultiSampleDepth()
100 	{
101 		return multiSampleDepth;
102 	}
103 
addRef()104 	void Image::addRef()
105 	{
106 		if(parentTexture)
107 		{
108 			return parentTexture->addRef();
109 		}
110 
111 		sw::atomicIncrement(&referenceCount);
112 	}
113 
release()114 	void Image::release()
115 	{
116 		if(parentTexture)
117 		{
118 			return parentTexture->release();
119 		}
120 
121 		if(referenceCount > 0)
122 		{
123 			sw::atomicDecrement(&referenceCount);
124 		}
125 
126 		if(referenceCount == 0)
127 		{
128 			delete this;
129 		}
130 	}
131 
unbind()132 	void Image::unbind()
133 	{
134 		parentTexture = 0;
135 
136 		release();
137 	}
138 
selectInternalFormat(GLenum format,GLenum type)139 	sw::Format Image::selectInternalFormat(GLenum format, GLenum type)
140 	{
141 		if(type == GL_NONE && format == GL_NONE)
142 		{
143 			return sw::FORMAT_NULL;
144 		}
145 		else
146 		#if S3TC_SUPPORT
147 		if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
148 		   format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
149 		{
150 			return sw::FORMAT_DXT1;
151 		}
152 		else if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
153 		{
154 			return sw::FORMAT_DXT3;
155 		}
156 		else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
157 		{
158 			return sw::FORMAT_DXT5;
159 		}
160 		else
161 		#endif
162 		if(type == GL_FLOAT)
163 		{
164 			return sw::FORMAT_A32B32G32R32F;
165 		}
166 		else if(type == GL_HALF_FLOAT)
167 		{
168 			return sw::FORMAT_A16B16G16R16F;
169 		}
170 		else if(type == GL_UNSIGNED_BYTE)
171 		{
172 			if(format == GL_LUMINANCE)
173 			{
174 				return sw::FORMAT_L8;
175 			}
176 			else if(format == GL_LUMINANCE_ALPHA)
177 			{
178 				return sw::FORMAT_A8L8;
179 			}
180 			else if(format == GL_RGBA || format == GL_BGRA_EXT)
181 			{
182 				return sw::FORMAT_A8R8G8B8;
183 			}
184 			else if(format == GL_RGB)
185 			{
186 				return sw::FORMAT_X8R8G8B8;
187 			}
188 			else if(format == GL_ALPHA)
189 			{
190 				return sw::FORMAT_A8;
191 			}
192 			else UNREACHABLE(format);
193 		}
194 		else if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT)
195 		{
196 			if(format == GL_DEPTH_COMPONENT)
197 			{
198 				return sw::FORMAT_D32FS8_TEXTURE;
199 			}
200 			else UNREACHABLE(format);
201 		}
202 		else if(type == GL_UNSIGNED_INT_24_8_EXT)
203 		{
204 			if(format == GL_DEPTH_STENCIL_EXT)
205 			{
206 				return sw::FORMAT_D32FS8_TEXTURE;
207 			}
208 			else UNREACHABLE(format);
209 		}
210 		else if(type == GL_UNSIGNED_SHORT_4_4_4_4)
211 		{
212 			return sw::FORMAT_A8R8G8B8;
213 		}
214 		else if(type == GL_UNSIGNED_SHORT_5_5_5_1)
215 		{
216 			return sw::FORMAT_A8R8G8B8;
217 		}
218 		else if(type == GL_UNSIGNED_SHORT_5_6_5)
219 		{
220 			return sw::FORMAT_R5G6B5;
221 		}
222 		else if(type == GL_UNSIGNED_INT_8_8_8_8_REV)
223 		{
224 			return sw::FORMAT_A8R8G8B8;
225 		}
226 
227 		else UNREACHABLE(type);
228 
229 		return sw::FORMAT_A8R8G8B8;
230 	}
231 
loadImageData(GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLint unpackAlignment,const void * input)232 	void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
233 	{
234 		GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
235 		void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
236 
237 		if(buffer)
238 		{
239 			switch(type)
240 			{
241 			case GL_UNSIGNED_BYTE:
242 			case GL_UNSIGNED_INT_8_8_8_8_REV:
243 				switch(format)
244 				{
245 				case GL_ALPHA:
246 					loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
247 					break;
248 				case GL_LUMINANCE:
249 					loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
250 					break;
251 				case GL_LUMINANCE_ALPHA:
252 					loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
253 					break;
254 				case GL_RGB:
255 					loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
256 					break;
257 				case GL_RGBA:
258 					loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
259 					break;
260 				case GL_BGRA_EXT:
261 					loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
262 					break;
263 				default: UNREACHABLE(format);
264 				}
265 				break;
266 			case GL_UNSIGNED_SHORT_5_6_5:
267 				switch(format)
268 				{
269 				case GL_RGB:
270 					loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
271 					break;
272 				default: UNREACHABLE(format);
273 				}
274 				break;
275 			case GL_UNSIGNED_SHORT_4_4_4_4:
276 				switch(format)
277 				{
278 				case GL_RGBA:
279 					loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
280 					break;
281 				default: UNREACHABLE(format);
282 				}
283 				break;
284 			case GL_UNSIGNED_SHORT_5_5_5_1:
285 				switch(format)
286 				{
287 				case GL_RGBA:
288 					loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
289 					break;
290 				default: UNREACHABLE(format);
291 				}
292 				break;
293 			case GL_FLOAT:
294 				switch(format)
295 				{
296 				// float textures are converted to RGBA, not BGRA
297 				case GL_ALPHA:
298 					loadAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
299 					break;
300 				case GL_LUMINANCE:
301 					loadLuminanceFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
302 					break;
303 				case GL_LUMINANCE_ALPHA:
304 					loadLuminanceAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
305 					break;
306 				case GL_RGB:
307 					loadRGBFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
308 					break;
309 				case GL_RGBA:
310 					loadRGBAFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
311 					break;
312 				default: UNREACHABLE(format);
313 				}
314 				break;
315 			case GL_HALF_FLOAT:
316 				switch(format)
317 				{
318 				// float textures are converted to RGBA, not BGRA
319 				case GL_ALPHA:
320 					loadAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
321 					break;
322 				case GL_LUMINANCE:
323 					loadLuminanceHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
324 					break;
325 				case GL_LUMINANCE_ALPHA:
326 					loadLuminanceAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
327 					break;
328 				case GL_RGB:
329 					loadRGBHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
330 					break;
331 				case GL_RGBA:
332 					loadRGBAHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
333 					break;
334 				default: UNREACHABLE(format);
335 				}
336 				break;
337 			case GL_UNSIGNED_SHORT:
338 				loadD16ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
339 				break;
340 			case GL_UNSIGNED_INT:
341 				loadD32ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
342 				break;
343 			case GL_UNSIGNED_INT_24_8_EXT:
344 				loadD24S8ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
345 				break;
346 			default: UNREACHABLE(type);
347 			}
348 		}
349 
350 		unlock();
351 	}
352 
loadAlphaImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const353 	void Image::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
354 	{
355 		for(int y = 0; y < height; y++)
356 		{
357 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
358 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset;
359 
360 			memcpy(dest, source, width);
361 		}
362 	}
363 
loadAlphaFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const364 	void Image::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
365 	{
366 		for(int y = 0; y < height; y++)
367 		{
368 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
369 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
370 
371 			for(int x = 0; x < width; x++)
372 			{
373 				dest[4 * x + 0] = 0;
374 				dest[4 * x + 1] = 0;
375 				dest[4 * x + 2] = 0;
376 				dest[4 * x + 3] = source[x];
377 			}
378 		}
379 	}
380 
loadAlphaHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const381 	void Image::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
382 	{
383 		for(int y = 0; y < height; y++)
384 		{
385 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
386 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
387 
388 			for(int x = 0; x < width; x++)
389 			{
390 				dest[4 * x + 0] = 0;
391 				dest[4 * x + 1] = 0;
392 				dest[4 * x + 2] = 0;
393 				dest[4 * x + 3] = source[x];
394 			}
395 		}
396 	}
397 
loadLuminanceImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const398 	void Image::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
399 	{
400 		for(int y = 0; y < height; y++)
401 		{
402 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
403 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset;
404 
405 			memcpy(dest, source, width);
406 		}
407 	}
408 
loadLuminanceFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const409 	void Image::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
410 	{
411 		for(int y = 0; y < height; y++)
412 		{
413 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
414 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
415 
416 			for(int x = 0; x < width; x++)
417 			{
418 				dest[4 * x + 0] = source[x];
419 				dest[4 * x + 1] = source[x];
420 				dest[4 * x + 2] = source[x];
421 				dest[4 * x + 3] = 1.0f;
422 			}
423 		}
424 	}
425 
loadLuminanceHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const426 	void Image::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
427 	{
428 		for(int y = 0; y < height; y++)
429 		{
430 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
431 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
432 
433 			for(int x = 0; x < width; x++)
434 			{
435 				dest[4 * x + 0] = source[x];
436 				dest[4 * x + 1] = source[x];
437 				dest[4 * x + 2] = source[x];
438 				dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
439 			}
440 		}
441 	}
442 
loadLuminanceAlphaImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const443 	void Image::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
444 	{
445 		for(int y = 0; y < height; y++)
446 		{
447 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
448 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
449 
450 			memcpy(dest, source, width * 2);
451 		}
452 	}
453 
loadLuminanceAlphaFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const454 	void Image::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
455 	{
456 		for(int y = 0; y < height; y++)
457 		{
458 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
459 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
460 
461 			for(int x = 0; x < width; x++)
462 			{
463 				dest[4 * x + 0] = source[2*x+0];
464 				dest[4 * x + 1] = source[2*x+0];
465 				dest[4 * x + 2] = source[2*x+0];
466 				dest[4 * x + 3] = source[2*x+1];
467 			}
468 		}
469 	}
470 
loadLuminanceAlphaHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const471 	void Image::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
472 	{
473 		for(int y = 0; y < height; y++)
474 		{
475 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
476 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
477 
478 			for(int x = 0; x < width; x++)
479 			{
480 				dest[4 * x + 0] = source[2*x+0];
481 				dest[4 * x + 1] = source[2*x+0];
482 				dest[4 * x + 2] = source[2*x+0];
483 				dest[4 * x + 3] = source[2*x+1];
484 			}
485 		}
486 	}
487 
loadRGBUByteImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const488 	void Image::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
489 	{
490 		for(int y = 0; y < height; y++)
491 		{
492 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
493 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
494 
495 			for(int x = 0; x < width; x++)
496 			{
497 				dest[4 * x + 0] = source[x * 3 + 2];
498 				dest[4 * x + 1] = source[x * 3 + 1];
499 				dest[4 * x + 2] = source[x * 3 + 0];
500 				dest[4 * x + 3] = 0xFF;
501 			}
502 		}
503 	}
504 
loadRGB565ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const505 	void Image::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
506 	{
507 		for(int y = 0; y < height; y++)
508 		{
509 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
510 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
511 
512 			memcpy(dest, source, width * 2);
513 		}
514 	}
515 
loadRGBFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const516 	void Image::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
517 	{
518 		for(int y = 0; y < height; y++)
519 		{
520 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
521 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
522 
523 			for(int x = 0; x < width; x++)
524 			{
525 				dest[4 * x + 0] = source[x * 3 + 0];
526 				dest[4 * x + 1] = source[x * 3 + 1];
527 				dest[4 * x + 2] = source[x * 3 + 2];
528 				dest[4 * x + 3] = 1.0f;
529 			}
530 		}
531 	}
532 
loadRGBHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const533 	void Image::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
534 	{
535 		for(int y = 0; y < height; y++)
536 		{
537 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
538 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
539 
540 			for(int x = 0; x < width; x++)
541 			{
542 				dest[4 * x + 0] = source[x * 3 + 0];
543 				dest[4 * x + 1] = source[x * 3 + 1];
544 				dest[4 * x + 2] = source[x * 3 + 2];
545 				dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
546 			}
547 		}
548 	}
549 
loadRGBAUByteImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const550 	void Image::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
551 	{
552 		for(int y = 0; y < height; y++)
553 		{
554 			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
555 			unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
556 
557 			for(int x = 0; x < width; x++)
558 			{
559 				unsigned int rgba = source[x];
560 				dest[x] = (rgba & 0xFF00FF00) | ((rgba << 16) & 0x00FF0000) | ((rgba >> 16) & 0x000000FF);
561 			}
562 		}
563 	}
564 
loadRGBA4444ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const565 	void Image::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
566 	{
567 		for(int y = 0; y < height; y++)
568 		{
569 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
570 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
571 
572 			for(int x = 0; x < width; x++)
573 			{
574 				unsigned short rgba = source[x];
575 				dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
576 				dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
577 				dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
578 				dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
579 			}
580 		}
581 	}
582 
loadRGBA5551ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const583 	void Image::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
584 	{
585 		for(int y = 0; y < height; y++)
586 		{
587 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
588 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
589 
590 			for(int x = 0; x < width; x++)
591 			{
592 				unsigned short rgba = source[x];
593 				dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
594 				dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
595 				dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
596 				dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
597 			}
598 		}
599 	}
600 
loadRGBAFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const601 	void Image::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
602 	{
603 		for(int y = 0; y < height; y++)
604 		{
605 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
606 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
607 
608 			memcpy(dest, source, width * 16);
609 		}
610 	}
611 
loadRGBAHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const612 	void Image::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
613 	{
614 		for(int y = 0; y < height; y++)
615 		{
616 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
617 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8;
618 
619 			memcpy(dest, source, width * 8);
620 		}
621 	}
622 
loadBGRAImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const623 	void Image::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
624 	{
625 		for(int y = 0; y < height; y++)
626 		{
627 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
628 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
629 
630 			memcpy(dest, source, width*4);
631 		}
632 	}
633 
loadD16ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const634 	void Image::loadD16ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
635 	{
636 		for(int y = 0; y < height; y++)
637 		{
638 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
639 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
640 
641 			for(int x = 0; x < width; x++)
642 			{
643 				dest[x] = (float)source[x] / 0xFFFF;
644 			}
645 		}
646 	}
647 
loadD32ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const648 	void Image::loadD32ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
649 	{
650 		for(int y = 0; y < height; y++)
651 		{
652 			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
653 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
654 
655 			for(int x = 0; x < width; x++)
656 			{
657 				dest[x] = (float)source[x] / 0xFFFFFFFF;
658 			}
659 		}
660 	}
661 
loadD24S8ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer)662 	void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer)
663 	{
664 		for(int y = 0; y < height; y++)
665 		{
666 			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
667 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
668 
669 			for(int x = 0; x < width; x++)
670 			{
671 				dest[x] = (float)(source[x] & 0xFFFFFF00) / 0xFFFFFF00;
672 			}
673 		}
674 
675 		unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, sw::PUBLIC));
676 
677 		if(stencil)
678 		{
679 			for(int y = 0; y < height; y++)
680 			{
681 				const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
682 				unsigned char *dest = static_cast<unsigned char*>(stencil) + (y + yoffset) * getStencilPitchB() + xoffset;
683 
684 				for(int x = 0; x < width; x++)
685 				{
686 					dest[x] = static_cast<unsigned char>(source[x] & 0x000000FF);   // FIXME: Quad layout
687 				}
688 			}
689 
690 			unlockStencil();
691 		}
692 	}
693 
loadCompressedData(GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLsizei imageSize,const void * pixels)694 	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
695 	{
696 		int inputPitch = ComputeCompressedPitch(width, format);
697 		int rows = imageSize / inputPitch;
698 		void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
699 
700 		if(buffer)
701 		{
702 			for(int i = 0; i < rows; i++)
703 			{
704 				memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
705 			}
706 		}
707 
708 		unlock();
709 	}
710 }