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 { 28 Rect() {} 29 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 33 int width() const { return x1 - x0; } 34 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 { 44 SliceRect() : slice(0) {} 45 SliceRect(const Rect& rect) : Rect(rect), slice(0) {} 46 SliceRect(const Rect& rect, int s) : Rect(rect), slice(s) {} 47 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 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 public: 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 virtual ~Surface(); 258 259 inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false); 260 inline void unlock(bool internal = false); 261 inline int getWidth() const; 262 inline int getHeight() const; 263 inline int getDepth() const; 264 inline Format getFormat(bool internal = false) const; 265 inline int getPitchB(bool internal = false) const; 266 inline int getPitchP(bool internal = false) const; 267 inline int getSliceB(bool internal = false) const; 268 inline int getSliceP(bool internal = false) const; 269 270 void *lockExternal(int x, int y, int z, Lock lock, Accessor client); 271 void unlockExternal(); 272 inline Format getExternalFormat() const; 273 inline int getExternalPitchB() const; 274 inline int getExternalPitchP() const; 275 inline int getExternalSliceB() const; 276 inline int getExternalSliceP() const; 277 278 virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client); 279 virtual void unlockInternal(); 280 inline Format getInternalFormat() const; 281 inline int getInternalPitchB() const; 282 inline int getInternalPitchP() const; 283 inline int getInternalSliceB() const; 284 inline int getInternalSliceP() const; 285 286 void *lockStencil(int front, Accessor client); 287 void unlockStencil(); 288 inline int getStencilPitchB() const; 289 inline int getStencilSliceB() const; 290 291 inline int getMultiSampleCount() const; 292 inline int getSuperSampleCount() const; 293 294 bool isEntire(const SliceRect& rect) const; 295 SliceRect getRect() const; 296 void clearDepth(float depth, int x0, int y0, int width, int height); 297 void clearStencil(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height); 298 void fill(const Color<float> &color, int x0, int y0, int width, int height); 299 300 Color<float> readExternal(int x, int y, int z) const; 301 Color<float> readExternal(int x, int y) const; 302 Color<float> sampleExternal(float x, float y, float z) const; 303 Color<float> sampleExternal(float x, float y) const; 304 void writeExternal(int x, int y, int z, const Color<float> &color); 305 void writeExternal(int x, int y, const Color<float> &color); 306 307 void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter); 308 void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter); 309 310 bool hasStencil() const; 311 bool hasDepth() const; 312 bool hasPalette() const; 313 bool isRenderTarget() const; 314 315 bool hasDirtyMipmaps() const; 316 void cleanMipmaps(); 317 inline bool isExternalDirty() const; 318 Resource *getResource(); 319 320 static int bytes(Format format); 321 static int pitchB(int width, Format format, bool target); 322 static int pitchP(int width, Format format, bool target); 323 static int sliceB(int width, int height, Format format, bool target); 324 static int sliceP(int width, int height, Format format, bool target); 325 static unsigned int size(int width, int height, int depth, Format format); // FIXME: slice * depth 326 327 static bool isStencil(Format format); 328 static bool isDepth(Format format); 329 static bool isPalette(Format format); 330 331 static bool isFloatFormat(Format format); 332 static bool isUnsignedComponent(Format format, int component); 333 static bool isSRGBreadable(Format format); 334 static bool isSRGBwritable(Format format); 335 static bool isCompressed(Format format); 336 static bool isNonNormalizedInteger(Format format); 337 static int componentCount(Format format); 338 339 static void setTexturePalette(unsigned int *palette); 340 341 protected: 342 sw::Resource *resource; 343 344 private: 345 typedef unsigned char byte; 346 typedef unsigned short word; 347 typedef unsigned int dword; 348 typedef uint64_t qword; 349 350 #if S3TC_SUPPORT 351 struct DXT1 352 { 353 word c0; 354 word c1; 355 dword lut; 356 }; 357 358 struct DXT3 359 { 360 qword a; 361 362 word c0; 363 word c1; 364 dword lut; 365 }; 366 367 struct DXT5 368 { 369 union 370 { 371 struct 372 { 373 byte a0; 374 byte a1; 375 }; 376 377 qword alut; // Skip first 16 bit 378 }; 379 380 word c0; 381 word c1; 382 dword clut; 383 }; 384 #endif 385 386 struct ATI2 387 { 388 union 389 { 390 struct 391 { 392 byte y0; 393 byte y1; 394 }; 395 396 qword ylut; // Skip first 16 bit 397 }; 398 399 union 400 { 401 struct 402 { 403 byte x0; 404 byte x1; 405 }; 406 407 qword xlut; // Skip first 16 bit 408 }; 409 }; 410 411 struct ATI1 412 { 413 union 414 { 415 struct 416 { 417 byte r0; 418 byte r1; 419 }; 420 421 qword rlut; // Skip first 16 bit 422 }; 423 }; 424 425 static void decodeR8G8B8(Buffer &destination, const Buffer &source); 426 static void decodeX1R5G5B5(Buffer &destination, const Buffer &source); 427 static void decodeA1R5G5B5(Buffer &destination, const Buffer &source); 428 static void decodeX4R4G4B4(Buffer &destination, const Buffer &source); 429 static void decodeA4R4G4B4(Buffer &destination, const Buffer &source); 430 static void decodeP8(Buffer &destination, const Buffer &source); 431 432 #if S3TC_SUPPORT 433 static void decodeDXT1(Buffer &internal, const Buffer &external); 434 static void decodeDXT3(Buffer &internal, const Buffer &external); 435 static void decodeDXT5(Buffer &internal, const Buffer &external); 436 #endif 437 static void decodeATI1(Buffer &internal, const Buffer &external); 438 static void decodeATI2(Buffer &internal, const Buffer &external); 439 static void decodeEAC(Buffer &internal, const Buffer &external, int nbChannels, bool isSigned); 440 static void decodeETC2(Buffer &internal, const Buffer &external, int nbAlphaBits, bool isSRGB); 441 static void decodeASTC(Buffer &internal, const Buffer &external, int xSize, int ySize, int zSize, bool isSRGB); 442 443 static void update(Buffer &destination, Buffer &source); 444 static void genericUpdate(Buffer &destination, Buffer &source); 445 static void *allocateBuffer(int width, int height, int depth, Format format); 446 static void memfill4(void *buffer, int pattern, int bytes); 447 448 bool identicalFormats() const; 449 Format selectInternalFormat(Format format) const; 450 451 void resolve(); 452 453 Buffer external; 454 Buffer internal; 455 Buffer stencil; 456 457 const bool lockable; 458 const bool renderTarget; 459 460 bool dirtyMipmaps; 461 unsigned int paletteUsed; 462 463 static unsigned int *palette; // FIXME: Not multi-device safe 464 static unsigned int paletteID; 465 466 bool hasParent; 467 bool ownExternal; 468 }; 469 } 470 471 #undef min 472 #undef max 473 474 namespace sw 475 { 476 void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal) 477 { 478 return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client); 479 } 480 481 void Surface::unlock(bool internal) 482 { 483 return internal ? unlockInternal() : unlockExternal(); 484 } 485 486 int Surface::getWidth() const 487 { 488 return external.width; 489 } 490 491 int Surface::getHeight() const 492 { 493 return external.height; 494 } 495 496 int Surface::getDepth() const 497 { 498 return external.depth; 499 } 500 501 Format Surface::getFormat(bool internal) const 502 { 503 return internal ? getInternalFormat() : getExternalFormat(); 504 } 505 506 int Surface::getPitchB(bool internal) const 507 { 508 return internal ? getInternalPitchB() : getExternalPitchB(); 509 } 510 511 int Surface::getPitchP(bool internal) const 512 { 513 return internal ? getInternalPitchP() : getExternalPitchB(); 514 } 515 516 int Surface::getSliceB(bool internal) const 517 { 518 return internal ? getInternalSliceB() : getExternalSliceB(); 519 } 520 521 int Surface::getSliceP(bool internal) const 522 { 523 return internal ? getInternalSliceP() : getExternalSliceB(); 524 } 525 526 Format Surface::getExternalFormat() const 527 { 528 return external.format; 529 } 530 531 int Surface::getExternalPitchB() const 532 { 533 return external.pitchB; 534 } 535 536 int Surface::getExternalPitchP() const 537 { 538 return external.pitchP; 539 } 540 541 int Surface::getExternalSliceB() const 542 { 543 return external.sliceB; 544 } 545 546 int Surface::getExternalSliceP() const 547 { 548 return external.sliceP; 549 } 550 551 Format Surface::getInternalFormat() const 552 { 553 return internal.format; 554 } 555 556 int Surface::getInternalPitchB() const 557 { 558 return internal.pitchB; 559 } 560 561 int Surface::getInternalPitchP() const 562 { 563 return internal.pitchP; 564 } 565 566 int Surface::getInternalSliceB() const 567 { 568 return internal.sliceB; 569 } 570 571 int Surface::getInternalSliceP() const 572 { 573 return internal.sliceP; 574 } 575 576 int Surface::getStencilPitchB() const 577 { 578 return stencil.pitchB; 579 } 580 581 int Surface::getStencilSliceB() const 582 { 583 return stencil.sliceB; 584 } 585 586 int Surface::getMultiSampleCount() const 587 { 588 return sw::min(internal.depth, 4); 589 } 590 591 int Surface::getSuperSampleCount() const 592 { 593 return internal.depth > 4 ? internal.depth / 4 : 1; 594 } 595 596 bool Surface::isExternalDirty() const 597 { 598 return external.buffer && external.buffer != internal.buffer && external.dirty; 599 } 600 } 601 602 #endif // sw_Surface_hpp 603