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 	{
RectTsw::RectT28 		RectT() {}
RectTsw::RectT29 		RectT(T x0i, T y0i, T x1i, T y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {}
30 
clipsw::RectT31 		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 
widthsw::RectT39 		T width() const  { return x1 - x0; }
heightsw::RectT40 		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 	{
SliceRectTsw::SliceRectT53 		SliceRectT() : slice(0) {}
SliceRectTsw::SliceRectT54 		SliceRectT(const RectT<T>& rect) : RectT<T>(rect), slice(0) {}
SliceRectTsw::SliceRectT55 		SliceRectT(const RectT<T>& rect, int s) : RectT<T>(rect), slice(s) {}
SliceRectTsw::SliceRectT56 		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 ENUM_UNDERLYING_TYPE_UNSIGNED_INT
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 		// Floating-point formats
141 		FORMAT_A16F,
142 		FORMAT_R16F,
143 		FORMAT_G16R16F,
144 		FORMAT_B16G16R16F,
145 		FORMAT_X16B16G16R16F,
146 		FORMAT_A16B16G16R16F,
147 		FORMAT_X16B16G16R16F_UNSIGNED,
148 		FORMAT_A32F,
149 		FORMAT_R32F,
150 		FORMAT_G32R32F,
151 		FORMAT_B32G32R32F,
152 		FORMAT_X32B32G32R32F,
153 		FORMAT_A32B32G32R32F,
154 		FORMAT_X32B32G32R32F_UNSIGNED,
155 		// Bump map formats
156 		FORMAT_V8U8,
157 		FORMAT_L6V5U5,
158 		FORMAT_Q8W8V8U8,
159 		FORMAT_X8L8V8U8,
160 		FORMAT_A2W10V10U10,
161 		FORMAT_V16U16,
162 		FORMAT_A16W16V16U16,
163 		FORMAT_Q16W16V16U16,
164 		// Luminance formats
165 		FORMAT_L8,
166 		FORMAT_A4L4,
167 		FORMAT_L16,
168 		FORMAT_A8L8,
169 		FORMAT_L16F,
170 		FORMAT_A16L16F,
171 		FORMAT_L32F,
172 		FORMAT_A32L32F,
173 		// Depth/stencil formats
174 		FORMAT_D16,
175 		FORMAT_D32,
176 		FORMAT_D24X8,
177 		FORMAT_D24S8,
178 		FORMAT_D24FS8,
179 		FORMAT_D32F,                 // Quad layout
180 		FORMAT_D32FS8,               // Quad layout
181 		FORMAT_D32F_COMPLEMENTARY,   // Quad layout, 1 - z
182 		FORMAT_D32FS8_COMPLEMENTARY, // Quad layout, 1 - z
183 		FORMAT_D32F_LOCKABLE,        // Linear layout
184 		FORMAT_D32FS8_TEXTURE,       // Linear layout, no PCF
185 		FORMAT_D32F_SHADOW,          // Linear layout, PCF
186 		FORMAT_D32FS8_SHADOW,        // Linear layout, PCF
187 		FORMAT_DF24S8,
188 		FORMAT_DF16S8,
189 		FORMAT_INTZ,
190 		FORMAT_S8,
191 		// Quad layout framebuffer
192 		FORMAT_X8G8R8B8Q,
193 		FORMAT_A8G8R8B8Q,
194 		// YUV formats
195 		FORMAT_YV12_BT601,
196 		FORMAT_YV12_BT709,
197 		FORMAT_YV12_JFIF,    // Full-swing BT.601
198 
199 		FORMAT_LAST = FORMAT_YV12_JFIF
200 	};
201 
202 	enum Lock
203 	{
204 		LOCK_UNLOCKED,
205 		LOCK_READONLY,
206 		LOCK_WRITEONLY,
207 		LOCK_READWRITE,
208 		LOCK_DISCARD,
209 		LOCK_UPDATE   // Write access which doesn't dirty the buffer, because it's being updated with the sibling's data.
210 	};
211 
212 	class [[clang::lto_visibility_public]] Surface
213 	{
214 	private:
215 		struct Buffer
216 		{
217 			friend Surface;
218 
219 		private:
220 			void write(int x, int y, int z, const Color<float> &color);
221 			void write(int x, int y, const Color<float> &color);
222 			void write(void *element, const Color<float> &color);
223 			Color<float> read(int x, int y, int z) const;
224 			Color<float> read(int x, int y) const;
225 			Color<float> read(void *element) const;
226 			Color<float> sample(float x, float y, float z) const;
227 			Color<float> sample(float x, float y, int layer) const;
228 
229 			void *lockRect(int x, int y, int z, Lock lock);
230 			void unlockRect();
231 
232 			void *buffer;
233 			int width;
234 			int height;
235 			int depth;
236 			short border;
237 			short samples;
238 
239 			int bytes;
240 			int pitchB;
241 			int pitchP;
242 			int sliceB;
243 			int sliceP;
244 
245 			Format format;
246 			AtomicInt lock;
247 
248 			bool dirty;   // Sibling internal/external buffer doesn't match.
249 		};
250 
251 	protected:
252 		Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
253 		Surface(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0);
254 
255 	public:
256 		static Surface *create(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
257 		static Surface *create(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0);
258 
259 		virtual ~Surface() = 0;
260 
261 		inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false);
262 		inline void unlock(bool internal = false);
263 		inline int getWidth() const;
264 		inline int getHeight() const;
265 		inline int getDepth() const;
266 		inline int getBorder() const;
267 		inline Format getFormat(bool internal = false) const;
268 		inline int getPitchB(bool internal = false) const;
269 		inline int getPitchP(bool internal = false) const;
270 		inline int getSliceB(bool internal = false) const;
271 		inline int getSliceP(bool internal = false) const;
272 
273 		void *lockExternal(int x, int y, int z, Lock lock, Accessor client);
274 		void unlockExternal();
275 		inline Format getExternalFormat() const;
276 		inline int getExternalPitchB() const;
277 		inline int getExternalPitchP() const;
278 		inline int getExternalSliceB() const;
279 		inline int getExternalSliceP() const;
280 
281 		virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client) = 0;
282 		virtual void unlockInternal() = 0;
283 		inline Format getInternalFormat() const;
284 		inline int getInternalPitchB() const;
285 		inline int getInternalPitchP() const;
286 		inline int getInternalSliceB() const;
287 		inline int getInternalSliceP() const;
288 
289 		void *lockStencil(int x, int y, int front, Accessor client);
290 		void unlockStencil();
291 		inline Format getStencilFormat() const;
292 		inline int getStencilPitchB() const;
293 		inline int getStencilSliceB() const;
294 
295 		void sync();                      // Wait for lock(s) to be released.
requiresSync() const296 		virtual bool requiresSync() const { return false; }
297 		inline bool isUnlocked() const;   // Only reliable after sync().
298 
299 		inline int getSamples() const;
300 		inline int getMultiSampleCount() const;
301 		inline int getSuperSampleCount() const;
302 
303 		bool isEntire(const Rect& rect) const;
304 		Rect getRect() const;
305 		void clearDepth(float depth, int x0, int y0, int width, int height);
306 		void clearStencil(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height);
307 		void fill(const Color<float> &color, int x0, int y0, int width, int height);
308 
309 		Color<float> readExternal(int x, int y, int z) const;
310 		Color<float> readExternal(int x, int y) const;
311 		Color<float> sampleExternal(float x, float y, float z) const;
312 		Color<float> sampleExternal(float x, float y) const;
313 		void writeExternal(int x, int y, int z, const Color<float> &color);
314 		void writeExternal(int x, int y, const Color<float> &color);
315 
316 		void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter);
317 		void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter);
318 
319 		enum Edge { TOP, BOTTOM, RIGHT, LEFT };
320 		void copyCubeEdge(Edge dstEdge, Surface *src, Edge srcEdge);
321 		void computeCubeCorner(int x0, int y0, int x1, int y1);
322 
323 		bool hasStencil() const;
324 		bool hasDepth() const;
325 		bool hasPalette() const;
326 		bool isRenderTarget() const;
327 
328 		bool hasDirtyContents() const;
329 		void markContentsClean();
330 		inline bool isExternalDirty() const;
331 		Resource *getResource();
332 
333 		static int bytes(Format format);
334 		static int pitchB(int width, int border, Format format, bool target);
335 		static int pitchP(int width, int border, Format format, bool target);
336 		static int sliceB(int width, int height, int border, Format format, bool target);
337 		static int sliceP(int width, int height, int border, Format format, bool target);
338 		static size_t size(int width, int height, int depth, int border, int samples, Format format);
339 
340 		static bool isStencil(Format format);
341 		static bool isDepth(Format format);
342 		static bool hasQuadLayout(Format format);
343 		static bool isPalette(Format format);
344 
345 		static bool isFloatFormat(Format format);
346 		static bool isUnsignedComponent(Format format, int component);
347 		static bool isSRGBreadable(Format format);
348 		static bool isSRGBwritable(Format format);
349 		static bool isSRGBformat(Format format);
350 		static bool isCompressed(Format format);
351 		static bool isSignedNonNormalizedInteger(Format format);
352 		static bool isUnsignedNonNormalizedInteger(Format format);
353 		static bool isNonNormalizedInteger(Format format);
354 		static bool isNormalizedInteger(Format format);
355 		static int componentCount(Format format);
356 
357 		static void setTexturePalette(unsigned int *palette);
358 
359 	private:
360 		sw::Resource *resource;
361 
362 		typedef unsigned char byte;
363 		typedef unsigned short word;
364 		typedef unsigned int dword;
365 		typedef uint64_t qword;
366 
367 		struct DXT1
368 		{
369 			word c0;
370 			word c1;
371 			dword lut;
372 		};
373 
374 		struct DXT3
375 		{
376 			qword a;
377 
378 			word c0;
379 			word c1;
380 			dword lut;
381 		};
382 
383 		struct DXT5
384 		{
385 			union
386 			{
387 				struct
388 				{
389 					byte a0;
390 					byte a1;
391 				};
392 
393 				qword alut;   // Skip first 16 bit
394 			};
395 
396 			word c0;
397 			word c1;
398 			dword clut;
399 		};
400 
401 		struct ATI2
402 		{
403 			union
404 			{
405 				struct
406 				{
407 					byte y0;
408 					byte y1;
409 				};
410 
411 				qword ylut;   // Skip first 16 bit
412 			};
413 
414 			union
415 			{
416 				struct
417 				{
418 					byte x0;
419 					byte x1;
420 				};
421 
422 				qword xlut;   // Skip first 16 bit
423 			};
424 		};
425 
426 		struct ATI1
427 		{
428 			union
429 			{
430 				struct
431 				{
432 					byte r0;
433 					byte r1;
434 				};
435 
436 				qword rlut;   // Skip first 16 bit
437 			};
438 		};
439 
440 		static void decodeR8G8B8(Buffer &destination, Buffer &source);
441 		static void decodeX1R5G5B5(Buffer &destination, Buffer &source);
442 		static void decodeA1R5G5B5(Buffer &destination, Buffer &source);
443 		static void decodeX4R4G4B4(Buffer &destination, Buffer &source);
444 		static void decodeA4R4G4B4(Buffer &destination, Buffer &source);
445 		static void decodeP8(Buffer &destination, Buffer &source);
446 
447 		static void decodeDXT1(Buffer &internal, Buffer &external);
448 		static void decodeDXT3(Buffer &internal, Buffer &external);
449 		static void decodeDXT5(Buffer &internal, Buffer &external);
450 		static void decodeATI1(Buffer &internal, Buffer &external);
451 		static void decodeATI2(Buffer &internal, Buffer &external);
452 		static void decodeEAC(Buffer &internal, Buffer &external, int nbChannels, bool isSigned);
453 		static void decodeETC2(Buffer &internal, Buffer &external, int nbAlphaBits, bool isSRGB);
454 
455 		static void update(Buffer &destination, Buffer &source);
456 		static void genericUpdate(Buffer &destination, Buffer &source);
457 		static void *allocateBuffer(int width, int height, int depth, int border, int samples, Format format);
458 		static void memfill4(void *buffer, int pattern, int bytes);
459 
460 		bool identicalBuffers() const;
461 		Format selectInternalFormat(Format format) const;
462 
463 		void resolve();
464 
465 		Buffer external;
466 		Buffer internal;
467 		Buffer stencil;
468 
469 		const bool lockable;
470 		const bool renderTarget;
471 
472 		bool dirtyContents;   // Sibling surfaces need updating (mipmaps / cube borders).
473 		unsigned int paletteUsed;
474 
475 		static unsigned int *palette;   // FIXME: Not multi-device safe
476 		static unsigned int paletteID;
477 
478 		bool hasParent;
479 		bool ownExternal;
480 	};
481 }
482 
483 #undef min
484 #undef max
485 
486 namespace sw
487 {
lock(int x,int y,int z,Lock lock,Accessor client,bool internal)488 	void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal)
489 	{
490 		return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client);
491 	}
492 
unlock(bool internal)493 	void Surface::unlock(bool internal)
494 	{
495 		return internal ? unlockInternal() : unlockExternal();
496 	}
497 
getWidth() const498 	int Surface::getWidth() const
499 	{
500 		return external.width;
501 	}
502 
getHeight() const503 	int Surface::getHeight() const
504 	{
505 		return external.height;
506 	}
507 
getDepth() const508 	int Surface::getDepth() const
509 	{
510 		return external.depth;
511 	}
512 
getBorder() const513 	int Surface::getBorder() const
514 	{
515 		return internal.border;
516 	}
517 
getFormat(bool internal) const518 	Format Surface::getFormat(bool internal) const
519 	{
520 		return internal ? getInternalFormat() : getExternalFormat();
521 	}
522 
getPitchB(bool internal) const523 	int Surface::getPitchB(bool internal) const
524 	{
525 		return internal ? getInternalPitchB() : getExternalPitchB();
526 	}
527 
getPitchP(bool internal) const528 	int Surface::getPitchP(bool internal) const
529 	{
530 		return internal ? getInternalPitchP() : getExternalPitchP();
531 	}
532 
getSliceB(bool internal) const533 	int Surface::getSliceB(bool internal) const
534 	{
535 		return internal ? getInternalSliceB() : getExternalSliceB();
536 	}
537 
getSliceP(bool internal) const538 	int Surface::getSliceP(bool internal) const
539 	{
540 		return internal ? getInternalSliceP() : getExternalSliceP();
541 	}
542 
getExternalFormat() const543 	Format Surface::getExternalFormat() const
544 	{
545 		return external.format;
546 	}
547 
getExternalPitchB() const548 	int Surface::getExternalPitchB() const
549 	{
550 		return external.pitchB;
551 	}
552 
getExternalPitchP() const553 	int Surface::getExternalPitchP() const
554 	{
555 		return external.pitchP;
556 	}
557 
getExternalSliceB() const558 	int Surface::getExternalSliceB() const
559 	{
560 		return external.sliceB;
561 	}
562 
getExternalSliceP() const563 	int Surface::getExternalSliceP() const
564 	{
565 		return external.sliceP;
566 	}
567 
getInternalFormat() const568 	Format Surface::getInternalFormat() const
569 	{
570 		return internal.format;
571 	}
572 
getInternalPitchB() const573 	int Surface::getInternalPitchB() const
574 	{
575 		return internal.pitchB;
576 	}
577 
getInternalPitchP() const578 	int Surface::getInternalPitchP() const
579 	{
580 		return internal.pitchP;
581 	}
582 
getInternalSliceB() const583 	int Surface::getInternalSliceB() const
584 	{
585 		return internal.sliceB;
586 	}
587 
getInternalSliceP() const588 	int Surface::getInternalSliceP() const
589 	{
590 		return internal.sliceP;
591 	}
592 
getStencilFormat() const593 	Format Surface::getStencilFormat() const
594 	{
595 		return stencil.format;
596 	}
597 
getStencilPitchB() const598 	int Surface::getStencilPitchB() const
599 	{
600 		return stencil.pitchB;
601 	}
602 
getStencilSliceB() const603 	int Surface::getStencilSliceB() const
604 	{
605 		return stencil.sliceB;
606 	}
607 
getSamples() const608 	int Surface::getSamples() const
609 	{
610 		return internal.samples;
611 	}
612 
getMultiSampleCount() const613 	int Surface::getMultiSampleCount() const
614 	{
615 		return sw::min((int)internal.samples, 4);
616 	}
617 
getSuperSampleCount() const618 	int Surface::getSuperSampleCount() const
619 	{
620 		return internal.samples > 4 ? internal.samples / 4 : 1;
621 	}
622 
isUnlocked() const623 	bool Surface::isUnlocked() const
624 	{
625 		return external.lock == LOCK_UNLOCKED &&
626 		       internal.lock == LOCK_UNLOCKED &&
627 		       stencil.lock == LOCK_UNLOCKED;
628 	}
629 
isExternalDirty() const630 	bool Surface::isExternalDirty() const
631 	{
632 		return external.buffer && external.buffer != internal.buffer && external.dirty;
633 	}
634 }
635 
636 #endif   // sw_Surface_hpp
637