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