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 #ifndef sw_Surface_hpp 16 #define sw_Surface_hpp 17 18 #include "Color.hpp" 19 #include "Main/Config.hpp" 20 #include "Common/Resource.hpp" 21 22 namespace sw 23 { 24 class Resource; 25 26 template <typename T> struct RectT 27 { RectTsw::RectT28 RectT() {} RectTsw::RectT29 RectT(T x0i, T y0i, T x1i, T y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {} 30 clipsw::RectT31 void clip(T minX, T minY, T maxX, T maxY) 32 { 33 x0 = clamp(x0, minX, maxX); 34 y0 = clamp(y0, minY, maxY); 35 x1 = clamp(x1, minX, maxX); 36 y1 = clamp(y1, minY, maxY); 37 } 38 widthsw::RectT39 T width() const { return x1 - x0; } heightsw::RectT40 T height() const { return y1 - y0; } 41 42 T x0; // Inclusive 43 T y0; // Inclusive 44 T x1; // Exclusive 45 T y1; // Exclusive 46 }; 47 48 typedef RectT<int> Rect; 49 typedef RectT<float> RectF; 50 51 template<typename T> struct SliceRectT : public RectT<T> 52 { SliceRectTsw::SliceRectT53 SliceRectT() : slice(0) {} SliceRectTsw::SliceRectT54 SliceRectT(const RectT<T>& rect) : RectT<T>(rect), slice(0) {} SliceRectTsw::SliceRectT55 SliceRectT(const RectT<T>& rect, int s) : RectT<T>(rect), slice(s) {} SliceRectTsw::SliceRectT56 SliceRectT(T x0, T y0, T x1, T y1, int s) : RectT<T>(x0, y0, x1, y1), slice(s) {} 57 int slice; 58 }; 59 60 typedef SliceRectT<int> SliceRect; 61 typedef SliceRectT<float> SliceRectF; 62 63 enum Format : unsigned char 64 { 65 FORMAT_NULL, 66 67 FORMAT_A8, 68 FORMAT_R8I, 69 FORMAT_R8UI, 70 FORMAT_R8_SNORM, 71 FORMAT_R8, 72 FORMAT_R16I, 73 FORMAT_R16UI, 74 FORMAT_R32I, 75 FORMAT_R32UI, 76 FORMAT_R3G3B2, 77 FORMAT_A8R3G3B2, 78 FORMAT_X4R4G4B4, 79 FORMAT_A4R4G4B4, 80 FORMAT_R4G4B4A4, 81 FORMAT_R5G6B5, 82 FORMAT_R8G8B8, 83 FORMAT_B8G8R8, 84 FORMAT_X8R8G8B8, 85 FORMAT_A8R8G8B8, 86 FORMAT_X8B8G8R8I, 87 FORMAT_X8B8G8R8UI, 88 FORMAT_X8B8G8R8_SNORM, 89 FORMAT_X8B8G8R8, 90 FORMAT_A8B8G8R8I, 91 FORMAT_A8B8G8R8UI, 92 FORMAT_A8B8G8R8_SNORM, 93 FORMAT_A8B8G8R8, 94 FORMAT_SRGB8_X8, 95 FORMAT_SRGB8_A8, 96 FORMAT_X1R5G5B5, 97 FORMAT_A1R5G5B5, 98 FORMAT_R5G5B5A1, 99 FORMAT_G8R8I, 100 FORMAT_G8R8UI, 101 FORMAT_G8R8_SNORM, 102 FORMAT_G8R8, 103 FORMAT_G16R16, 104 FORMAT_G16R16I, 105 FORMAT_G16R16UI, 106 FORMAT_G32R32I, 107 FORMAT_G32R32UI, 108 FORMAT_A2R10G10B10, 109 FORMAT_A2B10G10R10, 110 FORMAT_A2B10G10R10UI, 111 FORMAT_A16B16G16R16, 112 FORMAT_X16B16G16R16I, 113 FORMAT_X16B16G16R16UI, 114 FORMAT_A16B16G16R16I, 115 FORMAT_A16B16G16R16UI, 116 FORMAT_X32B32G32R32I, 117 FORMAT_X32B32G32R32UI, 118 FORMAT_A32B32G32R32I, 119 FORMAT_A32B32G32R32UI, 120 // Paletted formats 121 FORMAT_P8, 122 FORMAT_A8P8, 123 // Compressed formats 124 FORMAT_DXT1, 125 FORMAT_DXT3, 126 FORMAT_DXT5, 127 FORMAT_ATI1, 128 FORMAT_ATI2, 129 FORMAT_ETC1, 130 FORMAT_R11_EAC, 131 FORMAT_SIGNED_R11_EAC, 132 FORMAT_RG11_EAC, 133 FORMAT_SIGNED_RG11_EAC, 134 FORMAT_RGB8_ETC2, 135 FORMAT_SRGB8_ETC2, 136 FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 137 FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 138 FORMAT_RGBA8_ETC2_EAC, 139 FORMAT_SRGB8_ALPHA8_ETC2_EAC, 140 FORMAT_RGBA_ASTC_4x4_KHR, 141 FORMAT_RGBA_ASTC_5x4_KHR, 142 FORMAT_RGBA_ASTC_5x5_KHR, 143 FORMAT_RGBA_ASTC_6x5_KHR, 144 FORMAT_RGBA_ASTC_6x6_KHR, 145 FORMAT_RGBA_ASTC_8x5_KHR, 146 FORMAT_RGBA_ASTC_8x6_KHR, 147 FORMAT_RGBA_ASTC_8x8_KHR, 148 FORMAT_RGBA_ASTC_10x5_KHR, 149 FORMAT_RGBA_ASTC_10x6_KHR, 150 FORMAT_RGBA_ASTC_10x8_KHR, 151 FORMAT_RGBA_ASTC_10x10_KHR, 152 FORMAT_RGBA_ASTC_12x10_KHR, 153 FORMAT_RGBA_ASTC_12x12_KHR, 154 FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR, 155 FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR, 156 FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR, 157 FORMAT_SRGB8_ALPHA8_ASTC_6x5_KHR, 158 FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR, 159 FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR, 160 FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR, 161 FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR, 162 FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR, 163 FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR, 164 FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR, 165 FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR, 166 FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR, 167 FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR, 168 // Floating-point formats 169 FORMAT_A16F, 170 FORMAT_R16F, 171 FORMAT_G16R16F, 172 FORMAT_B16G16R16F, 173 FORMAT_X16B16G16R16F, 174 FORMAT_A16B16G16R16F, 175 FORMAT_X16B16G16R16F_UNSIGNED, 176 FORMAT_A32F, 177 FORMAT_R32F, 178 FORMAT_G32R32F, 179 FORMAT_B32G32R32F, 180 FORMAT_X32B32G32R32F, 181 FORMAT_A32B32G32R32F, 182 FORMAT_X32B32G32R32F_UNSIGNED, 183 // Bump map formats 184 FORMAT_V8U8, 185 FORMAT_L6V5U5, 186 FORMAT_Q8W8V8U8, 187 FORMAT_X8L8V8U8, 188 FORMAT_A2W10V10U10, 189 FORMAT_V16U16, 190 FORMAT_A16W16V16U16, 191 FORMAT_Q16W16V16U16, 192 // Luminance formats 193 FORMAT_L8, 194 FORMAT_A4L4, 195 FORMAT_L16, 196 FORMAT_A8L8, 197 FORMAT_L16F, 198 FORMAT_A16L16F, 199 FORMAT_L32F, 200 FORMAT_A32L32F, 201 // Depth/stencil formats 202 FORMAT_D16, 203 FORMAT_D32, 204 FORMAT_D24X8, 205 FORMAT_D24S8, 206 FORMAT_D24FS8, 207 FORMAT_D32F, // Quad layout 208 FORMAT_D32FS8, // Quad layout 209 FORMAT_D32F_COMPLEMENTARY, // Quad layout, 1 - z 210 FORMAT_D32FS8_COMPLEMENTARY, // Quad layout, 1 - z 211 FORMAT_D32F_LOCKABLE, // Linear layout 212 FORMAT_D32FS8_TEXTURE, // Linear layout, no PCF 213 FORMAT_D32F_SHADOW, // Linear layout, PCF 214 FORMAT_D32FS8_SHADOW, // Linear layout, PCF 215 FORMAT_DF24S8, 216 FORMAT_DF16S8, 217 FORMAT_INTZ, 218 FORMAT_S8, 219 // Quad layout framebuffer 220 FORMAT_X8G8R8B8Q, 221 FORMAT_A8G8R8B8Q, 222 // YUV formats 223 FORMAT_YV12_BT601, 224 FORMAT_YV12_BT709, 225 FORMAT_YV12_JFIF, // Full-swing BT.601 226 227 FORMAT_LAST = FORMAT_YV12_JFIF 228 }; 229 230 enum Lock 231 { 232 LOCK_UNLOCKED, 233 LOCK_READONLY, 234 LOCK_WRITEONLY, 235 LOCK_READWRITE, 236 LOCK_DISCARD, 237 LOCK_UPDATE // Write access which doesn't dirty the buffer, because it's being updated with the sibling's data. 238 }; 239 240 class [[clang::lto_visibility_public]] Surface 241 { 242 private: 243 struct Buffer 244 { 245 friend Surface; 246 247 private: 248 void write(int x, int y, int z, const Color<float> &color); 249 void write(int x, int y, const Color<float> &color); 250 void write(void *element, const Color<float> &color); 251 Color<float> read(int x, int y, int z) const; 252 Color<float> read(int x, int y) const; 253 Color<float> read(void *element) const; 254 Color<float> sample(float x, float y, float z) const; 255 Color<float> sample(float x, float y, int layer) const; 256 257 void *lockRect(int x, int y, int z, Lock lock); 258 void unlockRect(); 259 260 void *buffer; 261 int width; 262 int height; 263 int depth; 264 short border; 265 short samples; 266 267 int bytes; 268 int pitchB; 269 int pitchP; 270 int sliceB; 271 int sliceP; 272 273 Format format; 274 AtomicInt lock; 275 276 bool dirty; // Sibling internal/external buffer doesn't match. 277 }; 278 279 protected: 280 Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice); 281 Surface(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0); 282 283 public: 284 static Surface *create(int width, int height, int depth, Format format, void *pixels, int pitch, int slice); 285 static Surface *create(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0); 286 287 virtual ~Surface() = 0; 288 289 inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false); 290 inline void unlock(bool internal = false); 291 inline int getWidth() const; 292 inline int getHeight() const; 293 inline int getDepth() const; 294 inline int getBorder() const; 295 inline Format getFormat(bool internal = false) const; 296 inline int getPitchB(bool internal = false) const; 297 inline int getPitchP(bool internal = false) const; 298 inline int getSliceB(bool internal = false) const; 299 inline int getSliceP(bool internal = false) const; 300 301 void *lockExternal(int x, int y, int z, Lock lock, Accessor client); 302 void unlockExternal(); 303 inline Format getExternalFormat() const; 304 inline int getExternalPitchB() const; 305 inline int getExternalPitchP() const; 306 inline int getExternalSliceB() const; 307 inline int getExternalSliceP() const; 308 309 virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client) = 0; 310 virtual void unlockInternal() = 0; 311 inline Format getInternalFormat() const; 312 inline int getInternalPitchB() const; 313 inline int getInternalPitchP() const; 314 inline int getInternalSliceB() const; 315 inline int getInternalSliceP() const; 316 317 void *lockStencil(int x, int y, int front, Accessor client); 318 void unlockStencil(); 319 inline Format getStencilFormat() const; 320 inline int getStencilPitchB() const; 321 inline int getStencilSliceB() const; 322 323 void sync(); // Wait for lock(s) to be released. 324 inline bool isUnlocked() const; // Only reliable after sync(). 325 326 inline int getSamples() const; 327 inline int getMultiSampleCount() const; 328 inline int getSuperSampleCount() const; 329 330 bool isEntire(const Rect& rect) const; 331 Rect getRect() const; 332 void clearDepth(float depth, int x0, int y0, int width, int height); 333 void clearStencil(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height); 334 void fill(const Color<float> &color, int x0, int y0, int width, int height); 335 336 Color<float> readExternal(int x, int y, int z) const; 337 Color<float> readExternal(int x, int y) const; 338 Color<float> sampleExternal(float x, float y, float z) const; 339 Color<float> sampleExternal(float x, float y) const; 340 void writeExternal(int x, int y, int z, const Color<float> &color); 341 void writeExternal(int x, int y, const Color<float> &color); 342 343 void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter); 344 void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter); 345 346 enum Edge { TOP, BOTTOM, RIGHT, LEFT }; 347 void copyCubeEdge(Edge dstEdge, Surface *src, Edge srcEdge); 348 void computeCubeCorner(int x0, int y0, int x1, int y1); 349 350 bool hasStencil() const; 351 bool hasDepth() const; 352 bool hasPalette() const; 353 bool isRenderTarget() const; 354 355 bool hasDirtyContents() const; 356 void markContentsClean(); 357 inline bool isExternalDirty() const; 358 Resource *getResource(); 359 360 static int bytes(Format format); 361 static int pitchB(int width, int border, Format format, bool target); 362 static int pitchP(int width, int border, Format format, bool target); 363 static int sliceB(int width, int height, int border, Format format, bool target); 364 static int sliceP(int width, int height, int border, Format format, bool target); 365 static unsigned int size(int width, int height, int depth, int border, int samples, Format format); // FIXME: slice * depth 366 367 static bool isStencil(Format format); 368 static bool isDepth(Format format); 369 static bool hasQuadLayout(Format format); 370 static bool isPalette(Format format); 371 372 static bool isFloatFormat(Format format); 373 static bool isUnsignedComponent(Format format, int component); 374 static bool isSRGBreadable(Format format); 375 static bool isSRGBwritable(Format format); 376 static bool isSRGBformat(Format format); 377 static bool isCompressed(Format format); 378 static bool isSignedNonNormalizedInteger(Format format); 379 static bool isUnsignedNonNormalizedInteger(Format format); 380 static bool isNonNormalizedInteger(Format format); 381 static bool isNormalizedInteger(Format format); 382 static int componentCount(Format format); 383 384 static void setTexturePalette(unsigned int *palette); 385 386 private: 387 sw::Resource *resource; 388 389 typedef unsigned char byte; 390 typedef unsigned short word; 391 typedef unsigned int dword; 392 typedef uint64_t qword; 393 394 struct DXT1 395 { 396 word c0; 397 word c1; 398 dword lut; 399 }; 400 401 struct DXT3 402 { 403 qword a; 404 405 word c0; 406 word c1; 407 dword lut; 408 }; 409 410 struct DXT5 411 { 412 union 413 { 414 struct 415 { 416 byte a0; 417 byte a1; 418 }; 419 420 qword alut; // Skip first 16 bit 421 }; 422 423 word c0; 424 word c1; 425 dword clut; 426 }; 427 428 struct ATI2 429 { 430 union 431 { 432 struct 433 { 434 byte y0; 435 byte y1; 436 }; 437 438 qword ylut; // Skip first 16 bit 439 }; 440 441 union 442 { 443 struct 444 { 445 byte x0; 446 byte x1; 447 }; 448 449 qword xlut; // Skip first 16 bit 450 }; 451 }; 452 453 struct ATI1 454 { 455 union 456 { 457 struct 458 { 459 byte r0; 460 byte r1; 461 }; 462 463 qword rlut; // Skip first 16 bit 464 }; 465 }; 466 467 static void decodeR8G8B8(Buffer &destination, Buffer &source); 468 static void decodeX1R5G5B5(Buffer &destination, Buffer &source); 469 static void decodeA1R5G5B5(Buffer &destination, Buffer &source); 470 static void decodeX4R4G4B4(Buffer &destination, Buffer &source); 471 static void decodeA4R4G4B4(Buffer &destination, Buffer &source); 472 static void decodeP8(Buffer &destination, Buffer &source); 473 474 static void decodeDXT1(Buffer &internal, Buffer &external); 475 static void decodeDXT3(Buffer &internal, Buffer &external); 476 static void decodeDXT5(Buffer &internal, Buffer &external); 477 static void decodeATI1(Buffer &internal, Buffer &external); 478 static void decodeATI2(Buffer &internal, Buffer &external); 479 static void decodeEAC(Buffer &internal, Buffer &external, int nbChannels, bool isSigned); 480 static void decodeETC2(Buffer &internal, Buffer &external, int nbAlphaBits, bool isSRGB); 481 static void decodeASTC(Buffer &internal, Buffer &external, int xSize, int ySize, int zSize, bool isSRGB); 482 483 static void update(Buffer &destination, Buffer &source); 484 static void genericUpdate(Buffer &destination, Buffer &source); 485 static void *allocateBuffer(int width, int height, int depth, int border, int samples, Format format); 486 static void memfill4(void *buffer, int pattern, int bytes); 487 488 bool identicalFormats() const; 489 Format selectInternalFormat(Format format) const; 490 491 void resolve(); 492 493 Buffer external; 494 Buffer internal; 495 Buffer stencil; 496 497 const bool lockable; 498 const bool renderTarget; 499 500 bool dirtyContents; // Sibling surfaces need updating (mipmaps / cube borders). 501 unsigned int paletteUsed; 502 503 static unsigned int *palette; // FIXME: Not multi-device safe 504 static unsigned int paletteID; 505 506 bool hasParent; 507 bool ownExternal; 508 }; 509 } 510 511 #undef min 512 #undef max 513 514 namespace sw 515 { lock(int x,int y,int z,Lock lock,Accessor client,bool internal)516 void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal) 517 { 518 return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client); 519 } 520 unlock(bool internal)521 void Surface::unlock(bool internal) 522 { 523 return internal ? unlockInternal() : unlockExternal(); 524 } 525 getWidth() const526 int Surface::getWidth() const 527 { 528 return external.width; 529 } 530 getHeight() const531 int Surface::getHeight() const 532 { 533 return external.height; 534 } 535 getDepth() const536 int Surface::getDepth() const 537 { 538 return external.depth; 539 } 540 getBorder() const541 int Surface::getBorder() const 542 { 543 return internal.border; 544 } 545 getFormat(bool internal) const546 Format Surface::getFormat(bool internal) const 547 { 548 return internal ? getInternalFormat() : getExternalFormat(); 549 } 550 getPitchB(bool internal) const551 int Surface::getPitchB(bool internal) const 552 { 553 return internal ? getInternalPitchB() : getExternalPitchB(); 554 } 555 getPitchP(bool internal) const556 int Surface::getPitchP(bool internal) const 557 { 558 return internal ? getInternalPitchP() : getExternalPitchP(); 559 } 560 getSliceB(bool internal) const561 int Surface::getSliceB(bool internal) const 562 { 563 return internal ? getInternalSliceB() : getExternalSliceB(); 564 } 565 getSliceP(bool internal) const566 int Surface::getSliceP(bool internal) const 567 { 568 return internal ? getInternalSliceP() : getExternalSliceP(); 569 } 570 getExternalFormat() const571 Format Surface::getExternalFormat() const 572 { 573 return external.format; 574 } 575 getExternalPitchB() const576 int Surface::getExternalPitchB() const 577 { 578 return external.pitchB; 579 } 580 getExternalPitchP() const581 int Surface::getExternalPitchP() const 582 { 583 return external.pitchP; 584 } 585 getExternalSliceB() const586 int Surface::getExternalSliceB() const 587 { 588 return external.sliceB; 589 } 590 getExternalSliceP() const591 int Surface::getExternalSliceP() const 592 { 593 return external.sliceP; 594 } 595 getInternalFormat() const596 Format Surface::getInternalFormat() const 597 { 598 return internal.format; 599 } 600 getInternalPitchB() const601 int Surface::getInternalPitchB() const 602 { 603 return internal.pitchB; 604 } 605 getInternalPitchP() const606 int Surface::getInternalPitchP() const 607 { 608 return internal.pitchP; 609 } 610 getInternalSliceB() const611 int Surface::getInternalSliceB() const 612 { 613 return internal.sliceB; 614 } 615 getInternalSliceP() const616 int Surface::getInternalSliceP() const 617 { 618 return internal.sliceP; 619 } 620 getStencilFormat() const621 Format Surface::getStencilFormat() const 622 { 623 return stencil.format; 624 } 625 getStencilPitchB() const626 int Surface::getStencilPitchB() const 627 { 628 return stencil.pitchB; 629 } 630 getStencilSliceB() const631 int Surface::getStencilSliceB() const 632 { 633 return stencil.sliceB; 634 } 635 getSamples() const636 int Surface::getSamples() const 637 { 638 return internal.samples; 639 } 640 getMultiSampleCount() const641 int Surface::getMultiSampleCount() const 642 { 643 return sw::min((int)internal.samples, 4); 644 } 645 getSuperSampleCount() const646 int Surface::getSuperSampleCount() const 647 { 648 return internal.samples > 4 ? internal.samples / 4 : 1; 649 } 650 isUnlocked() const651 bool Surface::isUnlocked() const 652 { 653 return external.lock == LOCK_UNLOCKED && 654 internal.lock == LOCK_UNLOCKED && 655 stencil.lock == LOCK_UNLOCKED; 656 } 657 isExternalDirty() const658 bool Surface::isExternalDirty() const 659 { 660 return external.buffer && external.buffer != internal.buffer && external.dirty; 661 } 662 } 663 664 #endif // sw_Surface_hpp 665