1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "Image.hpp" 16 17 #include "Texture.h" 18 #include "utilities.h" 19 #include "../common/debug.h" 20 #include "Common/Thread.hpp" 21 22 #define _GDI32_ 23 #include <windows.h> 24 #include <GL/GL.h> 25 #include <GL/glext.h> 26 27 namespace gl 28 { getParentResource(Texture * texture)29 static sw::Resource *getParentResource(Texture *texture) 30 { 31 if(texture) 32 { 33 return texture->getResource(); 34 } 35 36 return nullptr; 37 } 38 Image(Texture * parentTexture,GLsizei width,GLsizei height,GLenum format,GLenum type)39 Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type) 40 : sw::Surface(getParentResource(parentTexture), width, height, 1, 0, 1, selectInternalFormat(format, type), true, true) 41 , parentTexture(parentTexture), width(width), height(height), format(format), type(type) 42 , internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1) 43 { 44 referenceCount = 1; 45 } 46 Image(Texture * parentTexture,GLsizei width,GLsizei height,sw::Format internalFormat,int multiSampleDepth,bool lockable,bool renderTarget)47 Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget) 48 : sw::Surface(getParentResource(parentTexture), width, height, 1, 0, multiSampleDepth, internalFormat, lockable, renderTarget) 49 , parentTexture(parentTexture), width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), multiSampleDepth(multiSampleDepth) 50 { 51 referenceCount = 1; 52 } 53 ~Image()54 Image::~Image() 55 { 56 ASSERT(referenceCount == 0); 57 } 58 lock(unsigned int left,unsigned int top,sw::Lock lock)59 void *Image::lock(unsigned int left, unsigned int top, sw::Lock lock) 60 { 61 return lockExternal(left, top, 0, lock, sw::PUBLIC); 62 } 63 getPitch() const64 unsigned int Image::getPitch() const 65 { 66 return getExternalPitchB(); 67 } 68 unlock()69 void Image::unlock() 70 { 71 unlockExternal(); 72 } 73 lockInternal(int x,int y,int z,sw::Lock lock,sw::Accessor client)74 void *Image::lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) 75 { 76 return Surface::lockInternal(x, y, z, lock, client); 77 } 78 unlockInternal()79 void Image::unlockInternal() 80 { 81 Surface::unlockInternal(); 82 } 83 getWidth()84 int Image::getWidth() 85 { 86 return width; 87 } 88 getHeight()89 int Image::getHeight() 90 { 91 return height; 92 } 93 getFormat()94 GLenum Image::getFormat() 95 { 96 return format; 97 } 98 getType()99 GLenum Image::getType() 100 { 101 return type; 102 } 103 getInternalFormat()104 sw::Format Image::getInternalFormat() 105 { 106 return internalFormat; 107 } 108 getMultiSampleDepth()109 int Image::getMultiSampleDepth() 110 { 111 return multiSampleDepth; 112 } 113 addRef()114 void Image::addRef() 115 { 116 if(parentTexture) 117 { 118 return parentTexture->addRef(); 119 } 120 121 sw::atomicIncrement(&referenceCount); 122 } 123 release()124 void Image::release() 125 { 126 if(parentTexture) 127 { 128 return parentTexture->release(); 129 } 130 131 if(referenceCount > 0) 132 { 133 sw::atomicDecrement(&referenceCount); 134 } 135 136 if(referenceCount == 0) 137 { 138 delete this; 139 } 140 } 141 unbind()142 void Image::unbind() 143 { 144 parentTexture = nullptr; 145 146 release(); 147 } 148 selectInternalFormat(GLenum format,GLenum type)149 sw::Format Image::selectInternalFormat(GLenum format, GLenum type) 150 { 151 if(type == GL_NONE && format == GL_NONE) 152 { 153 return sw::FORMAT_NULL; 154 } 155 else if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || 156 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) 157 { 158 return sw::FORMAT_DXT1; 159 } 160 else if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) 161 { 162 return sw::FORMAT_DXT3; 163 } 164 else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) 165 { 166 return sw::FORMAT_DXT5; 167 } 168 else if(type == GL_FLOAT) 169 { 170 return sw::FORMAT_A32B32G32R32F; 171 } 172 else if(type == GL_HALF_FLOAT) 173 { 174 return sw::FORMAT_A16B16G16R16F; 175 } 176 else if(type == GL_UNSIGNED_BYTE) 177 { 178 if(format == GL_LUMINANCE) 179 { 180 return sw::FORMAT_L8; 181 } 182 else if(format == GL_LUMINANCE_ALPHA) 183 { 184 return sw::FORMAT_A8L8; 185 } 186 else if(format == GL_RGBA || format == GL_BGRA_EXT) 187 { 188 return sw::FORMAT_A8R8G8B8; 189 } 190 else if(format == GL_RGB) 191 { 192 return sw::FORMAT_X8R8G8B8; 193 } 194 else if(format == GL_ALPHA) 195 { 196 return sw::FORMAT_A8; 197 } 198 else UNREACHABLE(format); 199 } 200 else if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT) 201 { 202 if(format == GL_DEPTH_COMPONENT) 203 { 204 return sw::FORMAT_D32FS8_TEXTURE; 205 } 206 else UNREACHABLE(format); 207 } 208 else if(type == GL_UNSIGNED_INT_24_8_EXT) 209 { 210 if(format == GL_DEPTH_STENCIL_EXT) 211 { 212 return sw::FORMAT_D32FS8_TEXTURE; 213 } 214 else UNREACHABLE(format); 215 } 216 else if(type == GL_UNSIGNED_SHORT_4_4_4_4) 217 { 218 return sw::FORMAT_A8R8G8B8; 219 } 220 else if(type == GL_UNSIGNED_SHORT_5_5_5_1) 221 { 222 return sw::FORMAT_A8R8G8B8; 223 } 224 else if(type == GL_UNSIGNED_SHORT_5_6_5) 225 { 226 return sw::FORMAT_R5G6B5; 227 } 228 else if(type == GL_UNSIGNED_INT_8_8_8_8_REV) 229 { 230 return sw::FORMAT_A8R8G8B8; 231 } 232 233 else UNREACHABLE(type); 234 235 return sw::FORMAT_A8R8G8B8; 236 } 237 loadImageData(GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLint unpackAlignment,const void * input)238 void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input) 239 { 240 GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment); 241 void *buffer = lock(0, 0, sw::LOCK_WRITEONLY); 242 243 if(buffer) 244 { 245 switch(type) 246 { 247 case GL_UNSIGNED_BYTE: 248 case GL_UNSIGNED_INT_8_8_8_8_REV: 249 switch(format) 250 { 251 case GL_ALPHA: 252 loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 253 break; 254 case GL_LUMINANCE: 255 loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 256 break; 257 case GL_LUMINANCE_ALPHA: 258 loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 259 break; 260 case GL_RGB: 261 loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 262 break; 263 case GL_RGBA: 264 loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 265 break; 266 case GL_BGRA_EXT: 267 loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 268 break; 269 default: UNREACHABLE(format); 270 } 271 break; 272 case GL_UNSIGNED_SHORT_5_6_5: 273 switch(format) 274 { 275 case GL_RGB: 276 loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 277 break; 278 default: UNREACHABLE(format); 279 } 280 break; 281 case GL_UNSIGNED_SHORT_4_4_4_4: 282 switch(format) 283 { 284 case GL_RGBA: 285 loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 286 break; 287 default: UNREACHABLE(format); 288 } 289 break; 290 case GL_UNSIGNED_SHORT_5_5_5_1: 291 switch(format) 292 { 293 case GL_RGBA: 294 loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 295 break; 296 default: UNREACHABLE(format); 297 } 298 break; 299 case GL_FLOAT: 300 switch(format) 301 { 302 // float textures are converted to RGBA, not BGRA 303 case GL_ALPHA: 304 loadAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 305 break; 306 case GL_LUMINANCE: 307 loadLuminanceFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 308 break; 309 case GL_LUMINANCE_ALPHA: 310 loadLuminanceAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 311 break; 312 case GL_RGB: 313 loadRGBFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 314 break; 315 case GL_RGBA: 316 loadRGBAFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 317 break; 318 default: UNREACHABLE(format); 319 } 320 break; 321 case GL_HALF_FLOAT: 322 switch(format) 323 { 324 // float textures are converted to RGBA, not BGRA 325 case GL_ALPHA: 326 loadAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 327 break; 328 case GL_LUMINANCE: 329 loadLuminanceHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 330 break; 331 case GL_LUMINANCE_ALPHA: 332 loadLuminanceAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 333 break; 334 case GL_RGB: 335 loadRGBHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 336 break; 337 case GL_RGBA: 338 loadRGBAHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 339 break; 340 default: UNREACHABLE(format); 341 } 342 break; 343 case GL_UNSIGNED_SHORT: 344 loadD16ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 345 break; 346 case GL_UNSIGNED_INT: 347 loadD32ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 348 break; 349 case GL_UNSIGNED_INT_24_8_EXT: 350 loadD24S8ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer); 351 break; 352 default: UNREACHABLE(type); 353 } 354 } 355 356 unlock(); 357 } 358 loadAlphaImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const359 void Image::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 360 { 361 for(int y = 0; y < height; y++) 362 { 363 const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch; 364 unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset; 365 366 memcpy(dest, source, width); 367 } 368 } 369 loadAlphaFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const370 void Image::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 371 { 372 for(int y = 0; y < height; y++) 373 { 374 const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); 375 float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16); 376 377 for(int x = 0; x < width; x++) 378 { 379 dest[4 * x + 0] = 0; 380 dest[4 * x + 1] = 0; 381 dest[4 * x + 2] = 0; 382 dest[4 * x + 3] = source[x]; 383 } 384 } 385 } 386 loadAlphaHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const387 void Image::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 388 { 389 for(int y = 0; y < height; y++) 390 { 391 const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); 392 unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8); 393 394 for(int x = 0; x < width; x++) 395 { 396 dest[4 * x + 0] = 0; 397 dest[4 * x + 1] = 0; 398 dest[4 * x + 2] = 0; 399 dest[4 * x + 3] = source[x]; 400 } 401 } 402 } 403 loadLuminanceImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const404 void Image::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 405 { 406 for(int y = 0; y < height; y++) 407 { 408 const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch; 409 unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset; 410 411 memcpy(dest, source, width); 412 } 413 } 414 loadLuminanceFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const415 void Image::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 416 { 417 for(int y = 0; y < height; y++) 418 { 419 const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); 420 float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16); 421 422 for(int x = 0; x < width; x++) 423 { 424 dest[4 * x + 0] = source[x]; 425 dest[4 * x + 1] = source[x]; 426 dest[4 * x + 2] = source[x]; 427 dest[4 * x + 3] = 1.0f; 428 } 429 } 430 } 431 loadLuminanceHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const432 void Image::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 433 { 434 for(int y = 0; y < height; y++) 435 { 436 const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); 437 unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8); 438 439 for(int x = 0; x < width; x++) 440 { 441 dest[4 * x + 0] = source[x]; 442 dest[4 * x + 1] = source[x]; 443 dest[4 * x + 2] = source[x]; 444 dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1 445 } 446 } 447 } 448 loadLuminanceAlphaImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const449 void Image::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 450 { 451 for(int y = 0; y < height; y++) 452 { 453 const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch; 454 unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2; 455 456 memcpy(dest, source, width * 2); 457 } 458 } 459 loadLuminanceAlphaFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const460 void Image::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 461 { 462 for(int y = 0; y < height; y++) 463 { 464 const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); 465 float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16); 466 467 for(int x = 0; x < width; x++) 468 { 469 dest[4 * x + 0] = source[2*x+0]; 470 dest[4 * x + 1] = source[2*x+0]; 471 dest[4 * x + 2] = source[2*x+0]; 472 dest[4 * x + 3] = source[2*x+1]; 473 } 474 } 475 } 476 loadLuminanceAlphaHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const477 void Image::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 478 { 479 for(int y = 0; y < height; y++) 480 { 481 const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); 482 unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8); 483 484 for(int x = 0; x < width; x++) 485 { 486 dest[4 * x + 0] = source[2*x+0]; 487 dest[4 * x + 1] = source[2*x+0]; 488 dest[4 * x + 2] = source[2*x+0]; 489 dest[4 * x + 3] = source[2*x+1]; 490 } 491 } 492 } 493 loadRGBUByteImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const494 void Image::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 495 { 496 for(int y = 0; y < height; y++) 497 { 498 const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch; 499 unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4; 500 501 for(int x = 0; x < width; x++) 502 { 503 dest[4 * x + 0] = source[x * 3 + 2]; 504 dest[4 * x + 1] = source[x * 3 + 1]; 505 dest[4 * x + 2] = source[x * 3 + 0]; 506 dest[4 * x + 3] = 0xFF; 507 } 508 } 509 } 510 loadRGB565ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const511 void Image::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 512 { 513 for(int y = 0; y < height; y++) 514 { 515 const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); 516 unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2; 517 518 memcpy(dest, source, width * 2); 519 } 520 } 521 loadRGBFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const522 void Image::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 523 { 524 for(int y = 0; y < height; y++) 525 { 526 const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); 527 float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16); 528 529 for(int x = 0; x < width; x++) 530 { 531 dest[4 * x + 0] = source[x * 3 + 0]; 532 dest[4 * x + 1] = source[x * 3 + 1]; 533 dest[4 * x + 2] = source[x * 3 + 2]; 534 dest[4 * x + 3] = 1.0f; 535 } 536 } 537 } 538 loadRGBHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const539 void Image::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 540 { 541 for(int y = 0; y < height; y++) 542 { 543 const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); 544 unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8); 545 546 for(int x = 0; x < width; x++) 547 { 548 dest[4 * x + 0] = source[x * 3 + 0]; 549 dest[4 * x + 1] = source[x * 3 + 1]; 550 dest[4 * x + 2] = source[x * 3 + 2]; 551 dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1 552 } 553 } 554 } 555 loadRGBAUByteImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const556 void Image::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 557 { 558 for(int y = 0; y < height; y++) 559 { 560 const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); 561 unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4); 562 563 for(int x = 0; x < width; x++) 564 { 565 unsigned int rgba = source[x]; 566 dest[x] = (rgba & 0xFF00FF00) | ((rgba << 16) & 0x00FF0000) | ((rgba >> 16) & 0x000000FF); 567 } 568 } 569 } 570 loadRGBA4444ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const571 void Image::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 572 { 573 for(int y = 0; y < height; y++) 574 { 575 const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); 576 unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4; 577 578 for(int x = 0; x < width; x++) 579 { 580 unsigned short rgba = source[x]; 581 dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4); 582 dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8); 583 dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12); 584 dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0); 585 } 586 } 587 } 588 loadRGBA5551ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const589 void Image::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 590 { 591 for(int y = 0; y < height; y++) 592 { 593 const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); 594 unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4; 595 596 for(int x = 0; x < width; x++) 597 { 598 unsigned short rgba = source[x]; 599 dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3); 600 dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8); 601 dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); 602 dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0; 603 } 604 } 605 } 606 loadRGBAFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const607 void Image::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 608 { 609 for(int y = 0; y < height; y++) 610 { 611 const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); 612 float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16); 613 614 memcpy(dest, source, width * 16); 615 } 616 } 617 loadRGBAHalfFloatImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const618 void Image::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 619 { 620 for(int y = 0; y < height; y++) 621 { 622 const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch; 623 unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8; 624 625 memcpy(dest, source, width * 8); 626 } 627 } 628 loadBGRAImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const629 void Image::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 630 { 631 for(int y = 0; y < height; y++) 632 { 633 const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch; 634 unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4; 635 636 memcpy(dest, source, width*4); 637 } 638 } 639 loadD16ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const640 void Image::loadD16ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 641 { 642 for(int y = 0; y < height; y++) 643 { 644 const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); 645 float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4); 646 647 for(int x = 0; x < width; x++) 648 { 649 dest[x] = (float)source[x] / 0xFFFF; 650 } 651 } 652 } 653 loadD32ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer) const654 void Image::loadD32ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const 655 { 656 for(int y = 0; y < height; y++) 657 { 658 const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); 659 float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4); 660 661 for(int x = 0; x < width; x++) 662 { 663 dest[x] = (float)source[x] / 0xFFFFFFFF; 664 } 665 } 666 } 667 loadD24S8ImageData(GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,int inputPitch,const void * input,void * buffer)668 void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) 669 { 670 for(int y = 0; y < height; y++) 671 { 672 const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); 673 float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4); 674 675 for(int x = 0; x < width; x++) 676 { 677 dest[x] = (float)(source[x] & 0xFFFFFF00) / 0xFFFFFF00; 678 } 679 } 680 681 unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, 0, 0, sw::PUBLIC)); 682 683 if(stencil) 684 { 685 for(int y = 0; y < height; y++) 686 { 687 const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); 688 unsigned char *dest = static_cast<unsigned char*>(stencil) + (y + yoffset) * getStencilPitchB() + xoffset; 689 690 for(int x = 0; x < width; x++) 691 { 692 dest[x] = static_cast<unsigned char>(source[x] & 0x000000FF); // FIXME: Quad layout 693 } 694 } 695 696 unlockStencil(); 697 } 698 } 699 loadCompressedData(GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLsizei imageSize,const void * pixels)700 void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) 701 { 702 int inputPitch = ComputeCompressedPitch(width, format); 703 int rows = imageSize / inputPitch; 704 void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY); 705 706 if(buffer) 707 { 708 for(int i = 0; i < rows; i++) 709 { 710 memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch); 711 } 712 } 713 714 unlock(); 715 } 716 }