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