| 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 | { | 
|---|
| 28 | RectT() {} | 
|---|
| 29 | RectT(T x0i, T y0i, T x1i, T y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {} | 
|---|
| 30 |  | 
|---|
| 31 | 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 |  | 
|---|
| 39 | T width() const  { return x1 - x0; } | 
|---|
| 40 | 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 | { | 
|---|
| 53 | SliceRectT() : slice(0) {} | 
|---|
| 54 | SliceRectT(const RectT<T>& rect) : RectT<T>(rect), slice(0) {} | 
|---|
| 55 | SliceRectT(const RectT<T>& rect, int s) : RectT<T>(rect), slice(s) {} | 
|---|
| 56 | 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 | virtual bool requiresSync() const { return false; } | 
|---|
| 325 | inline bool isUnlocked() const;   // Only reliable after sync(). | 
|---|
| 326 |  | 
|---|
| 327 | inline int getSamples() const; | 
|---|
| 328 | inline int getMultiSampleCount() const; | 
|---|
| 329 | inline int getSuperSampleCount() const; | 
|---|
| 330 |  | 
|---|
| 331 | bool isEntire(const Rect& rect) const; | 
|---|
| 332 | Rect getRect() const; | 
|---|
| 333 | void clearDepth(float depth, int x0, int y0, int width, int height); | 
|---|
| 334 | void clearStencil(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height); | 
|---|
| 335 | void fill(const Color<float> &color, int x0, int y0, int width, int height); | 
|---|
| 336 |  | 
|---|
| 337 | Color<float> readExternal(int x, int y, int z) const; | 
|---|
| 338 | Color<float> readExternal(int x, int y) const; | 
|---|
| 339 | Color<float> sampleExternal(float x, float y, float z) const; | 
|---|
| 340 | Color<float> sampleExternal(float x, float y) const; | 
|---|
| 341 | void writeExternal(int x, int y, int z, const Color<float> &color); | 
|---|
| 342 | void writeExternal(int x, int y, const Color<float> &color); | 
|---|
| 343 |  | 
|---|
| 344 | void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter); | 
|---|
| 345 | void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter); | 
|---|
| 346 |  | 
|---|
| 347 | enum Edge { TOP, BOTTOM, RIGHT, LEFT }; | 
|---|
| 348 | void copyCubeEdge(Edge dstEdge, Surface *src, Edge srcEdge); | 
|---|
| 349 | void computeCubeCorner(int x0, int y0, int x1, int y1); | 
|---|
| 350 |  | 
|---|
| 351 | bool hasStencil() const; | 
|---|
| 352 | bool hasDepth() const; | 
|---|
| 353 | bool hasPalette() const; | 
|---|
| 354 | bool isRenderTarget() const; | 
|---|
| 355 |  | 
|---|
| 356 | bool hasDirtyContents() const; | 
|---|
| 357 | void markContentsClean(); | 
|---|
| 358 | inline bool isExternalDirty() const; | 
|---|
| 359 | Resource *getResource(); | 
|---|
| 360 |  | 
|---|
| 361 | static int bytes(Format format); | 
|---|
| 362 | static int pitchB(int width, int border, Format format, bool target); | 
|---|
| 363 | static int pitchP(int width, int border, Format format, bool target); | 
|---|
| 364 | static int sliceB(int width, int height, int border, Format format, bool target); | 
|---|
| 365 | static int sliceP(int width, int height, int border, Format format, bool target); | 
|---|
| 366 | static size_t size(int width, int height, int depth, int border, int samples, Format format); | 
|---|
| 367 |  | 
|---|
| 368 | static bool isStencil(Format format); | 
|---|
| 369 | static bool isDepth(Format format); | 
|---|
| 370 | static bool hasQuadLayout(Format format); | 
|---|
| 371 | static bool isPalette(Format format); | 
|---|
| 372 |  | 
|---|
| 373 | static bool isFloatFormat(Format format); | 
|---|
| 374 | static bool isUnsignedComponent(Format format, int component); | 
|---|
| 375 | static bool isSRGBreadable(Format format); | 
|---|
| 376 | static bool isSRGBwritable(Format format); | 
|---|
| 377 | static bool isSRGBformat(Format format); | 
|---|
| 378 | static bool isCompressed(Format format); | 
|---|
| 379 | static bool isSignedNonNormalizedInteger(Format format); | 
|---|
| 380 | static bool isUnsignedNonNormalizedInteger(Format format); | 
|---|
| 381 | static bool isNonNormalizedInteger(Format format); | 
|---|
| 382 | static bool isNormalizedInteger(Format format); | 
|---|
| 383 | static int componentCount(Format format); | 
|---|
| 384 |  | 
|---|
| 385 | static void setTexturePalette(unsigned int *palette); | 
|---|
| 386 |  | 
|---|
| 387 | private: | 
|---|
| 388 | sw::Resource *resource; | 
|---|
| 389 |  | 
|---|
| 390 | typedef unsigned char byte; | 
|---|
| 391 | typedef unsigned short word; | 
|---|
| 392 | typedef unsigned int dword; | 
|---|
| 393 | typedef uint64_t qword; | 
|---|
| 394 |  | 
|---|
| 395 | struct DXT1 | 
|---|
| 396 | { | 
|---|
| 397 | word c0; | 
|---|
| 398 | word c1; | 
|---|
| 399 | dword lut; | 
|---|
| 400 | }; | 
|---|
| 401 |  | 
|---|
| 402 | struct DXT3 | 
|---|
| 403 | { | 
|---|
| 404 | qword a; | 
|---|
| 405 |  | 
|---|
| 406 | word c0; | 
|---|
| 407 | word c1; | 
|---|
| 408 | dword lut; | 
|---|
| 409 | }; | 
|---|
| 410 |  | 
|---|
| 411 | struct DXT5 | 
|---|
| 412 | { | 
|---|
| 413 | union | 
|---|
| 414 | { | 
|---|
| 415 | struct | 
|---|
| 416 | { | 
|---|
| 417 | byte a0; | 
|---|
| 418 | byte a1; | 
|---|
| 419 | }; | 
|---|
| 420 |  | 
|---|
| 421 | qword alut;   // Skip first 16 bit | 
|---|
| 422 | }; | 
|---|
| 423 |  | 
|---|
| 424 | word c0; | 
|---|
| 425 | word c1; | 
|---|
| 426 | dword clut; | 
|---|
| 427 | }; | 
|---|
| 428 |  | 
|---|
| 429 | struct ATI2 | 
|---|
| 430 | { | 
|---|
| 431 | union | 
|---|
| 432 | { | 
|---|
| 433 | struct | 
|---|
| 434 | { | 
|---|
| 435 | byte y0; | 
|---|
| 436 | byte y1; | 
|---|
| 437 | }; | 
|---|
| 438 |  | 
|---|
| 439 | qword ylut;   // Skip first 16 bit | 
|---|
| 440 | }; | 
|---|
| 441 |  | 
|---|
| 442 | union | 
|---|
| 443 | { | 
|---|
| 444 | struct | 
|---|
| 445 | { | 
|---|
| 446 | byte x0; | 
|---|
| 447 | byte x1; | 
|---|
| 448 | }; | 
|---|
| 449 |  | 
|---|
| 450 | qword xlut;   // Skip first 16 bit | 
|---|
| 451 | }; | 
|---|
| 452 | }; | 
|---|
| 453 |  | 
|---|
| 454 | struct ATI1 | 
|---|
| 455 | { | 
|---|
| 456 | union | 
|---|
| 457 | { | 
|---|
| 458 | struct | 
|---|
| 459 | { | 
|---|
| 460 | byte r0; | 
|---|
| 461 | byte r1; | 
|---|
| 462 | }; | 
|---|
| 463 |  | 
|---|
| 464 | qword rlut;   // Skip first 16 bit | 
|---|
| 465 | }; | 
|---|
| 466 | }; | 
|---|
| 467 |  | 
|---|
| 468 | static void decodeR8G8B8(Buffer &destination, Buffer &source); | 
|---|
| 469 | static void decodeX1R5G5B5(Buffer &destination, Buffer &source); | 
|---|
| 470 | static void decodeA1R5G5B5(Buffer &destination, Buffer &source); | 
|---|
| 471 | static void decodeX4R4G4B4(Buffer &destination, Buffer &source); | 
|---|
| 472 | static void decodeA4R4G4B4(Buffer &destination, Buffer &source); | 
|---|
| 473 | static void decodeP8(Buffer &destination, Buffer &source); | 
|---|
| 474 |  | 
|---|
| 475 | static void decodeDXT1(Buffer &internal, Buffer &external); | 
|---|
| 476 | static void decodeDXT3(Buffer &internal, Buffer &external); | 
|---|
| 477 | static void decodeDXT5(Buffer &internal, Buffer &external); | 
|---|
| 478 | static void decodeATI1(Buffer &internal, Buffer &external); | 
|---|
| 479 | static void decodeATI2(Buffer &internal, Buffer &external); | 
|---|
| 480 | static void decodeEAC(Buffer &internal, Buffer &external, int nbChannels, bool isSigned); | 
|---|
| 481 | static void decodeETC2(Buffer &internal, Buffer &external, int nbAlphaBits, bool isSRGB); | 
|---|
| 482 | static void decodeASTC(Buffer &internal, Buffer &external, int xSize, int ySize, int zSize, bool isSRGB); | 
|---|
| 483 |  | 
|---|
| 484 | static void update(Buffer &destination, Buffer &source); | 
|---|
| 485 | static void genericUpdate(Buffer &destination, Buffer &source); | 
|---|
| 486 | static void *allocateBuffer(int width, int height, int depth, int border, int samples, Format format); | 
|---|
| 487 | static void memfill4(void *buffer, int pattern, int bytes); | 
|---|
| 488 |  | 
|---|
| 489 | bool identicalBuffers() const; | 
|---|
| 490 | Format selectInternalFormat(Format format) const; | 
|---|
| 491 |  | 
|---|
| 492 | void resolve(); | 
|---|
| 493 |  | 
|---|
| 494 | Buffer external; | 
|---|
| 495 | Buffer internal; | 
|---|
| 496 | Buffer stencil; | 
|---|
| 497 |  | 
|---|
| 498 | const bool lockable; | 
|---|
| 499 | const bool renderTarget; | 
|---|
| 500 |  | 
|---|
| 501 | bool dirtyContents;   // Sibling surfaces need updating (mipmaps / cube borders). | 
|---|
| 502 | unsigned int paletteUsed; | 
|---|
| 503 |  | 
|---|
| 504 | static unsigned int *palette;   // FIXME: Not multi-device safe | 
|---|
| 505 | static unsigned int paletteID; | 
|---|
| 506 |  | 
|---|
| 507 | bool hasParent; | 
|---|
| 508 | bool ownExternal; | 
|---|
| 509 | }; | 
|---|
| 510 | } | 
|---|
| 511 |  | 
|---|
| 512 | #undef min | 
|---|
| 513 | #undef max | 
|---|
| 514 |  | 
|---|
| 515 | namespace sw | 
|---|
| 516 | { | 
|---|
| 517 | void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal) | 
|---|
| 518 | { | 
|---|
| 519 | return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client); | 
|---|
| 520 | } | 
|---|
| 521 |  | 
|---|
| 522 | void Surface::unlock(bool internal) | 
|---|
| 523 | { | 
|---|
| 524 | return internal ? unlockInternal() : unlockExternal(); | 
|---|
| 525 | } | 
|---|
| 526 |  | 
|---|
| 527 | int Surface::getWidth() const | 
|---|
| 528 | { | 
|---|
| 529 | return external.width; | 
|---|
| 530 | } | 
|---|
| 531 |  | 
|---|
| 532 | int Surface::getHeight() const | 
|---|
| 533 | { | 
|---|
| 534 | return external.height; | 
|---|
| 535 | } | 
|---|
| 536 |  | 
|---|
| 537 | int Surface::getDepth() const | 
|---|
| 538 | { | 
|---|
| 539 | return external.depth; | 
|---|
| 540 | } | 
|---|
| 541 |  | 
|---|
| 542 | int Surface::getBorder() const | 
|---|
| 543 | { | 
|---|
| 544 | return internal.border; | 
|---|
| 545 | } | 
|---|
| 546 |  | 
|---|
| 547 | Format Surface::getFormat(bool internal) const | 
|---|
| 548 | { | 
|---|
| 549 | return internal ? getInternalFormat() : getExternalFormat(); | 
|---|
| 550 | } | 
|---|
| 551 |  | 
|---|
| 552 | int Surface::getPitchB(bool internal) const | 
|---|
| 553 | { | 
|---|
| 554 | return internal ? getInternalPitchB() : getExternalPitchB(); | 
|---|
| 555 | } | 
|---|
| 556 |  | 
|---|
| 557 | int Surface::getPitchP(bool internal) const | 
|---|
| 558 | { | 
|---|
| 559 | return internal ? getInternalPitchP() : getExternalPitchP(); | 
|---|
| 560 | } | 
|---|
| 561 |  | 
|---|
| 562 | int Surface::getSliceB(bool internal) const | 
|---|
| 563 | { | 
|---|
| 564 | return internal ? getInternalSliceB() : getExternalSliceB(); | 
|---|
| 565 | } | 
|---|
| 566 |  | 
|---|
| 567 | int Surface::getSliceP(bool internal) const | 
|---|
| 568 | { | 
|---|
| 569 | return internal ? getInternalSliceP() : getExternalSliceP(); | 
|---|
| 570 | } | 
|---|
| 571 |  | 
|---|
| 572 | Format Surface::getExternalFormat() const | 
|---|
| 573 | { | 
|---|
| 574 | return external.format; | 
|---|
| 575 | } | 
|---|
| 576 |  | 
|---|
| 577 | int Surface::getExternalPitchB() const | 
|---|
| 578 | { | 
|---|
| 579 | return external.pitchB; | 
|---|
| 580 | } | 
|---|
| 581 |  | 
|---|
| 582 | int Surface::getExternalPitchP() const | 
|---|
| 583 | { | 
|---|
| 584 | return external.pitchP; | 
|---|
| 585 | } | 
|---|
| 586 |  | 
|---|
| 587 | int Surface::getExternalSliceB() const | 
|---|
| 588 | { | 
|---|
| 589 | return external.sliceB; | 
|---|
| 590 | } | 
|---|
| 591 |  | 
|---|
| 592 | int Surface::getExternalSliceP() const | 
|---|
| 593 | { | 
|---|
| 594 | return external.sliceP; | 
|---|
| 595 | } | 
|---|
| 596 |  | 
|---|
| 597 | Format Surface::getInternalFormat() const | 
|---|
| 598 | { | 
|---|
| 599 | return internal.format; | 
|---|
| 600 | } | 
|---|
| 601 |  | 
|---|
| 602 | int Surface::getInternalPitchB() const | 
|---|
| 603 | { | 
|---|
| 604 | return internal.pitchB; | 
|---|
| 605 | } | 
|---|
| 606 |  | 
|---|
| 607 | int Surface::getInternalPitchP() const | 
|---|
| 608 | { | 
|---|
| 609 | return internal.pitchP; | 
|---|
| 610 | } | 
|---|
| 611 |  | 
|---|
| 612 | int Surface::getInternalSliceB() const | 
|---|
| 613 | { | 
|---|
| 614 | return internal.sliceB; | 
|---|
| 615 | } | 
|---|
| 616 |  | 
|---|
| 617 | int Surface::getInternalSliceP() const | 
|---|
| 618 | { | 
|---|
| 619 | return internal.sliceP; | 
|---|
| 620 | } | 
|---|
| 621 |  | 
|---|
| 622 | Format Surface::getStencilFormat() const | 
|---|
| 623 | { | 
|---|
| 624 | return stencil.format; | 
|---|
| 625 | } | 
|---|
| 626 |  | 
|---|
| 627 | int Surface::getStencilPitchB() const | 
|---|
| 628 | { | 
|---|
| 629 | return stencil.pitchB; | 
|---|
| 630 | } | 
|---|
| 631 |  | 
|---|
| 632 | int Surface::getStencilSliceB() const | 
|---|
| 633 | { | 
|---|
| 634 | return stencil.sliceB; | 
|---|
| 635 | } | 
|---|
| 636 |  | 
|---|
| 637 | int Surface::getSamples() const | 
|---|
| 638 | { | 
|---|
| 639 | return internal.samples; | 
|---|
| 640 | } | 
|---|
| 641 |  | 
|---|
| 642 | int Surface::getMultiSampleCount() const | 
|---|
| 643 | { | 
|---|
| 644 | return sw::min((int)internal.samples, 4); | 
|---|
| 645 | } | 
|---|
| 646 |  | 
|---|
| 647 | int Surface::getSuperSampleCount() const | 
|---|
| 648 | { | 
|---|
| 649 | return internal.samples > 4 ? internal.samples / 4 : 1; | 
|---|
| 650 | } | 
|---|
| 651 |  | 
|---|
| 652 | bool Surface::isUnlocked() const | 
|---|
| 653 | { | 
|---|
| 654 | return external.lock == LOCK_UNLOCKED && | 
|---|
| 655 | internal.lock == LOCK_UNLOCKED && | 
|---|
| 656 | stencil.lock == LOCK_UNLOCKED; | 
|---|
| 657 | } | 
|---|
| 658 |  | 
|---|
| 659 | bool Surface::isExternalDirty() const | 
|---|
| 660 | { | 
|---|
| 661 | return external.buffer && external.buffer != internal.buffer && external.dirty; | 
|---|
| 662 | } | 
|---|
| 663 | } | 
|---|
| 664 |  | 
|---|
| 665 | #endif   // sw_Surface_hpp | 
|---|
| 666 |  | 
|---|