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