blob: 6a8c01dc8813d66afa76bd7cc30065451fe973a1 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
Nicolas Capens264f1522015-01-09 17:21:17 -05002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// 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
Nicolas Capens264f1522015-01-09 17:21:17 -05006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
Nicolas Capens264f1522015-01-09 17:21:17 -05008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// 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.
Nicolas Capens264f1522015-01-09 17:21:17 -050014
15#include "Image.hpp"
16
17#include "Texture.h"
18#include "utilities.h"
19#include "../common/debug.h"
20#include "Common/Thread.hpp"
21
Nicolas Capensa9b49372015-01-30 00:33:26 -050022#define _GDI32_
23#include <windows.h>
24#include <GL/GL.h>
Nicolas Capensa9b49372015-01-30 00:33:26 -050025#include <GL/glext.h>
Nicolas Capens264f1522015-01-09 17:21:17 -050026
Nicolas Capensf4486fd2015-01-22 11:10:37 -050027namespace gl
Nicolas Capens264f1522015-01-09 17:21:17 -050028{
29 static sw::Resource *getParentResource(Texture *texture)
30 {
31 if(texture)
32 {
33 return texture->getResource();
34 }
35
36 return 0;
37 }
38
39 Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
Nicolas Capensa9b49372015-01-30 00:33:26 -050040 : 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)
Nicolas Capens264f1522015-01-09 17:21:17 -050043 {
44 referenceCount = 1;
45 }
46
47 Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget)
Nicolas Capensa9b49372015-01-30 00:33:26 -050048 : 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)
Nicolas Capens264f1522015-01-09 17:21:17 -050050 {
51 referenceCount = 1;
52 }
53
54 Image::~Image()
55 {
56 ASSERT(referenceCount == 0);
57 }
58
Nicolas Capensa9b49372015-01-30 00:33:26 -050059 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 int Image::getWidth()
75 {
76 return width;
77 }
Nicolas Capens0bac2852016-05-07 06:09:58 -040078
Nicolas Capensa9b49372015-01-30 00:33:26 -050079 int Image::getHeight()
80 {
81 return height;
82 }
83
84 GLenum Image::getFormat()
85 {
86 return format;
87 }
Nicolas Capens0bac2852016-05-07 06:09:58 -040088
Nicolas Capensa9b49372015-01-30 00:33:26 -050089 GLenum Image::getType()
90 {
91 return type;
92 }
Nicolas Capens0bac2852016-05-07 06:09:58 -040093
Nicolas Capensa9b49372015-01-30 00:33:26 -050094 sw::Format Image::getInternalFormat()
95 {
96 return internalFormat;
97 }
Nicolas Capens0bac2852016-05-07 06:09:58 -040098
Nicolas Capensa9b49372015-01-30 00:33:26 -050099 int Image::getMultiSampleDepth()
100 {
101 return multiSampleDepth;
102 }
103
Nicolas Capens264f1522015-01-09 17:21:17 -0500104 void Image::addRef()
105 {
106 if(parentTexture)
107 {
108 return parentTexture->addRef();
109 }
110
111 sw::atomicIncrement(&referenceCount);
112 }
113
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 {
Nicolas Capens264f1522015-01-09 17:21:17 -0500128 delete this;
129 }
130 }
131
Nicolas Capensa9b49372015-01-30 00:33:26 -0500132 void Image::unbind()
Nicolas Capens264f1522015-01-09 17:21:17 -0500133 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500134 parentTexture = 0;
Nicolas Capens264f1522015-01-09 17:21:17 -0500135
136 release();
137 }
138
139 sw::Format Image::selectInternalFormat(GLenum format, GLenum type)
140 {
Nicolas Capens0bac2852016-05-07 06:09:58 -0400141 if(type == GL_NONE && format == GL_NONE)
142 {
143 return sw::FORMAT_NULL;
144 }
145 else
Nicolas Capens264f1522015-01-09 17:21:17 -0500146 #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 }
Nicolas Capensa9b49372015-01-30 00:33:26 -0500152 else if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500153 {
154 return sw::FORMAT_DXT3;
155 }
Nicolas Capensa9b49372015-01-30 00:33:26 -0500156 else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500157 {
158 return sw::FORMAT_DXT5;
159 }
160 else
161 #endif
162 if(type == GL_FLOAT)
163 {
164 return sw::FORMAT_A32B32G32R32F;
165 }
Nicolas Capensa9b49372015-01-30 00:33:26 -0500166 else if(type == GL_HALF_FLOAT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500167 {
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 }
Nicolas Capens3713cd42015-06-22 10:41:54 -0400192 else UNREACHABLE(format);
Nicolas Capens264f1522015-01-09 17:21:17 -0500193 }
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 }
Nicolas Capens3713cd42015-06-22 10:41:54 -0400200 else UNREACHABLE(format);
Nicolas Capens264f1522015-01-09 17:21:17 -0500201 }
Nicolas Capensa9b49372015-01-30 00:33:26 -0500202 else if(type == GL_UNSIGNED_INT_24_8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500203 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500204 if(format == GL_DEPTH_STENCIL_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500205 {
206 return sw::FORMAT_D32FS8_TEXTURE;
207 }
Nicolas Capens3713cd42015-06-22 10:41:54 -0400208 else UNREACHABLE(format);
Nicolas Capens264f1522015-01-09 17:21:17 -0500209 }
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 {
Nicolas Capens5a86ee92015-09-04 10:45:43 -0400220 return sw::FORMAT_R5G6B5;
Nicolas Capens264f1522015-01-09 17:21:17 -0500221 }
Nicolas Capens0bac2852016-05-07 06:09:58 -0400222 else if(type == GL_UNSIGNED_INT_8_8_8_8_REV)
223 {
224 return sw::FORMAT_A8R8G8B8;
225 }
Nicolas Capensa9b49372015-01-30 00:33:26 -0500226
Nicolas Capens3713cd42015-06-22 10:41:54 -0400227 else UNREACHABLE(type);
Nicolas Capens264f1522015-01-09 17:21:17 -0500228
229 return sw::FORMAT_A8R8G8B8;
230 }
231
Alexis Hetub027aa92015-01-19 15:56:12 -0500232 void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
Nicolas Capens264f1522015-01-09 17:21:17 -0500233 {
234 GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
235 void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400236
Nicolas Capens264f1522015-01-09 17:21:17 -0500237 if(buffer)
238 {
239 switch(type)
240 {
241 case GL_UNSIGNED_BYTE:
Nicolas Capens0bac2852016-05-07 06:09:58 -0400242 case GL_UNSIGNED_INT_8_8_8_8_REV:
Nicolas Capens264f1522015-01-09 17:21:17 -0500243 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;
Nicolas Capens3713cd42015-06-22 10:41:54 -0400263 default: UNREACHABLE(format);
Nicolas Capens264f1522015-01-09 17:21:17 -0500264 }
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;
Nicolas Capens3713cd42015-06-22 10:41:54 -0400272 default: UNREACHABLE(format);
Nicolas Capens264f1522015-01-09 17:21:17 -0500273 }
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;
Nicolas Capens3713cd42015-06-22 10:41:54 -0400281 default: UNREACHABLE(format);
Nicolas Capens264f1522015-01-09 17:21:17 -0500282 }
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;
Nicolas Capens3713cd42015-06-22 10:41:54 -0400290 default: UNREACHABLE(format);
Nicolas Capens264f1522015-01-09 17:21:17 -0500291 }
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;
Nicolas Capens3713cd42015-06-22 10:41:54 -0400312 default: UNREACHABLE(format);
Nicolas Capens264f1522015-01-09 17:21:17 -0500313 }
314 break;
Nicolas Capens3713cd42015-06-22 10:41:54 -0400315 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500316 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;
Nicolas Capens3713cd42015-06-22 10:41:54 -0400334 default: UNREACHABLE(format);
Nicolas Capens264f1522015-01-09 17:21:17 -0500335 }
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;
Nicolas Capensa9b49372015-01-30 00:33:26 -0500343 case GL_UNSIGNED_INT_24_8_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500344 loadD24S8ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
345 break;
Nicolas Capens3713cd42015-06-22 10:41:54 -0400346 default: UNREACHABLE(type);
Nicolas Capens264f1522015-01-09 17:21:17 -0500347 }
348 }
349
350 unlock();
351 }
352
353 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
364 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400370
Nicolas Capens264f1522015-01-09 17:21:17 -0500371 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
381 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400387
Nicolas Capens264f1522015-01-09 17:21:17 -0500388 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
398 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
409 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400415
Nicolas Capens264f1522015-01-09 17:21:17 -0500416 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
426 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400432
Nicolas Capens264f1522015-01-09 17:21:17 -0500433 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
443 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;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400449
Nicolas Capens264f1522015-01-09 17:21:17 -0500450 memcpy(dest, source, width * 2);
451 }
452 }
453
454 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400460
Nicolas Capens264f1522015-01-09 17:21:17 -0500461 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
471 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400477
Nicolas Capens264f1522015-01-09 17:21:17 -0500478 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
488 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;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400494
Nicolas Capens264f1522015-01-09 17:21:17 -0500495 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
505 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);
Nicolas Capens5a86ee92015-09-04 10:45:43 -0400510 unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400511
Nicolas Capens5a86ee92015-09-04 10:45:43 -0400512 memcpy(dest, source, width * 2);
Nicolas Capens264f1522015-01-09 17:21:17 -0500513 }
514 }
515
516 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400522
Nicolas Capens264f1522015-01-09 17:21:17 -0500523 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
533 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400539
Nicolas Capens264f1522015-01-09 17:21:17 -0500540 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
550 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
565 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;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400571
Nicolas Capens264f1522015-01-09 17:21:17 -0500572 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
583 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;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400589
Nicolas Capens264f1522015-01-09 17:21:17 -0500590 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
601 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400607
Nicolas Capens264f1522015-01-09 17:21:17 -0500608 memcpy(dest, source, width * 16);
609 }
610 }
611
612 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;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400618
Nicolas Capens264f1522015-01-09 17:21:17 -0500619 memcpy(dest, source, width * 8);
620 }
621 }
622
623 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;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400629
Nicolas Capens264f1522015-01-09 17:21:17 -0500630 memcpy(dest, source, width*4);
631 }
632 }
633
634 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
648 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
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
Alexis Hetua52dfbd2016-10-05 17:03:30 -0400675 unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, 0, 0, sw::PUBLIC));
Nicolas Capens264f1522015-01-09 17:21:17 -0500676
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
Alexis Hetub027aa92015-01-19 15:56:12 -0500694 void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -0500695 {
696 int inputPitch = ComputeCompressedPitch(width, format);
697 int rows = imageSize / inputPitch;
698 void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
699
Nicolas Capens0bac2852016-05-07 06:09:58 -0400700 if(buffer)
701 {
Nicolas Capens264f1522015-01-09 17:21:17 -0500702 for(int i = 0; i < rows; i++)
703 {
704 memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
705 }
Nicolas Capens0bac2852016-05-07 06:09:58 -0400706 }
Nicolas Capens264f1522015-01-09 17:21:17 -0500707
708 unlock();
709 }
710}