Surface.hpp revision 8059442dded9441b54cc764e0ccc3a0c83120fc3
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 x0;   // Inclusive
31		int y0;   // Inclusive
32		int x1;   // Exclusive
33		int y1;   // Exclusive
34	};
35
36	struct SliceRect : public Rect
37	{
38		SliceRect() : slice(0) {}
39		SliceRect(const Rect& rect) : Rect(rect), slice(0) {}
40		SliceRect(const Rect& rect, int s) : Rect(rect), slice(s) {}
41		SliceRect(int x0, int y0, int x1, int y1, int s) : Rect(x0, y0, x1, y1), slice(s) {}
42		int slice;
43	};
44
45	enum Format : unsigned char
46	{
47		FORMAT_NULL,
48
49		FORMAT_A8,
50		FORMAT_R8,
51		FORMAT_R3G3B2,
52		FORMAT_A8R3G3B2,
53		FORMAT_X4R4G4B4,
54		FORMAT_A4R4G4B4,
55		FORMAT_R4G4B4A4,
56		FORMAT_R5G6B5,
57		FORMAT_R8G8B8,
58		FORMAT_B8G8R8,
59		FORMAT_X8R8G8B8,
60		FORMAT_A8R8G8B8,
61		FORMAT_X8B8G8R8,
62		FORMAT_A8B8G8R8,
63		FORMAT_X1R5G5B5,
64		FORMAT_A1R5G5B5,
65		FORMAT_R5G5B5A1,
66		FORMAT_G8R8,
67		FORMAT_G16R16,
68		FORMAT_A2R10G10B10,
69		FORMAT_A2B10G10R10,
70		FORMAT_A16B16G16R16,
71		// Paletted formats
72		FORMAT_P8,
73		FORMAT_A8P8,
74		// Compressed formats
75		FORMAT_DXT1,
76		FORMAT_DXT3,
77		FORMAT_DXT5,
78		FORMAT_ATI1,
79		FORMAT_ATI2,
80        FORMAT_ETC1,
81		// Floating-point formats
82		FORMAT_A16F,
83		FORMAT_R16F,
84		FORMAT_G16R16F,
85		FORMAT_B16G16R16F,
86		FORMAT_A16B16G16R16F,
87		FORMAT_A32F,
88		FORMAT_R32F,
89		FORMAT_G32R32F,
90		FORMAT_B32G32R32F,
91		FORMAT_A32B32G32R32F,
92		// Bump map formats
93		FORMAT_V8U8,
94		FORMAT_L6V5U5,
95		FORMAT_Q8W8V8U8,
96		FORMAT_X8L8V8U8,
97		FORMAT_A2W10V10U10,
98		FORMAT_V16U16,
99		FORMAT_A16W16V16U16,
100		FORMAT_Q16W16V16U16,
101		// Luminance formats
102		FORMAT_L8,
103		FORMAT_A4L4,
104		FORMAT_L16,
105		FORMAT_A8L8,
106		FORMAT_L16F,
107		FORMAT_A16L16F,
108		FORMAT_L32F,
109		FORMAT_A32L32F,
110		// Depth/stencil formats
111		FORMAT_D16,
112		FORMAT_D32,
113		FORMAT_D24X8,
114		FORMAT_D24S8,
115		FORMAT_D24FS8,
116		FORMAT_D32F,                 // Quad layout
117		FORMAT_D32F_COMPLEMENTARY,   // Quad layout, 1 - z
118		FORMAT_D32F_LOCKABLE,        // Linear layout
119		FORMAT_D32FS8_TEXTURE,       // Linear layout, no PCF
120		FORMAT_D32FS8_SHADOW,        // Linear layout, PCF
121		FORMAT_DF24S8,
122		FORMAT_DF16S8,
123		FORMAT_INTZ,
124		FORMAT_S8,
125		// Quad layout framebuffer
126		FORMAT_X8G8R8B8Q,
127		FORMAT_A8G8R8B8Q,
128
129		FORMAT_LAST = FORMAT_A8G8R8B8Q
130	};
131
132	enum Lock
133	{
134		LOCK_UNLOCKED,
135		LOCK_READONLY,
136		LOCK_WRITEONLY,
137		LOCK_READWRITE,
138		LOCK_DISCARD
139	};
140
141	class Surface
142	{
143	private:
144		struct Buffer
145		{
146		public:
147			void write(int x, int y, int z, const Color<float> &color);
148			void write(int x, int y, const Color<float> &color);
149			void write(void *element, const Color<float> &color);
150			Color<float> read(int x, int y, int z) const;
151			Color<float> read(int x, int y) const;
152			Color<float> read(void *element) const;
153			Color<float> sample(float x, float y, float z) const;
154			Color<float> sample(float x, float y) const;
155
156			void *lockRect(int x, int y, int z, Lock lock);
157			void unlockRect();
158
159			void *buffer;
160			int width;
161			int height;
162			int depth;
163			int bytes;
164			int pitchB;
165			int pitchP;
166			int sliceB;
167			int sliceP;
168			Format format;
169			Lock lock;
170
171			bool dirty;
172		};
173
174	public:
175		Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget);
176
177		virtual ~Surface();
178
179		inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false);
180		inline void unlock(bool internal = false);
181		inline int getWidth() const;
182		inline int getHeight() const;
183		inline int getDepth() const;
184		inline Format getFormat(bool internal = false) const;
185		inline int getPitchB(bool internal = false) const;
186		inline int getPitchP(bool internal = false) const;
187		inline int getSliceB(bool internal = false) const;
188		inline int getSliceP(bool internal = false) const;
189
190		void *lockExternal(int x, int y, int z, Lock lock, Accessor client);
191		void unlockExternal();
192		inline Format getExternalFormat() const;
193		inline int getExternalPitchB() const;
194		inline int getExternalPitchP() const;
195		inline int getExternalSliceB() const;
196		inline int getExternalSliceP() const;
197
198		virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client);
199		virtual void unlockInternal();
200		inline Format getInternalFormat() const;
201		inline int getInternalPitchB() const;
202		inline int getInternalPitchP() const;
203		inline int getInternalSliceB() const;
204		inline int getInternalSliceP() const;
205
206		void *lockStencil(int front, Accessor client);
207		void unlockStencil();
208		inline int getStencilPitchB() const;
209		inline int getStencilPitchP() const;
210		inline int getStencilSliceB() const;
211
212		inline int getMultiSampleCount() const;
213		inline int getSuperSampleCount() const;
214
215		void clearColorBuffer(unsigned int colorARGB, unsigned int rgbaMask, int x0, int y0, int width, int height);
216		void clearDepthBuffer(float depth, int x0, int y0, int width, int height);
217		void clearStencilBuffer(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height);
218		void fill(const Color<float> &color, int x0, int y0, int width, int height);
219
220		Color<float> readExternal(int x, int y, int z) const;
221		Color<float> readExternal(int x, int y) const;
222		Color<float> sampleExternal(float x, float y, float z) const;
223		Color<float> sampleExternal(float x, float y) const;
224		void writeExternal(int x, int y, int z, const Color<float> &color);
225		void writeExternal(int x, int y, const Color<float> &color);
226
227		Color<float> readInternal(int x, int y, int z) const;
228		Color<float> readInternal(int x, int y) const;
229		Color<float> sampleInternal(float x, float y, float z) const;
230		Color<float> sampleInternal(float x, float y) const;
231		void writeInternal(int x, int y, int z, const Color<float> &color);
232		void writeInternal(int x, int y, const Color<float> &color);
233
234		bool hasStencil() const;
235		bool hasDepth() const;
236		bool hasPalette() const;
237		bool isRenderTarget() const;
238
239		bool hasDirtyMipmaps() const;
240		void cleanMipmaps();
241		inline bool isExternalDirty() const;
242		Resource *getResource();
243
244		static int bytes(Format format);
245		static int pitchB(int width, Format format, bool target);
246		static int pitchP(int width, Format format, bool target);
247		static int sliceB(int width, int height, Format format, bool target);
248		static int sliceP(int width, int height, Format format, bool target);
249		static unsigned int size(int width, int height, int depth, Format format);   // FIXME: slice * depth
250
251		static bool isStencil(Format format);
252		static bool isDepth(Format format);
253		static bool isPalette(Format format);
254
255		static bool isFloatFormat(Format format);
256		static bool isUnsignedComponent(Format format, int component);
257		static bool isSRGBreadable(Format format);
258		static bool isSRGBwritable(Format format);
259		static bool isCompressed(Format format);
260		static int componentCount(Format format);
261
262		static void setTexturePalette(unsigned int *palette);
263
264	protected:
265		sw::Resource *resource;
266
267	private:
268		typedef unsigned char byte;
269		typedef unsigned short word;
270		typedef unsigned int dword;
271		typedef uint64_t qword;
272
273		#if S3TC_SUPPORT
274		struct DXT1
275		{
276			word c0;
277			word c1;
278			dword lut;
279		};
280
281		struct DXT3
282		{
283			qword a;
284
285			word c0;
286			word c1;
287			dword lut;
288		};
289
290		struct DXT5
291		{
292			union
293			{
294				struct
295				{
296					byte a0;
297					byte a1;
298				};
299
300				qword alut;   // Skip first 16 bit
301			};
302
303			word c0;
304			word c1;
305			dword clut;
306		};
307		#endif
308
309		struct ATI2
310		{
311			union
312			{
313				struct
314				{
315					byte y0;
316					byte y1;
317				};
318
319				qword ylut;   // Skip first 16 bit
320			};
321
322			union
323			{
324				struct
325				{
326					byte x0;
327					byte x1;
328				};
329
330				qword xlut;   // Skip first 16 bit
331			};
332		};
333
334		struct ATI1
335		{
336			union
337			{
338				struct
339				{
340					byte r0;
341					byte r1;
342				};
343
344				qword rlut;   // Skip first 16 bit
345			};
346		};
347
348		static void decodeR8G8B8(Buffer &destination, const Buffer &source);
349		static void decodeR5G6B5(Buffer &destination, const Buffer &source);
350		static void decodeX1R5G5B5(Buffer &destination, const Buffer &source);
351		static void decodeA1R5G5B5(Buffer &destination, const Buffer &source);
352		static void decodeX4R4G4B4(Buffer &destination, const Buffer &source);
353		static void decodeA4R4G4B4(Buffer &destination, const Buffer &source);
354		static void decodeP8(Buffer &destination, const Buffer &source);
355
356		#if S3TC_SUPPORT
357		static void decodeDXT1(Buffer &internal, const Buffer &external);
358		static void decodeDXT3(Buffer &internal, const Buffer &external);
359		static void decodeDXT5(Buffer &internal, const Buffer &external);
360		#endif
361		static void decodeATI1(Buffer &internal, const Buffer &external);
362		static void decodeATI2(Buffer &internal, const Buffer &external);
363		static void decodeETC1(Buffer &internal, const Buffer &external);
364
365		static void update(Buffer &destination, Buffer &source);
366		static void genericUpdate(Buffer &destination, Buffer &source);
367		static void *allocateBuffer(int width, int height, int depth, Format format);
368		static void memfill4(void *buffer, int pattern, int bytes);
369
370		bool identicalFormats() const;
371		Format selectInternalFormat(Format format) const;
372
373		void resolve();
374
375		Buffer external;
376		Buffer internal;
377		Buffer stencil;
378
379		const bool lockable;
380		const bool renderTarget;
381
382		bool dirtyMipmaps;
383		unsigned int paletteUsed;
384
385		static unsigned int *palette;   // FIXME: Not multi-device safe
386		static unsigned int paletteID;
387
388		bool hasParent;
389	};
390}
391
392#undef min
393#undef max
394
395namespace sw
396{
397	void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal)
398	{
399		return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client);
400	}
401
402	void Surface::unlock(bool internal)
403	{
404		return internal ? unlockInternal() : unlockExternal();
405	}
406
407	int Surface::getWidth() const
408	{
409		return external.width;
410	}
411
412	int Surface::getHeight() const
413	{
414		return external.height;
415	}
416
417	int Surface::getDepth() const
418	{
419		return external.depth;
420	}
421
422	Format Surface::getFormat(bool internal) const
423	{
424		return internal ? getInternalFormat() : getExternalFormat();
425	}
426
427	int Surface::getPitchB(bool internal) const
428	{
429		return internal ? getInternalPitchB() : getExternalPitchB();
430	}
431
432	int Surface::getPitchP(bool internal) const
433	{
434		return internal ? getInternalPitchP() : getExternalPitchB();
435	}
436
437	int Surface::getSliceB(bool internal) const
438	{
439		return internal ? getInternalSliceB() : getExternalSliceB();
440	}
441
442	int Surface::getSliceP(bool internal) const
443	{
444		return internal ? getInternalSliceP() : getExternalSliceB();
445	}
446
447	Format Surface::getExternalFormat() const
448	{
449		return external.format;
450	}
451
452	int Surface::getExternalPitchB() const
453	{
454		return external.pitchB;
455	}
456
457	int Surface::getExternalPitchP() const
458	{
459		return external.pitchP;
460	}
461
462	int Surface::getExternalSliceB() const
463	{
464		return external.sliceB;
465	}
466
467	int Surface::getExternalSliceP() const
468	{
469		return external.sliceP;
470	}
471
472	Format Surface::getInternalFormat() const
473	{
474		return internal.format;
475	}
476
477	int Surface::getInternalPitchB() const
478	{
479		return internal.pitchB;
480	}
481
482	int Surface::getInternalPitchP() const
483	{
484		return internal.pitchP;
485	}
486
487	int Surface::getInternalSliceB() const
488	{
489		return internal.sliceB;
490	}
491
492	int Surface::getInternalSliceP() const
493	{
494		return internal.sliceP;
495	}
496
497	int Surface::getStencilPitchB() const
498	{
499		return stencil.pitchB;
500	}
501
502	int Surface::getStencilPitchP() const
503	{
504		return stencil.pitchP;
505	}
506
507	int Surface::getStencilSliceB() const
508	{
509		return stencil.sliceB;
510	}
511
512	int Surface::getMultiSampleCount() const
513	{
514		return sw::min(internal.depth, 4);
515	}
516
517	int Surface::getSuperSampleCount() const
518	{
519		return internal.depth > 4 ? internal.depth / 4 : 1;
520	}
521
522	bool Surface::isExternalDirty() const
523	{
524		return external.buffer && external.buffer != internal.buffer && external.dirty;
525	}
526}
527
528#endif   // sw_Surface_hpp
529