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