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