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 | |