Surface.hpp revision f946d78bc45fed74fbad8343f415e2a5d0fb2187
1// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2013 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		Rect() {}
26		Rect(int x0i, int y0i, int x1i, int y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {}
27
28		void clip(int minX, int minY, int maxX, int maxY);
29
30		int width() const  { return x1 - x0; }
31		int height() const { return y1 - y0; }
32
33		int x0;   // Inclusive
34		int y0;   // Inclusive
35		int x1;   // Exclusive
36		int y1;   // Exclusive
37	};
38
39	struct SliceRect : public Rect
40	{
41		SliceRect() : slice(0) {}
42		SliceRect(const Rect& rect) : Rect(rect), slice(0) {}
43		SliceRect(const Rect& rect, int s) : Rect(rect), slice(s) {}
44		SliceRect(int x0, int y0, int x1, int y1, int s) : Rect(x0, y0, x1, y1), slice(s) {}
45		int slice;
46	};
47
48	enum Format : unsigned char
49	{
50		FORMAT_NULL,
51
52		FORMAT_A8,
53		FORMAT_R8I,
54		FORMAT_R8UI,
55		FORMAT_R8I_SNORM,
56		FORMAT_R8, // UI_SNORM
57		FORMAT_R16I,
58		FORMAT_R16UI,
59		FORMAT_R32I,
60		FORMAT_R32UI,
61		FORMAT_R3G3B2,
62		FORMAT_A8R3G3B2,
63		FORMAT_X4R4G4B4,
64		FORMAT_A4R4G4B4,
65		FORMAT_R4G4B4A4,
66		FORMAT_R5G6B5,
67		FORMAT_R8G8B8,
68		FORMAT_B8G8R8,
69		FORMAT_X8R8G8B8,
70		FORMAT_A8R8G8B8,
71		FORMAT_X8B8G8R8I,
72		FORMAT_X8B8G8R8UI,
73		FORMAT_X8B8G8R8I_SNORM,
74		FORMAT_X8B8G8R8, // UI_SNORM
75		FORMAT_A8B8G8R8I,
76		FORMAT_A8B8G8R8UI,
77		FORMAT_A8B8G8R8I_SNORM,
78		FORMAT_A8B8G8R8, // UI_SNORM
79		FORMAT_X1R5G5B5,
80		FORMAT_A1R5G5B5,
81		FORMAT_R5G5B5A1,
82		FORMAT_G8R8I,
83		FORMAT_G8R8UI,
84		FORMAT_G8R8I_SNORM,
85		FORMAT_G8R8, // UI_SNORM
86		FORMAT_G16R16, // D3D format
87		FORMAT_G16R16I,
88		FORMAT_G16R16UI,
89		FORMAT_G32R32I,
90		FORMAT_G32R32UI,
91		FORMAT_A2R10G10B10,
92		FORMAT_A2B10G10R10,
93		FORMAT_A16B16G16R16, // D3D format
94		FORMAT_X16B16G16R16I,
95		FORMAT_X16B16G16R16UI,
96		FORMAT_A16B16G16R16I,
97		FORMAT_A16B16G16R16UI,
98		FORMAT_X32B32G32R32I,
99		FORMAT_X32B32G32R32UI,
100		FORMAT_A32B32G32R32I,
101		FORMAT_A32B32G32R32UI,
102		// Paletted formats
103		FORMAT_P8,
104		FORMAT_A8P8,
105		// Compressed formats
106		FORMAT_DXT1,
107		FORMAT_DXT3,
108		FORMAT_DXT5,
109		FORMAT_ATI1,
110		FORMAT_ATI2,
111		FORMAT_ETC1,
112		FORMAT_R11_EAC,
113		FORMAT_SIGNED_R11_EAC,
114		FORMAT_RG11_EAC,
115		FORMAT_SIGNED_RG11_EAC,
116		FORMAT_RGB8_ETC2,
117		FORMAT_SRGB8_ETC2,
118		FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
119		FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
120		FORMAT_RGBA8_ETC2_EAC,
121		FORMAT_SRGB8_ALPHA8_ETC2_EAC,
122		FORMAT_RGBA_ASTC_4x4_KHR,
123		FORMAT_RGBA_ASTC_5x4_KHR,
124		FORMAT_RGBA_ASTC_5x5_KHR,
125		FORMAT_RGBA_ASTC_6x5_KHR,
126		FORMAT_RGBA_ASTC_6x6_KHR,
127		FORMAT_RGBA_ASTC_8x5_KHR,
128		FORMAT_RGBA_ASTC_8x6_KHR,
129		FORMAT_RGBA_ASTC_8x8_KHR,
130		FORMAT_RGBA_ASTC_10x5_KHR,
131		FORMAT_RGBA_ASTC_10x6_KHR,
132		FORMAT_RGBA_ASTC_10x8_KHR,
133		FORMAT_RGBA_ASTC_10x10_KHR,
134		FORMAT_RGBA_ASTC_12x10_KHR,
135		FORMAT_RGBA_ASTC_12x12_KHR,
136		FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR,
137		FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR,
138		FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR,
139		FORMAT_SRGB8_ALPHA8_ASTC_6x5_KHR,
140		FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR,
141		FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR,
142		FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR,
143		FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR,
144		FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR,
145		FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR,
146		FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR,
147		FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR,
148		FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR,
149		FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR,
150		// Floating-point formats
151		FORMAT_A16F,
152		FORMAT_R16F,
153		FORMAT_G16R16F,
154		FORMAT_B16G16R16F,
155		FORMAT_A16B16G16R16F,
156		FORMAT_A32F,
157		FORMAT_R32F,
158		FORMAT_G32R32F,
159		FORMAT_B32G32R32F,
160		FORMAT_X32B32G32R32F,
161		FORMAT_A32B32G32R32F,
162		// Bump map formats
163		FORMAT_V8U8,
164		FORMAT_L6V5U5,
165		FORMAT_Q8W8V8U8,
166		FORMAT_X8L8V8U8,
167		FORMAT_A2W10V10U10,
168		FORMAT_V16U16,
169		FORMAT_A16W16V16U16,
170		FORMAT_Q16W16V16U16,
171		// Luminance formats
172		FORMAT_L8,
173		FORMAT_A4L4,
174		FORMAT_L16,
175		FORMAT_A8L8,
176		FORMAT_L16F,
177		FORMAT_A16L16F,
178		FORMAT_L32F,
179		FORMAT_A32L32F,
180		// Depth/stencil formats
181		FORMAT_D16,
182		FORMAT_D32,
183		FORMAT_D24X8,
184		FORMAT_D24S8,
185		FORMAT_D24FS8,
186		FORMAT_D32F,                 // Quad layout
187		FORMAT_D32F_COMPLEMENTARY,   // Quad layout, 1 - z
188		FORMAT_D32F_LOCKABLE,        // Linear layout
189		FORMAT_D32FS8_TEXTURE,       // Linear layout, no PCF
190		FORMAT_D32FS8_SHADOW,        // Linear layout, PCF
191		FORMAT_DF24S8,
192		FORMAT_DF16S8,
193		FORMAT_INTZ,
194		FORMAT_S8,
195		// Quad layout framebuffer
196		FORMAT_X8G8R8B8Q,
197		FORMAT_A8G8R8B8Q,
198		// YUV formats
199		FORMAT_YV12_BT601,
200		FORMAT_YV12_BT709,
201		FORMAT_YV12_JFIF,    // Full-swing BT.601
202
203		FORMAT_LAST = FORMAT_YV12_JFIF
204	};
205
206	enum Lock
207	{
208		LOCK_UNLOCKED,
209		LOCK_READONLY,
210		LOCK_WRITEONLY,
211		LOCK_READWRITE,
212		LOCK_DISCARD
213	};
214
215	class Surface
216	{
217	private:
218		struct Buffer
219		{
220		public:
221			void write(int x, int y, int z, const Color<float> &color);
222			void write(int x, int y, const Color<float> &color);
223			void write(void *element, const Color<float> &color);
224			Color<float> read(int x, int y, int z) const;
225			Color<float> read(int x, int y) const;
226			Color<float> read(void *element) const;
227			Color<float> sample(float x, float y, float z) const;
228			Color<float> sample(float x, float y) const;
229
230			void *lockRect(int x, int y, int z, Lock lock);
231			void unlockRect();
232
233			void *buffer;
234			int width;
235			int height;
236			int depth;
237			int bytes;
238			int pitchB;
239			int pitchP;
240			int sliceB;
241			int sliceP;
242			Format format;
243			Lock lock;
244
245			bool dirty;
246		};
247
248	public:
249		Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
250		Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0);
251
252		virtual ~Surface();
253
254		inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false);
255		inline void unlock(bool internal = false);
256		inline int getWidth() const;
257		inline int getHeight() const;
258		inline int getDepth() const;
259		inline Format getFormat(bool internal = false) const;
260		inline int getPitchB(bool internal = false) const;
261		inline int getPitchP(bool internal = false) const;
262		inline int getSliceB(bool internal = false) const;
263		inline int getSliceP(bool internal = false) const;
264
265		void *lockExternal(int x, int y, int z, Lock lock, Accessor client);
266		void unlockExternal();
267		inline Format getExternalFormat() const;
268		inline int getExternalPitchB() const;
269		inline int getExternalPitchP() const;
270		inline int getExternalSliceB() const;
271		inline int getExternalSliceP() const;
272
273		virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client);
274		virtual void unlockInternal();
275		inline Format getInternalFormat() const;
276		inline int getInternalPitchB() const;
277		inline int getInternalPitchP() const;
278		inline int getInternalSliceB() const;
279		inline int getInternalSliceP() const;
280
281		void *lockStencil(int front, Accessor client);
282		void unlockStencil();
283		inline int getStencilPitchB() const;
284		inline int getStencilSliceB() const;
285
286		inline int getMultiSampleCount() const;
287		inline int getSuperSampleCount() const;
288
289		bool isEntire(const SliceRect& rect) const;
290		SliceRect getRect() const;
291		void clearDepth(float depth, int x0, int y0, int width, int height);
292		void clearStencil(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height);
293		void fill(const Color<float> &color, int x0, int y0, int width, int height);
294
295		Color<float> readExternal(int x, int y, int z) const;
296		Color<float> readExternal(int x, int y) const;
297		Color<float> sampleExternal(float x, float y, float z) const;
298		Color<float> sampleExternal(float x, float y) const;
299		void writeExternal(int x, int y, int z, const Color<float> &color);
300		void writeExternal(int x, int y, const Color<float> &color);
301
302		void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter);
303		void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter);
304
305		bool hasStencil() const;
306		bool hasDepth() const;
307		bool hasPalette() const;
308		bool isRenderTarget() const;
309
310		bool hasDirtyMipmaps() const;
311		void cleanMipmaps();
312		inline bool isExternalDirty() const;
313		Resource *getResource();
314
315		static int bytes(Format format);
316		static int pitchB(int width, Format format, bool target);
317		static int pitchP(int width, Format format, bool target);
318		static int sliceB(int width, int height, Format format, bool target);
319		static int sliceP(int width, int height, Format format, bool target);
320		static unsigned int size(int width, int height, int depth, Format format);   // FIXME: slice * depth
321
322		static bool isStencil(Format format);
323		static bool isDepth(Format format);
324		static bool isPalette(Format format);
325
326		static bool isFloatFormat(Format format);
327		static bool isUnsignedComponent(Format format, int component);
328		static bool isSRGBreadable(Format format);
329		static bool isSRGBwritable(Format format);
330		static bool isCompressed(Format format);
331		static bool isNonNormalizedInteger(Format format);
332		static int componentCount(Format format);
333
334		static void setTexturePalette(unsigned int *palette);
335
336	protected:
337		sw::Resource *resource;
338
339	private:
340		typedef unsigned char byte;
341		typedef unsigned short word;
342		typedef unsigned int dword;
343		typedef uint64_t qword;
344
345		#if S3TC_SUPPORT
346		struct DXT1
347		{
348			word c0;
349			word c1;
350			dword lut;
351		};
352
353		struct DXT3
354		{
355			qword a;
356
357			word c0;
358			word c1;
359			dword lut;
360		};
361
362		struct DXT5
363		{
364			union
365			{
366				struct
367				{
368					byte a0;
369					byte a1;
370				};
371
372				qword alut;   // Skip first 16 bit
373			};
374
375			word c0;
376			word c1;
377			dword clut;
378		};
379		#endif
380
381		struct ATI2
382		{
383			union
384			{
385				struct
386				{
387					byte y0;
388					byte y1;
389				};
390
391				qword ylut;   // Skip first 16 bit
392			};
393
394			union
395			{
396				struct
397				{
398					byte x0;
399					byte x1;
400				};
401
402				qword xlut;   // Skip first 16 bit
403			};
404		};
405
406		struct ATI1
407		{
408			union
409			{
410				struct
411				{
412					byte r0;
413					byte r1;
414				};
415
416				qword rlut;   // Skip first 16 bit
417			};
418		};
419
420		static void decodeR8G8B8(Buffer &destination, const Buffer &source);
421		static void decodeX1R5G5B5(Buffer &destination, const Buffer &source);
422		static void decodeA1R5G5B5(Buffer &destination, const Buffer &source);
423		static void decodeX4R4G4B4(Buffer &destination, const Buffer &source);
424		static void decodeA4R4G4B4(Buffer &destination, const Buffer &source);
425		static void decodeP8(Buffer &destination, const Buffer &source);
426
427		#if S3TC_SUPPORT
428		static void decodeDXT1(Buffer &internal, const Buffer &external);
429		static void decodeDXT3(Buffer &internal, const Buffer &external);
430		static void decodeDXT5(Buffer &internal, const Buffer &external);
431		#endif
432		static void decodeATI1(Buffer &internal, const Buffer &external);
433		static void decodeATI2(Buffer &internal, const Buffer &external);
434		static void decodeEAC(Buffer &internal, const Buffer &external, int nbChannels, bool isSigned);
435		static void decodeETC2(Buffer &internal, const Buffer &external, int nbAlphaBits, bool isSRGB);
436		static void decodeASTC(Buffer &internal, const Buffer &external, int xSize, int ySize, int zSize, bool isSRGB);
437
438		static void update(Buffer &destination, Buffer &source);
439		static void genericUpdate(Buffer &destination, Buffer &source);
440		static void *allocateBuffer(int width, int height, int depth, Format format);
441		static void memfill4(void *buffer, int pattern, int bytes);
442
443		bool identicalFormats() const;
444		Format selectInternalFormat(Format format) const;
445
446		void resolve();
447
448		Buffer external;
449		Buffer internal;
450		Buffer stencil;
451
452		const bool lockable;
453		const bool renderTarget;
454
455		bool dirtyMipmaps;
456		unsigned int paletteUsed;
457
458		static unsigned int *palette;   // FIXME: Not multi-device safe
459		static unsigned int paletteID;
460
461		bool hasParent;
462		bool ownExternal;
463	};
464}
465
466#undef min
467#undef max
468
469namespace sw
470{
471	void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal)
472	{
473		return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client);
474	}
475
476	void Surface::unlock(bool internal)
477	{
478		return internal ? unlockInternal() : unlockExternal();
479	}
480
481	int Surface::getWidth() const
482	{
483		return external.width;
484	}
485
486	int Surface::getHeight() const
487	{
488		return external.height;
489	}
490
491	int Surface::getDepth() const
492	{
493		return external.depth;
494	}
495
496	Format Surface::getFormat(bool internal) const
497	{
498		return internal ? getInternalFormat() : getExternalFormat();
499	}
500
501	int Surface::getPitchB(bool internal) const
502	{
503		return internal ? getInternalPitchB() : getExternalPitchB();
504	}
505
506	int Surface::getPitchP(bool internal) const
507	{
508		return internal ? getInternalPitchP() : getExternalPitchB();
509	}
510
511	int Surface::getSliceB(bool internal) const
512	{
513		return internal ? getInternalSliceB() : getExternalSliceB();
514	}
515
516	int Surface::getSliceP(bool internal) const
517	{
518		return internal ? getInternalSliceP() : getExternalSliceB();
519	}
520
521	Format Surface::getExternalFormat() const
522	{
523		return external.format;
524	}
525
526	int Surface::getExternalPitchB() const
527	{
528		return external.pitchB;
529	}
530
531	int Surface::getExternalPitchP() const
532	{
533		return external.pitchP;
534	}
535
536	int Surface::getExternalSliceB() const
537	{
538		return external.sliceB;
539	}
540
541	int Surface::getExternalSliceP() const
542	{
543		return external.sliceP;
544	}
545
546	Format Surface::getInternalFormat() const
547	{
548		return internal.format;
549	}
550
551	int Surface::getInternalPitchB() const
552	{
553		return internal.pitchB;
554	}
555
556	int Surface::getInternalPitchP() const
557	{
558		return internal.pitchP;
559	}
560
561	int Surface::getInternalSliceB() const
562	{
563		return internal.sliceB;
564	}
565
566	int Surface::getInternalSliceP() const
567	{
568		return internal.sliceP;
569	}
570
571	int Surface::getStencilPitchB() const
572	{
573		return stencil.pitchB;
574	}
575
576	int Surface::getStencilSliceB() const
577	{
578		return stencil.sliceB;
579	}
580
581	int Surface::getMultiSampleCount() const
582	{
583		return sw::min(internal.depth, 4);
584	}
585
586	int Surface::getSuperSampleCount() const
587	{
588		return internal.depth > 4 ? internal.depth / 4 : 1;
589	}
590
591	bool Surface::isExternalDirty() const
592	{
593		return external.buffer && external.buffer != internal.buffer && external.dirty;
594	}
595}
596
597#endif   // sw_Surface_hpp
598