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 }