Surface.hpp revision 43577b8cc676a157ceab055ead33a441c23b2cf5
1// SwiftShader Software Renderer 2// 3// Copyright(c) 2005-2013 TransGaming Inc. 4// 5// All rights reserved. No part of this software may be copied, distributed, transmitted, 6// transcribed, stored in a retrieval system, translated into any human or computer 7// language by any means, or disclosed to third parties without the explicit written 8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express 9// or implied, including but not limited to any patent rights, are granted to you. 10// 11 12#ifndef sw_Surface_hpp 13#define sw_Surface_hpp 14 15#include "Color.hpp" 16#include "Main/Config.hpp" 17#include "Common/Resource.hpp" 18 19namespace sw 20{ 21 class Resource; 22 23 struct Rect 24 { 25 Rect() {} 26 Rect(int x0i, int y0i, int x1i, int y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {} 27 28 void clip(int minX, int minY, int maxX, int maxY); 29 30 int x0; // Inclusive 31 int y0; // Inclusive 32 int x1; // Exclusive 33 int y1; // Exclusive 34 }; 35 36 struct SliceRect : public Rect 37 { 38 SliceRect() : slice(0) {} 39 SliceRect(const Rect& rect) : Rect(rect), slice(0) {} 40 SliceRect(const Rect& rect, int s) : Rect(rect), slice(s) {} 41 SliceRect(int x0, int y0, int x1, int y1, int s) : Rect(x0, y0, x1, y1), slice(s) {} 42 int slice; 43 }; 44 45 enum Format : unsigned char 46 { 47 FORMAT_NULL, 48 49 FORMAT_A8, 50 FORMAT_R8I, 51 FORMAT_R8UI, 52 FORMAT_R8I_SNORM, 53 FORMAT_R8, // UI_SNORM 54 FORMAT_R16I, 55 FORMAT_R16UI, 56 FORMAT_R32I, 57 FORMAT_R32UI, 58 FORMAT_R3G3B2, 59 FORMAT_A8R3G3B2, 60 FORMAT_X4R4G4B4, 61 FORMAT_A4R4G4B4, 62 FORMAT_R4G4B4A4, 63 FORMAT_R5G6B5, 64 FORMAT_R8G8B8, 65 FORMAT_B8G8R8, 66 FORMAT_X8R8G8B8, 67 FORMAT_A8R8G8B8, 68 FORMAT_X8B8G8R8I, 69 FORMAT_X8B8G8R8UI, 70 FORMAT_X8B8G8R8I_SNORM, 71 FORMAT_X8B8G8R8, // UI_SNORM 72 FORMAT_A8B8G8R8I, 73 FORMAT_A8B8G8R8UI, 74 FORMAT_A8B8G8R8I_SNORM, 75 FORMAT_A8B8G8R8, // UI_SNORM 76 FORMAT_X1R5G5B5, 77 FORMAT_A1R5G5B5, 78 FORMAT_R5G5B5A1, 79 FORMAT_G8R8I, 80 FORMAT_G8R8UI, 81 FORMAT_G8R8I_SNORM, 82 FORMAT_G8R8, // UI_SNORM 83 FORMAT_G16R16, // D3D format 84 FORMAT_G16R16I, 85 FORMAT_G16R16UI, 86 FORMAT_G32R32I, 87 FORMAT_G32R32UI, 88 FORMAT_A2R10G10B10, 89 FORMAT_A2B10G10R10, 90 FORMAT_A16B16G16R16, // D3D format 91 FORMAT_X16B16G16R16I, 92 FORMAT_X16B16G16R16UI, 93 FORMAT_A16B16G16R16I, 94 FORMAT_A16B16G16R16UI, 95 FORMAT_X32B32G32R32I, 96 FORMAT_X32B32G32R32UI, 97 FORMAT_A32B32G32R32I, 98 FORMAT_A32B32G32R32UI, 99 // Paletted formats 100 FORMAT_P8, 101 FORMAT_A8P8, 102 // Compressed formats 103 FORMAT_DXT1, 104 FORMAT_DXT3, 105 FORMAT_DXT5, 106 FORMAT_ATI1, 107 FORMAT_ATI2, 108 FORMAT_ETC1, 109 FORMAT_R11_EAC, 110 FORMAT_SIGNED_R11_EAC, 111 FORMAT_RG11_EAC, 112 FORMAT_SIGNED_RG11_EAC, 113 FORMAT_RGB8_ETC2, 114 FORMAT_SRGB8_ETC2, 115 FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 116 FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 117 FORMAT_RGBA8_ETC2_EAC, 118 FORMAT_SRGB8_ALPHA8_ETC2_EAC, 119 FORMAT_RGBA_ASTC_4x4_KHR, 120 FORMAT_RGBA_ASTC_5x4_KHR, 121 FORMAT_RGBA_ASTC_5x5_KHR, 122 FORMAT_RGBA_ASTC_6x5_KHR, 123 FORMAT_RGBA_ASTC_6x6_KHR, 124 FORMAT_RGBA_ASTC_8x5_KHR, 125 FORMAT_RGBA_ASTC_8x6_KHR, 126 FORMAT_RGBA_ASTC_8x8_KHR, 127 FORMAT_RGBA_ASTC_10x5_KHR, 128 FORMAT_RGBA_ASTC_10x6_KHR, 129 FORMAT_RGBA_ASTC_10x8_KHR, 130 FORMAT_RGBA_ASTC_10x10_KHR, 131 FORMAT_RGBA_ASTC_12x10_KHR, 132 FORMAT_RGBA_ASTC_12x12_KHR, 133 FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR, 134 FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR, 135 FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR, 136 FORMAT_SRGB8_ALPHA8_ASTC_6x5_KHR, 137 FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR, 138 FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR, 139 FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR, 140 FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR, 141 FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR, 142 FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR, 143 FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR, 144 FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR, 145 FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR, 146 FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR, 147 // Floating-point formats 148 FORMAT_A16F, 149 FORMAT_R16F, 150 FORMAT_G16R16F, 151 FORMAT_B16G16R16F, 152 FORMAT_A16B16G16R16F, 153 FORMAT_A32F, 154 FORMAT_R32F, 155 FORMAT_G32R32F, 156 FORMAT_B32G32R32F, 157 FORMAT_A32B32G32R32F, 158 // Bump map formats 159 FORMAT_V8U8, 160 FORMAT_L6V5U5, 161 FORMAT_Q8W8V8U8, 162 FORMAT_X8L8V8U8, 163 FORMAT_A2W10V10U10, 164 FORMAT_V16U16, 165 FORMAT_A16W16V16U16, 166 FORMAT_Q16W16V16U16, 167 // Luminance formats 168 FORMAT_L8, 169 FORMAT_A4L4, 170 FORMAT_L16, 171 FORMAT_A8L8, 172 FORMAT_L16F, 173 FORMAT_A16L16F, 174 FORMAT_L32F, 175 FORMAT_A32L32F, 176 // Depth/stencil formats 177 FORMAT_D16, 178 FORMAT_D32, 179 FORMAT_D24X8, 180 FORMAT_D24S8, 181 FORMAT_D24FS8, 182 FORMAT_D32F, // Quad layout 183 FORMAT_D32F_COMPLEMENTARY, // Quad layout, 1 - z 184 FORMAT_D32F_LOCKABLE, // Linear layout 185 FORMAT_D32FS8_TEXTURE, // Linear layout, no PCF 186 FORMAT_D32FS8_SHADOW, // Linear layout, PCF 187 FORMAT_DF24S8, 188 FORMAT_DF16S8, 189 FORMAT_INTZ, 190 FORMAT_S8, 191 // Quad layout framebuffer 192 FORMAT_X8G8R8B8Q, 193 FORMAT_A8G8R8B8Q, 194 // YUV formats 195 FORMAT_YV12_BT601, 196 FORMAT_YV12_BT709, 197 FORMAT_YV12_JFIF, // Full-swing BT.601 198 199 FORMAT_LAST = FORMAT_YV12_JFIF 200 }; 201 202 enum Lock 203 { 204 LOCK_UNLOCKED, 205 LOCK_READONLY, 206 LOCK_WRITEONLY, 207 LOCK_READWRITE, 208 LOCK_DISCARD 209 }; 210 211 class Surface 212 { 213 private: 214 struct Buffer 215 { 216 public: 217 void write(int x, int y, int z, const Color<float> &color); 218 void write(int x, int y, const Color<float> &color); 219 void write(void *element, const Color<float> &color); 220 Color<float> read(int x, int y, int z) const; 221 Color<float> read(int x, int y) const; 222 Color<float> read(void *element) const; 223 Color<float> sample(float x, float y, float z) const; 224 Color<float> sample(float x, float y) const; 225 226 void *lockRect(int x, int y, int z, Lock lock); 227 void unlockRect(); 228 229 void *buffer; 230 int width; 231 int height; 232 int depth; 233 int bytes; 234 int pitchB; 235 int pitchP; 236 int sliceB; 237 int sliceP; 238 Format format; 239 Lock lock; 240 241 bool dirty; 242 }; 243 244 public: 245 Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice); 246 Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget); 247 248 virtual ~Surface(); 249 250 inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false); 251 inline void unlock(bool internal = false); 252 inline int getWidth() const; 253 inline int getHeight() const; 254 inline int getDepth() const; 255 inline Format getFormat(bool internal = false) const; 256 inline int getPitchB(bool internal = false) const; 257 inline int getPitchP(bool internal = false) const; 258 inline int getSliceB(bool internal = false) const; 259 inline int getSliceP(bool internal = false) const; 260 261 void *lockExternal(int x, int y, int z, Lock lock, Accessor client); 262 void unlockExternal(); 263 inline Format getExternalFormat() const; 264 inline int getExternalPitchB() const; 265 inline int getExternalPitchP() const; 266 inline int getExternalSliceB() const; 267 inline int getExternalSliceP() const; 268 269 virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client); 270 virtual void unlockInternal(); 271 inline Format getInternalFormat() const; 272 inline int getInternalPitchB() const; 273 inline int getInternalPitchP() const; 274 inline int getInternalSliceB() const; 275 inline int getInternalSliceP() const; 276 277 void *lockStencil(int front, Accessor client); 278 void unlockStencil(); 279 inline int getStencilPitchB() const; 280 inline int getStencilSliceB() const; 281 282 inline int getMultiSampleCount() const; 283 inline int getSuperSampleCount() const; 284 285 void clearColorBuffer(float red, float green, float blue, float alpha, unsigned int rgbaMask, int x0, int y0, int width, int height); 286 void clearDepthBuffer(float depth, int x0, int y0, int width, int height); 287 void clearStencilBuffer(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height); 288 void fill(const Color<float> &color, int x0, int y0, int width, int height); 289 290 Color<float> readExternal(int x, int y, int z) const; 291 Color<float> readExternal(int x, int y) const; 292 Color<float> sampleExternal(float x, float y, float z) const; 293 Color<float> sampleExternal(float x, float y) const; 294 void writeExternal(int x, int y, int z, const Color<float> &color); 295 void writeExternal(int x, int y, const Color<float> &color); 296 297 void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter); 298 void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter); 299 300 bool hasStencil() const; 301 bool hasDepth() const; 302 bool hasPalette() const; 303 bool isRenderTarget() const; 304 305 bool hasDirtyMipmaps() const; 306 void cleanMipmaps(); 307 inline bool isExternalDirty() const; 308 Resource *getResource(); 309 310 static int bytes(Format format); 311 static int pitchB(int width, Format format, bool target); 312 static int pitchP(int width, Format format, bool target); 313 static int sliceB(int width, int height, Format format, bool target); 314 static int sliceP(int width, int height, Format format, bool target); 315 static unsigned int size(int width, int height, int depth, Format format); // FIXME: slice * depth 316 317 static bool isStencil(Format format); 318 static bool isDepth(Format format); 319 static bool isPalette(Format format); 320 321 static bool isFloatFormat(Format format); 322 static bool isUnsignedComponent(Format format, int component); 323 static bool isSRGBreadable(Format format); 324 static bool isSRGBwritable(Format format); 325 static bool isCompressed(Format format); 326 static bool isNonNormalizedInteger(Format format); 327 static int componentCount(Format format); 328 329 static void setTexturePalette(unsigned int *palette); 330 331 protected: 332 sw::Resource *resource; 333 334 private: 335 typedef unsigned char byte; 336 typedef unsigned short word; 337 typedef unsigned int dword; 338 typedef uint64_t qword; 339 340 #if S3TC_SUPPORT 341 struct DXT1 342 { 343 word c0; 344 word c1; 345 dword lut; 346 }; 347 348 struct DXT3 349 { 350 qword a; 351 352 word c0; 353 word c1; 354 dword lut; 355 }; 356 357 struct DXT5 358 { 359 union 360 { 361 struct 362 { 363 byte a0; 364 byte a1; 365 }; 366 367 qword alut; // Skip first 16 bit 368 }; 369 370 word c0; 371 word c1; 372 dword clut; 373 }; 374 #endif 375 376 struct ATI2 377 { 378 union 379 { 380 struct 381 { 382 byte y0; 383 byte y1; 384 }; 385 386 qword ylut; // Skip first 16 bit 387 }; 388 389 union 390 { 391 struct 392 { 393 byte x0; 394 byte x1; 395 }; 396 397 qword xlut; // Skip first 16 bit 398 }; 399 }; 400 401 struct ATI1 402 { 403 union 404 { 405 struct 406 { 407 byte r0; 408 byte r1; 409 }; 410 411 qword rlut; // Skip first 16 bit 412 }; 413 }; 414 415 static void decodeR8G8B8(Buffer &destination, const Buffer &source); 416 static void decodeX1R5G5B5(Buffer &destination, const Buffer &source); 417 static void decodeA1R5G5B5(Buffer &destination, const Buffer &source); 418 static void decodeX4R4G4B4(Buffer &destination, const Buffer &source); 419 static void decodeA4R4G4B4(Buffer &destination, const Buffer &source); 420 static void decodeP8(Buffer &destination, const Buffer &source); 421 422 #if S3TC_SUPPORT 423 static void decodeDXT1(Buffer &internal, const Buffer &external); 424 static void decodeDXT3(Buffer &internal, const Buffer &external); 425 static void decodeDXT5(Buffer &internal, const Buffer &external); 426 #endif 427 static void decodeATI1(Buffer &internal, const Buffer &external); 428 static void decodeATI2(Buffer &internal, const Buffer &external); 429 static void decodeEAC(Buffer &internal, const Buffer &external, int nbChannels, bool isSigned); 430 static void decodeETC2(Buffer &internal, const Buffer &external, int nbAlphaBits, bool isSRGB); 431 static void decodeASTC(Buffer &internal, const Buffer &external, int xSize, int ySize, int zSize, bool isSRGB); 432 433 static void update(Buffer &destination, Buffer &source); 434 static void genericUpdate(Buffer &destination, Buffer &source); 435 static void *allocateBuffer(int width, int height, int depth, Format format); 436 static void memfill4(void *buffer, int pattern, int bytes); 437 438 bool identicalFormats() const; 439 Format selectInternalFormat(Format format) const; 440 441 void resolve(); 442 443 Buffer external; 444 Buffer internal; 445 Buffer stencil; 446 447 const bool lockable; 448 const bool renderTarget; 449 450 bool dirtyMipmaps; 451 unsigned int paletteUsed; 452 453 static unsigned int *palette; // FIXME: Not multi-device safe 454 static unsigned int paletteID; 455 456 bool hasParent; 457 bool ownExternal; 458 }; 459} 460 461#undef min 462#undef max 463 464namespace sw 465{ 466 void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal) 467 { 468 return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client); 469 } 470 471 void Surface::unlock(bool internal) 472 { 473 return internal ? unlockInternal() : unlockExternal(); 474 } 475 476 int Surface::getWidth() const 477 { 478 return external.width; 479 } 480 481 int Surface::getHeight() const 482 { 483 return external.height; 484 } 485 486 int Surface::getDepth() const 487 { 488 return external.depth; 489 } 490 491 Format Surface::getFormat(bool internal) const 492 { 493 return internal ? getInternalFormat() : getExternalFormat(); 494 } 495 496 int Surface::getPitchB(bool internal) const 497 { 498 return internal ? getInternalPitchB() : getExternalPitchB(); 499 } 500 501 int Surface::getPitchP(bool internal) const 502 { 503 return internal ? getInternalPitchP() : getExternalPitchB(); 504 } 505 506 int Surface::getSliceB(bool internal) const 507 { 508 return internal ? getInternalSliceB() : getExternalSliceB(); 509 } 510 511 int Surface::getSliceP(bool internal) const 512 { 513 return internal ? getInternalSliceP() : getExternalSliceB(); 514 } 515 516 Format Surface::getExternalFormat() const 517 { 518 return external.format; 519 } 520 521 int Surface::getExternalPitchB() const 522 { 523 return external.pitchB; 524 } 525 526 int Surface::getExternalPitchP() const 527 { 528 return external.pitchP; 529 } 530 531 int Surface::getExternalSliceB() const 532 { 533 return external.sliceB; 534 } 535 536 int Surface::getExternalSliceP() const 537 { 538 return external.sliceP; 539 } 540 541 Format Surface::getInternalFormat() const 542 { 543 return internal.format; 544 } 545 546 int Surface::getInternalPitchB() const 547 { 548 return internal.pitchB; 549 } 550 551 int Surface::getInternalPitchP() const 552 { 553 return internal.pitchP; 554 } 555 556 int Surface::getInternalSliceB() const 557 { 558 return internal.sliceB; 559 } 560 561 int Surface::getInternalSliceP() const 562 { 563 return internal.sliceP; 564 } 565 566 int Surface::getStencilPitchB() const 567 { 568 return stencil.pitchB; 569 } 570 571 int Surface::getStencilSliceB() const 572 { 573 return stencil.sliceB; 574 } 575 576 int Surface::getMultiSampleCount() const 577 { 578 return sw::min(internal.depth, 4); 579 } 580 581 int Surface::getSuperSampleCount() const 582 { 583 return internal.depth > 4 ? internal.depth / 4 : 1; 584 } 585 586 bool Surface::isExternalDirty() const 587 { 588 return external.buffer && external.buffer != internal.buffer && external.dirty; 589 } 590} 591 592#endif // sw_Surface_hpp 593