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