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