Surface.hpp revision 8059442dded9441b54cc764e0ccc3a0c83120fc3
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_R8, 51 FORMAT_R3G3B2, 52 FORMAT_A8R3G3B2, 53 FORMAT_X4R4G4B4, 54 FORMAT_A4R4G4B4, 55 FORMAT_R4G4B4A4, 56 FORMAT_R5G6B5, 57 FORMAT_R8G8B8, 58 FORMAT_B8G8R8, 59 FORMAT_X8R8G8B8, 60 FORMAT_A8R8G8B8, 61 FORMAT_X8B8G8R8, 62 FORMAT_A8B8G8R8, 63 FORMAT_X1R5G5B5, 64 FORMAT_A1R5G5B5, 65 FORMAT_R5G5B5A1, 66 FORMAT_G8R8, 67 FORMAT_G16R16, 68 FORMAT_A2R10G10B10, 69 FORMAT_A2B10G10R10, 70 FORMAT_A16B16G16R16, 71 // Paletted formats 72 FORMAT_P8, 73 FORMAT_A8P8, 74 // Compressed formats 75 FORMAT_DXT1, 76 FORMAT_DXT3, 77 FORMAT_DXT5, 78 FORMAT_ATI1, 79 FORMAT_ATI2, 80 FORMAT_ETC1, 81 // Floating-point formats 82 FORMAT_A16F, 83 FORMAT_R16F, 84 FORMAT_G16R16F, 85 FORMAT_B16G16R16F, 86 FORMAT_A16B16G16R16F, 87 FORMAT_A32F, 88 FORMAT_R32F, 89 FORMAT_G32R32F, 90 FORMAT_B32G32R32F, 91 FORMAT_A32B32G32R32F, 92 // Bump map formats 93 FORMAT_V8U8, 94 FORMAT_L6V5U5, 95 FORMAT_Q8W8V8U8, 96 FORMAT_X8L8V8U8, 97 FORMAT_A2W10V10U10, 98 FORMAT_V16U16, 99 FORMAT_A16W16V16U16, 100 FORMAT_Q16W16V16U16, 101 // Luminance formats 102 FORMAT_L8, 103 FORMAT_A4L4, 104 FORMAT_L16, 105 FORMAT_A8L8, 106 FORMAT_L16F, 107 FORMAT_A16L16F, 108 FORMAT_L32F, 109 FORMAT_A32L32F, 110 // Depth/stencil formats 111 FORMAT_D16, 112 FORMAT_D32, 113 FORMAT_D24X8, 114 FORMAT_D24S8, 115 FORMAT_D24FS8, 116 FORMAT_D32F, // Quad layout 117 FORMAT_D32F_COMPLEMENTARY, // Quad layout, 1 - z 118 FORMAT_D32F_LOCKABLE, // Linear layout 119 FORMAT_D32FS8_TEXTURE, // Linear layout, no PCF 120 FORMAT_D32FS8_SHADOW, // Linear layout, PCF 121 FORMAT_DF24S8, 122 FORMAT_DF16S8, 123 FORMAT_INTZ, 124 FORMAT_S8, 125 // Quad layout framebuffer 126 FORMAT_X8G8R8B8Q, 127 FORMAT_A8G8R8B8Q, 128 129 FORMAT_LAST = FORMAT_A8G8R8B8Q 130 }; 131 132 enum Lock 133 { 134 LOCK_UNLOCKED, 135 LOCK_READONLY, 136 LOCK_WRITEONLY, 137 LOCK_READWRITE, 138 LOCK_DISCARD 139 }; 140 141 class Surface 142 { 143 private: 144 struct Buffer 145 { 146 public: 147 void write(int x, int y, int z, const Color<float> &color); 148 void write(int x, int y, const Color<float> &color); 149 void write(void *element, const Color<float> &color); 150 Color<float> read(int x, int y, int z) const; 151 Color<float> read(int x, int y) const; 152 Color<float> read(void *element) const; 153 Color<float> sample(float x, float y, float z) const; 154 Color<float> sample(float x, float y) const; 155 156 void *lockRect(int x, int y, int z, Lock lock); 157 void unlockRect(); 158 159 void *buffer; 160 int width; 161 int height; 162 int depth; 163 int bytes; 164 int pitchB; 165 int pitchP; 166 int sliceB; 167 int sliceP; 168 Format format; 169 Lock lock; 170 171 bool dirty; 172 }; 173 174 public: 175 Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget); 176 177 virtual ~Surface(); 178 179 inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false); 180 inline void unlock(bool internal = false); 181 inline int getWidth() const; 182 inline int getHeight() const; 183 inline int getDepth() const; 184 inline Format getFormat(bool internal = false) const; 185 inline int getPitchB(bool internal = false) const; 186 inline int getPitchP(bool internal = false) const; 187 inline int getSliceB(bool internal = false) const; 188 inline int getSliceP(bool internal = false) const; 189 190 void *lockExternal(int x, int y, int z, Lock lock, Accessor client); 191 void unlockExternal(); 192 inline Format getExternalFormat() const; 193 inline int getExternalPitchB() const; 194 inline int getExternalPitchP() const; 195 inline int getExternalSliceB() const; 196 inline int getExternalSliceP() const; 197 198 virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client); 199 virtual void unlockInternal(); 200 inline Format getInternalFormat() const; 201 inline int getInternalPitchB() const; 202 inline int getInternalPitchP() const; 203 inline int getInternalSliceB() const; 204 inline int getInternalSliceP() const; 205 206 void *lockStencil(int front, Accessor client); 207 void unlockStencil(); 208 inline int getStencilPitchB() const; 209 inline int getStencilPitchP() const; 210 inline int getStencilSliceB() const; 211 212 inline int getMultiSampleCount() const; 213 inline int getSuperSampleCount() const; 214 215 void clearColorBuffer(unsigned int colorARGB, unsigned int rgbaMask, int x0, int y0, int width, int height); 216 void clearDepthBuffer(float depth, int x0, int y0, int width, int height); 217 void clearStencilBuffer(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height); 218 void fill(const Color<float> &color, int x0, int y0, int width, int height); 219 220 Color<float> readExternal(int x, int y, int z) const; 221 Color<float> readExternal(int x, int y) const; 222 Color<float> sampleExternal(float x, float y, float z) const; 223 Color<float> sampleExternal(float x, float y) const; 224 void writeExternal(int x, int y, int z, const Color<float> &color); 225 void writeExternal(int x, int y, const Color<float> &color); 226 227 Color<float> readInternal(int x, int y, int z) const; 228 Color<float> readInternal(int x, int y) const; 229 Color<float> sampleInternal(float x, float y, float z) const; 230 Color<float> sampleInternal(float x, float y) const; 231 void writeInternal(int x, int y, int z, const Color<float> &color); 232 void writeInternal(int x, int y, const Color<float> &color); 233 234 bool hasStencil() const; 235 bool hasDepth() const; 236 bool hasPalette() const; 237 bool isRenderTarget() const; 238 239 bool hasDirtyMipmaps() const; 240 void cleanMipmaps(); 241 inline bool isExternalDirty() const; 242 Resource *getResource(); 243 244 static int bytes(Format format); 245 static int pitchB(int width, Format format, bool target); 246 static int pitchP(int width, Format format, bool target); 247 static int sliceB(int width, int height, Format format, bool target); 248 static int sliceP(int width, int height, Format format, bool target); 249 static unsigned int size(int width, int height, int depth, Format format); // FIXME: slice * depth 250 251 static bool isStencil(Format format); 252 static bool isDepth(Format format); 253 static bool isPalette(Format format); 254 255 static bool isFloatFormat(Format format); 256 static bool isUnsignedComponent(Format format, int component); 257 static bool isSRGBreadable(Format format); 258 static bool isSRGBwritable(Format format); 259 static bool isCompressed(Format format); 260 static int componentCount(Format format); 261 262 static void setTexturePalette(unsigned int *palette); 263 264 protected: 265 sw::Resource *resource; 266 267 private: 268 typedef unsigned char byte; 269 typedef unsigned short word; 270 typedef unsigned int dword; 271 typedef uint64_t qword; 272 273 #if S3TC_SUPPORT 274 struct DXT1 275 { 276 word c0; 277 word c1; 278 dword lut; 279 }; 280 281 struct DXT3 282 { 283 qword a; 284 285 word c0; 286 word c1; 287 dword lut; 288 }; 289 290 struct DXT5 291 { 292 union 293 { 294 struct 295 { 296 byte a0; 297 byte a1; 298 }; 299 300 qword alut; // Skip first 16 bit 301 }; 302 303 word c0; 304 word c1; 305 dword clut; 306 }; 307 #endif 308 309 struct ATI2 310 { 311 union 312 { 313 struct 314 { 315 byte y0; 316 byte y1; 317 }; 318 319 qword ylut; // Skip first 16 bit 320 }; 321 322 union 323 { 324 struct 325 { 326 byte x0; 327 byte x1; 328 }; 329 330 qword xlut; // Skip first 16 bit 331 }; 332 }; 333 334 struct ATI1 335 { 336 union 337 { 338 struct 339 { 340 byte r0; 341 byte r1; 342 }; 343 344 qword rlut; // Skip first 16 bit 345 }; 346 }; 347 348 static void decodeR8G8B8(Buffer &destination, const Buffer &source); 349 static void decodeR5G6B5(Buffer &destination, const Buffer &source); 350 static void decodeX1R5G5B5(Buffer &destination, const Buffer &source); 351 static void decodeA1R5G5B5(Buffer &destination, const Buffer &source); 352 static void decodeX4R4G4B4(Buffer &destination, const Buffer &source); 353 static void decodeA4R4G4B4(Buffer &destination, const Buffer &source); 354 static void decodeP8(Buffer &destination, const Buffer &source); 355 356 #if S3TC_SUPPORT 357 static void decodeDXT1(Buffer &internal, const Buffer &external); 358 static void decodeDXT3(Buffer &internal, const Buffer &external); 359 static void decodeDXT5(Buffer &internal, const Buffer &external); 360 #endif 361 static void decodeATI1(Buffer &internal, const Buffer &external); 362 static void decodeATI2(Buffer &internal, const Buffer &external); 363 static void decodeETC1(Buffer &internal, const Buffer &external); 364 365 static void update(Buffer &destination, Buffer &source); 366 static void genericUpdate(Buffer &destination, Buffer &source); 367 static void *allocateBuffer(int width, int height, int depth, Format format); 368 static void memfill4(void *buffer, int pattern, int bytes); 369 370 bool identicalFormats() const; 371 Format selectInternalFormat(Format format) const; 372 373 void resolve(); 374 375 Buffer external; 376 Buffer internal; 377 Buffer stencil; 378 379 const bool lockable; 380 const bool renderTarget; 381 382 bool dirtyMipmaps; 383 unsigned int paletteUsed; 384 385 static unsigned int *palette; // FIXME: Not multi-device safe 386 static unsigned int paletteID; 387 388 bool hasParent; 389 }; 390} 391 392#undef min 393#undef max 394 395namespace sw 396{ 397 void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal) 398 { 399 return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client); 400 } 401 402 void Surface::unlock(bool internal) 403 { 404 return internal ? unlockInternal() : unlockExternal(); 405 } 406 407 int Surface::getWidth() const 408 { 409 return external.width; 410 } 411 412 int Surface::getHeight() const 413 { 414 return external.height; 415 } 416 417 int Surface::getDepth() const 418 { 419 return external.depth; 420 } 421 422 Format Surface::getFormat(bool internal) const 423 { 424 return internal ? getInternalFormat() : getExternalFormat(); 425 } 426 427 int Surface::getPitchB(bool internal) const 428 { 429 return internal ? getInternalPitchB() : getExternalPitchB(); 430 } 431 432 int Surface::getPitchP(bool internal) const 433 { 434 return internal ? getInternalPitchP() : getExternalPitchB(); 435 } 436 437 int Surface::getSliceB(bool internal) const 438 { 439 return internal ? getInternalSliceB() : getExternalSliceB(); 440 } 441 442 int Surface::getSliceP(bool internal) const 443 { 444 return internal ? getInternalSliceP() : getExternalSliceB(); 445 } 446 447 Format Surface::getExternalFormat() const 448 { 449 return external.format; 450 } 451 452 int Surface::getExternalPitchB() const 453 { 454 return external.pitchB; 455 } 456 457 int Surface::getExternalPitchP() const 458 { 459 return external.pitchP; 460 } 461 462 int Surface::getExternalSliceB() const 463 { 464 return external.sliceB; 465 } 466 467 int Surface::getExternalSliceP() const 468 { 469 return external.sliceP; 470 } 471 472 Format Surface::getInternalFormat() const 473 { 474 return internal.format; 475 } 476 477 int Surface::getInternalPitchB() const 478 { 479 return internal.pitchB; 480 } 481 482 int Surface::getInternalPitchP() const 483 { 484 return internal.pitchP; 485 } 486 487 int Surface::getInternalSliceB() const 488 { 489 return internal.sliceB; 490 } 491 492 int Surface::getInternalSliceP() const 493 { 494 return internal.sliceP; 495 } 496 497 int Surface::getStencilPitchB() const 498 { 499 return stencil.pitchB; 500 } 501 502 int Surface::getStencilPitchP() const 503 { 504 return stencil.pitchP; 505 } 506 507 int Surface::getStencilSliceB() const 508 { 509 return stencil.sliceB; 510 } 511 512 int Surface::getMultiSampleCount() const 513 { 514 return sw::min(internal.depth, 4); 515 } 516 517 int Surface::getSuperSampleCount() const 518 { 519 return internal.depth > 4 ? internal.depth / 4 : 1; 520 } 521 522 bool Surface::isExternalDirty() const 523 { 524 return external.buffer && external.buffer != internal.buffer && external.dirty; 525 } 526} 527 528#endif // sw_Surface_hpp 529