• 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 
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 = 0;
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
156 		#if S3TC_SUPPORT
157 		if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
158 		   format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
159 		{
160 			return sw::FORMAT_DXT1;
161 		}
162 		else if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
163 		{
164 			return sw::FORMAT_DXT3;
165 		}
166 		else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
167 		{
168 			return sw::FORMAT_DXT5;
169 		}
170 		else
171 		#endif
172 		if(type == GL_FLOAT)
173 		{
174 			return sw::FORMAT_A32B32G32R32F;
175 		}
176 		else if(type == GL_HALF_FLOAT)
177 		{
178 			return sw::FORMAT_A16B16G16R16F;
179 		}
180 		else if(type == GL_UNSIGNED_BYTE)
181 		{
182 			if(format == GL_LUMINANCE)
183 			{
184 				return sw::FORMAT_L8;
185 			}
186 			else if(format == GL_LUMINANCE_ALPHA)
187 			{
188 				return sw::FORMAT_A8L8;
189 			}
190 			else if(format == GL_RGBA || format == GL_BGRA_EXT)
191 			{
192 				return sw::FORMAT_A8R8G8B8;
193 			}
194 			else if(format == GL_RGB)
195 			{
196 				return sw::FORMAT_X8R8G8B8;
197 			}
198 			else if(format == GL_ALPHA)
199 			{
200 				return sw::FORMAT_A8;
201 			}
202 			else UNREACHABLE(format);
203 		}
204 		else if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT)
205 		{
206 			if(format == GL_DEPTH_COMPONENT)
207 			{
208 				return sw::FORMAT_D32FS8_TEXTURE;
209 			}
210 			else UNREACHABLE(format);
211 		}
212 		else if(type == GL_UNSIGNED_INT_24_8_EXT)
213 		{
214 			if(format == GL_DEPTH_STENCIL_EXT)
215 			{
216 				return sw::FORMAT_D32FS8_TEXTURE;
217 			}
218 			else UNREACHABLE(format);
219 		}
220 		else if(type == GL_UNSIGNED_SHORT_4_4_4_4)
221 		{
222 			return sw::FORMAT_A8R8G8B8;
223 		}
224 		else if(type == GL_UNSIGNED_SHORT_5_5_5_1)
225 		{
226 			return sw::FORMAT_A8R8G8B8;
227 		}
228 		else if(type == GL_UNSIGNED_SHORT_5_6_5)
229 		{
230 			return sw::FORMAT_R5G6B5;
231 		}
232 		else if(type == GL_UNSIGNED_INT_8_8_8_8_REV)
233 		{
234 			return sw::FORMAT_A8R8G8B8;
235 		}
236 
237 		else UNREACHABLE(type);
238 
239 		return sw::FORMAT_A8R8G8B8;
240 	}
241 
loadImageData(GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLint unpackAlignment,const void * input)242 	void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
243 	{
244 		GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
245 		void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
246 
247 		if(buffer)
248 		{
249 			switch(type)
250 			{
251 			case GL_UNSIGNED_BYTE:
252 			case GL_UNSIGNED_INT_8_8_8_8_REV:
253 				switch(format)
254 				{
255 				case GL_ALPHA:
256 					loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
257 					break;
258 				case GL_LUMINANCE:
259 					loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
260 					break;
261 				case GL_LUMINANCE_ALPHA:
262 					loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
263 					break;
264 				case GL_RGB:
265 					loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
266 					break;
267 				case GL_RGBA:
268 					loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
269 					break;
270 				case GL_BGRA_EXT:
271 					loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
272 					break;
273 				default: UNREACHABLE(format);
274 				}
275 				break;
276 			case GL_UNSIGNED_SHORT_5_6_5:
277 				switch(format)
278 				{
279 				case GL_RGB:
280 					loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
281 					break;
282 				default: UNREACHABLE(format);
283 				}
284 				break;
285 			case GL_UNSIGNED_SHORT_4_4_4_4:
286 				switch(format)
287 				{
288 				case GL_RGBA:
289 					loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
290 					break;
291 				default: UNREACHABLE(format);
292 				}
293 				break;
294 			case GL_UNSIGNED_SHORT_5_5_5_1:
295 				switch(format)
296 				{
297 				case GL_RGBA:
298 					loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
299 					break;
300 				default: UNREACHABLE(format);
301 				}
302 				break;
303 			case GL_FLOAT:
304 				switch(format)
305 				{
306 				// float textures are converted to RGBA, not BGRA
307 				case GL_ALPHA:
308 					loadAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
309 					break;
310 				case GL_LUMINANCE:
311 					loadLuminanceFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
312 					break;
313 				case GL_LUMINANCE_ALPHA:
314 					loadLuminanceAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
315 					break;
316 				case GL_RGB:
317 					loadRGBFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
318 					break;
319 				case GL_RGBA:
320 					loadRGBAFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
321 					break;
322 				default: UNREACHABLE(format);
323 				}
324 				break;
325 			case GL_HALF_FLOAT:
326 				switch(format)
327 				{
328 				// float textures are converted to RGBA, not BGRA
329 				case GL_ALPHA:
330 					loadAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
331 					break;
332 				case GL_LUMINANCE:
333 					loadLuminanceHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
334 					break;
335 				case GL_LUMINANCE_ALPHA:
336 					loadLuminanceAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
337 					break;
338 				case GL_RGB:
339 					loadRGBHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
340 					break;
341 				case GL_RGBA:
342 					loadRGBAHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
343 					break;
344 				default: UNREACHABLE(format);
345 				}
346 				break;
347 			case GL_UNSIGNED_SHORT:
348 				loadD16ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
349 				break;
350 			case GL_UNSIGNED_INT:
351 				loadD32ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
352 				break;
353 			case GL_UNSIGNED_INT_24_8_EXT:
354 				loadD24S8ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
355 				break;
356 			default: UNREACHABLE(type);
357 			}
358 		}
359 
360 		unlock();
361 	}
362 
loadAlphaImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const363 	void Image::loadAlphaImageData(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 char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
368 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset;
369 
370 			memcpy(dest, source, width);
371 		}
372 	}
373 
loadAlphaFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const374 	void Image::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
375 	{
376 		for(int y = 0; y < height; y++)
377 		{
378 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
379 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
380 
381 			for(int x = 0; x < width; x++)
382 			{
383 				dest[4 * x + 0] = 0;
384 				dest[4 * x + 1] = 0;
385 				dest[4 * x + 2] = 0;
386 				dest[4 * x + 3] = source[x];
387 			}
388 		}
389 	}
390 
loadAlphaHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const391 	void Image::loadAlphaHalfFloatImageData(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 unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
396 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
397 
398 			for(int x = 0; x < width; x++)
399 			{
400 				dest[4 * x + 0] = 0;
401 				dest[4 * x + 1] = 0;
402 				dest[4 * x + 2] = 0;
403 				dest[4 * x + 3] = source[x];
404 			}
405 		}
406 	}
407 
loadLuminanceImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const408 	void Image::loadLuminanceImageData(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 char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
413 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset;
414 
415 			memcpy(dest, source, width);
416 		}
417 	}
418 
loadLuminanceFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const419 	void Image::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
420 	{
421 		for(int y = 0; y < height; y++)
422 		{
423 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
424 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
425 
426 			for(int x = 0; x < width; x++)
427 			{
428 				dest[4 * x + 0] = source[x];
429 				dest[4 * x + 1] = source[x];
430 				dest[4 * x + 2] = source[x];
431 				dest[4 * x + 3] = 1.0f;
432 			}
433 		}
434 	}
435 
loadLuminanceHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const436 	void Image::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
437 	{
438 		for(int y = 0; y < height; y++)
439 		{
440 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
441 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
442 
443 			for(int x = 0; x < width; x++)
444 			{
445 				dest[4 * x + 0] = source[x];
446 				dest[4 * x + 1] = source[x];
447 				dest[4 * x + 2] = source[x];
448 				dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
449 			}
450 		}
451 	}
452 
loadLuminanceAlphaImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const453 	void Image::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
454 	{
455 		for(int y = 0; y < height; y++)
456 		{
457 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
458 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
459 
460 			memcpy(dest, source, width * 2);
461 		}
462 	}
463 
loadLuminanceAlphaFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const464 	void Image::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
465 	{
466 		for(int y = 0; y < height; y++)
467 		{
468 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
469 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
470 
471 			for(int x = 0; x < width; x++)
472 			{
473 				dest[4 * x + 0] = source[2*x+0];
474 				dest[4 * x + 1] = source[2*x+0];
475 				dest[4 * x + 2] = source[2*x+0];
476 				dest[4 * x + 3] = source[2*x+1];
477 			}
478 		}
479 	}
480 
loadLuminanceAlphaHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const481 	void Image::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
482 	{
483 		for(int y = 0; y < height; y++)
484 		{
485 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
486 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
487 
488 			for(int x = 0; x < width; x++)
489 			{
490 				dest[4 * x + 0] = source[2*x+0];
491 				dest[4 * x + 1] = source[2*x+0];
492 				dest[4 * x + 2] = source[2*x+0];
493 				dest[4 * x + 3] = source[2*x+1];
494 			}
495 		}
496 	}
497 
loadRGBUByteImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const498 	void Image::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
499 	{
500 		for(int y = 0; y < height; y++)
501 		{
502 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
503 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
504 
505 			for(int x = 0; x < width; x++)
506 			{
507 				dest[4 * x + 0] = source[x * 3 + 2];
508 				dest[4 * x + 1] = source[x * 3 + 1];
509 				dest[4 * x + 2] = source[x * 3 + 0];
510 				dest[4 * x + 3] = 0xFF;
511 			}
512 		}
513 	}
514 
loadRGB565ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const515 	void Image::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
516 	{
517 		for(int y = 0; y < height; y++)
518 		{
519 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
520 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
521 
522 			memcpy(dest, source, width * 2);
523 		}
524 	}
525 
loadRGBFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const526 	void Image::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
527 	{
528 		for(int y = 0; y < height; y++)
529 		{
530 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
531 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
532 
533 			for(int x = 0; x < width; x++)
534 			{
535 				dest[4 * x + 0] = source[x * 3 + 0];
536 				dest[4 * x + 1] = source[x * 3 + 1];
537 				dest[4 * x + 2] = source[x * 3 + 2];
538 				dest[4 * x + 3] = 1.0f;
539 			}
540 		}
541 	}
542 
loadRGBHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const543 	void Image::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
544 	{
545 		for(int y = 0; y < height; y++)
546 		{
547 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
548 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
549 
550 			for(int x = 0; x < width; x++)
551 			{
552 				dest[4 * x + 0] = source[x * 3 + 0];
553 				dest[4 * x + 1] = source[x * 3 + 1];
554 				dest[4 * x + 2] = source[x * 3 + 2];
555 				dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
556 			}
557 		}
558 	}
559 
loadRGBAUByteImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const560 	void Image::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
561 	{
562 		for(int y = 0; y < height; y++)
563 		{
564 			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
565 			unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
566 
567 			for(int x = 0; x < width; x++)
568 			{
569 				unsigned int rgba = source[x];
570 				dest[x] = (rgba & 0xFF00FF00) | ((rgba << 16) & 0x00FF0000) | ((rgba >> 16) & 0x000000FF);
571 			}
572 		}
573 	}
574 
loadRGBA4444ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const575 	void Image::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
576 	{
577 		for(int y = 0; y < height; y++)
578 		{
579 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
580 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
581 
582 			for(int x = 0; x < width; x++)
583 			{
584 				unsigned short rgba = source[x];
585 				dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
586 				dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
587 				dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
588 				dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
589 			}
590 		}
591 	}
592 
loadRGBA5551ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const593 	void Image::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
594 	{
595 		for(int y = 0; y < height; y++)
596 		{
597 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
598 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
599 
600 			for(int x = 0; x < width; x++)
601 			{
602 				unsigned short rgba = source[x];
603 				dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
604 				dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
605 				dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
606 				dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
607 			}
608 		}
609 	}
610 
loadRGBAFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const611 	void Image::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
612 	{
613 		for(int y = 0; y < height; y++)
614 		{
615 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
616 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
617 
618 			memcpy(dest, source, width * 16);
619 		}
620 	}
621 
loadRGBAHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const622 	void Image::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
623 	{
624 		for(int y = 0; y < height; y++)
625 		{
626 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
627 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8;
628 
629 			memcpy(dest, source, width * 8);
630 		}
631 	}
632 
loadBGRAImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const633 	void Image::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
634 	{
635 		for(int y = 0; y < height; y++)
636 		{
637 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
638 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
639 
640 			memcpy(dest, source, width*4);
641 		}
642 	}
643 
loadD16ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const644 	void Image::loadD16ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
645 	{
646 		for(int y = 0; y < height; y++)
647 		{
648 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
649 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
650 
651 			for(int x = 0; x < width; x++)
652 			{
653 				dest[x] = (float)source[x] / 0xFFFF;
654 			}
655 		}
656 	}
657 
loadD32ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const658 	void Image::loadD32ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
659 	{
660 		for(int y = 0; y < height; y++)
661 		{
662 			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
663 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
664 
665 			for(int x = 0; x < width; x++)
666 			{
667 				dest[x] = (float)source[x] / 0xFFFFFFFF;
668 			}
669 		}
670 	}
671 
loadD24S8ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer)672 	void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer)
673 	{
674 		for(int y = 0; y < height; y++)
675 		{
676 			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
677 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
678 
679 			for(int x = 0; x < width; x++)
680 			{
681 				dest[x] = (float)(source[x] & 0xFFFFFF00) / 0xFFFFFF00;
682 			}
683 		}
684 
685 		unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, 0, 0, sw::PUBLIC));
686 
687 		if(stencil)
688 		{
689 			for(int y = 0; y < height; y++)
690 			{
691 				const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
692 				unsigned char *dest = static_cast<unsigned char*>(stencil) + (y + yoffset) * getStencilPitchB() + xoffset;
693 
694 				for(int x = 0; x < width; x++)
695 				{
696 					dest[x] = static_cast<unsigned char>(source[x] & 0x000000FF);   // FIXME: Quad layout
697 				}
698 			}
699 
700 			unlockStencil();
701 		}
702 	}
703 
loadCompressedData(GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLsizei imageSize,const void * pixels)704 	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
705 	{
706 		int inputPitch = ComputeCompressedPitch(width, format);
707 		int rows = imageSize / inputPitch;
708 		void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
709 
710 		if(buffer)
711 		{
712 			for(int i = 0; i < rows; i++)
713 			{
714 				memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
715 			}
716 		}
717 
718 		unlock();
719 	}
720 }