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 #include "Sampler.hpp"
     16 
     17 #include "Context.hpp"
     18 #include "Surface.hpp"
     19 #include "CPUID.hpp"
     20 #include "PixelRoutine.hpp"
     21 #include "Debug.hpp"
     22 
     23 #include <memory.h>
     24 #include <string.h>
     25 
     26 namespace sw
     27 {
     28 	FilterType Sampler::maximumTextureFilterQuality = FILTER_LINEAR;
     29 	MipmapType Sampler::maximumMipmapFilterQuality = MIPMAP_POINT;
     30 
     31 	Sampler::State::State()
     32 	{
     33 		memset(this, 0, sizeof(State));
     34 	}
     35 
     36 	Sampler::Sampler()
     37 	{
     38 		// FIXME: Mipmap::init
     39 		static const unsigned int zero = 0x00FF00FF;
     40 
     41 		for(int level = 0; level < MIPMAP_LEVELS; level++)
     42 		{
     43 			Mipmap &mipmap = texture.mipmap[level];
     44 
     45 			memset(&mipmap, 0, sizeof(Mipmap));
     46 
     47 			for(int face = 0; face < 6; face++)
     48 			{
     49 				mipmap.buffer[face] = &zero;
     50 			}
     51 
     52 			mipmap.uFrac = 16;
     53 			mipmap.vFrac = 16;
     54 			mipmap.wFrac = 16;
     55 		}
     56 
     57 		externalTextureFormat = FORMAT_NULL;
     58 		internalTextureFormat = FORMAT_NULL;
     59 		textureType = TEXTURE_NULL;
     60 
     61 		textureFilter = FILTER_LINEAR;
     62 		addressingModeU = ADDRESSING_WRAP;
     63 		addressingModeV = ADDRESSING_WRAP;
     64 		addressingModeW = ADDRESSING_WRAP;
     65 		mipmapFilterState = MIPMAP_NONE;
     66 		sRGB = false;
     67 		gather = false;
     68 
     69 		swizzleR = SWIZZLE_RED;
     70 		swizzleG = SWIZZLE_GREEN;
     71 		swizzleB = SWIZZLE_BLUE;
     72 		swizzleA = SWIZZLE_ALPHA;
     73 
     74 		texture.LOD = 0.0f;
     75 		exp2LOD = 1.0f;
     76 	}
     77 
     78 	Sampler::~Sampler()
     79 	{
     80 	}
     81 
     82 	Sampler::State Sampler::samplerState() const
     83 	{
     84 		State state;
     85 
     86 		if(textureType != TEXTURE_NULL)
     87 		{
     88 			state.textureType = textureType;
     89 			state.textureFormat = internalTextureFormat;
     90 			state.textureFilter = getTextureFilter();
     91 			state.addressingModeU = getAddressingModeU();
     92 			state.addressingModeV = getAddressingModeV();
     93 			state.addressingModeW = getAddressingModeW();
     94 			state.mipmapFilter = mipmapFilter();
     95 			state.hasNPOTTexture = hasNPOTTexture();
     96 			state.sRGB = sRGB && Surface::isSRGBreadable(externalTextureFormat);
     97 			state.swizzleR = swizzleR;
     98 			state.swizzleG = swizzleG;
     99 			state.swizzleB = swizzleB;
    100 			state.swizzleA = swizzleA;
    101 
    102 			#if PERF_PROFILE
    103 				state.compressedFormat = Surface::isCompressed(externalTextureFormat);
    104 			#endif
    105 		}
    106 
    107 		return state;
    108 	}
    109 
    110 	void Sampler::setTextureLevel(int face, int level, Surface *surface, TextureType type)
    111 	{
    112 		if(surface)
    113 		{
    114 			Mipmap &mipmap = texture.mipmap[level];
    115 
    116 			mipmap.buffer[face] = surface->lockInternal(0, 0, 0, LOCK_UNLOCKED, PRIVATE);
    117 
    118 			if(face == 0)
    119 			{
    120 				externalTextureFormat = surface->getExternalFormat();
    121 				internalTextureFormat = surface->getInternalFormat();
    122 
    123 				int width = surface->getWidth();
    124 				int height = surface->getHeight();
    125 				int depth = surface->getDepth();
    126 				int pitchP = surface->getInternalPitchP();
    127 				int sliceP = surface->getInternalSliceP();
    128 
    129 				int logWidth = log2(width);
    130 				int logHeight = log2(height);
    131 				int logDepth = log2(depth);
    132 
    133 				if(level == 0)
    134 				{
    135 					texture.widthHeightLOD[0] = width * exp2LOD;
    136 					texture.widthHeightLOD[1] = width * exp2LOD;
    137 					texture.widthHeightLOD[2] = height * exp2LOD;
    138 					texture.widthHeightLOD[3] = height * exp2LOD;
    139 
    140 					texture.widthLOD[0] = width * exp2LOD;
    141 					texture.widthLOD[1] = width * exp2LOD;
    142 					texture.widthLOD[2] = width * exp2LOD;
    143 					texture.widthLOD[3] = width * exp2LOD;
    144 
    145 					texture.heightLOD[0] = height * exp2LOD;
    146 					texture.heightLOD[1] = height * exp2LOD;
    147 					texture.heightLOD[2] = height * exp2LOD;
    148 					texture.heightLOD[3] = height * exp2LOD;
    149 
    150 					texture.depthLOD[0] = depth * exp2LOD;
    151 					texture.depthLOD[1] = depth * exp2LOD;
    152 					texture.depthLOD[2] = depth * exp2LOD;
    153 					texture.depthLOD[3] = depth * exp2LOD;
    154 				}
    155 
    156 				if(!Surface::isFloatFormat(internalTextureFormat))
    157 				{
    158 					mipmap.uInt = logWidth;
    159 					mipmap.vInt = logHeight;
    160 					mipmap.wInt = logDepth;
    161 					mipmap.uFrac = 16 - logWidth;
    162 					mipmap.vFrac = 16 - logHeight;
    163 					mipmap.wFrac = 16 - logDepth;
    164 				}
    165 				else
    166 				{
    167 					mipmap.fWidth[0] = (float)width / 65536.0f;
    168 					mipmap.fWidth[1] = (float)width / 65536.0f;
    169 					mipmap.fWidth[2] = (float)width / 65536.0f;
    170 					mipmap.fWidth[3] = (float)width / 65536.0f;
    171 
    172 					mipmap.fHeight[0] = (float)height / 65536.0f;
    173 					mipmap.fHeight[1] = (float)height / 65536.0f;
    174 					mipmap.fHeight[2] = (float)height / 65536.0f;
    175 					mipmap.fHeight[3] = (float)height / 65536.0f;
    176 
    177 					mipmap.fDepth[0] = (float)depth / 65536.0f;
    178 					mipmap.fDepth[1] = (float)depth / 65536.0f;
    179 					mipmap.fDepth[2] = (float)depth / 65536.0f;
    180 					mipmap.fDepth[3] = (float)depth / 65536.0f;
    181 				}
    182 
    183 				short halfTexelU = 0x8000 / width;
    184 				short halfTexelV = 0x8000 / height;
    185 				short halfTexelW = 0x8000 / depth;
    186 
    187 				mipmap.uHalf[0] = halfTexelU;
    188 				mipmap.uHalf[1] = halfTexelU;
    189 				mipmap.uHalf[2] = halfTexelU;
    190 				mipmap.uHalf[3] = halfTexelU;
    191 
    192 				mipmap.vHalf[0] = halfTexelV;
    193 				mipmap.vHalf[1] = halfTexelV;
    194 				mipmap.vHalf[2] = halfTexelV;
    195 				mipmap.vHalf[3] = halfTexelV;
    196 
    197 				mipmap.wHalf[0] = halfTexelW;
    198 				mipmap.wHalf[1] = halfTexelW;
    199 				mipmap.wHalf[2] = halfTexelW;
    200 				mipmap.wHalf[3] = halfTexelW;
    201 
    202 				mipmap.width[0] = width;
    203 				mipmap.width[1] = width;
    204 				mipmap.width[2] = width;
    205 				mipmap.width[3] = width;
    206 
    207 				mipmap.height[0] = height;
    208 				mipmap.height[1] = height;
    209 				mipmap.height[2] = height;
    210 				mipmap.height[3] = height;
    211 
    212 				mipmap.depth[0] = depth;
    213 				mipmap.depth[1] = depth;
    214 				mipmap.depth[2] = depth;
    215 				mipmap.depth[3] = depth;
    216 
    217 				mipmap.onePitchP[0] = 1;
    218 				mipmap.onePitchP[1] = pitchP;
    219 				mipmap.onePitchP[2] = 1;
    220 				mipmap.onePitchP[3] = pitchP;
    221 
    222 				mipmap.sliceP[0] = sliceP;
    223 				mipmap.sliceP[1] = sliceP;
    224 
    225 				if(internalTextureFormat == FORMAT_YV12_BT601 ||
    226 				   internalTextureFormat == FORMAT_YV12_BT709 ||
    227 				   internalTextureFormat == FORMAT_YV12_JFIF)
    228 				{
    229 					unsigned int YStride = pitchP;
    230 					unsigned int YSize = YStride * height;
    231 					unsigned int CStride = align(YStride / 2, 16);
    232 					unsigned int CSize = CStride * height / 2;
    233 
    234 					mipmap.buffer[1] = (byte*)mipmap.buffer[0] + YSize;
    235 					mipmap.buffer[2] = (byte*)mipmap.buffer[1] + CSize;
    236 
    237 					texture.mipmap[1].uFrac = texture.mipmap[0].uFrac + 1;
    238 					texture.mipmap[1].vFrac = texture.mipmap[0].vFrac + 1;
    239 					texture.mipmap[1].width[0] = width / 2;
    240 					texture.mipmap[1].width[1] = width / 2;
    241 					texture.mipmap[1].width[2] = width / 2;
    242 					texture.mipmap[1].width[3] = width / 2;
    243 					texture.mipmap[1].height[0] = height / 2;
    244 					texture.mipmap[1].height[1] = height / 2;
    245 					texture.mipmap[1].height[2] = height / 2;
    246 					texture.mipmap[1].height[3] = height / 2;
    247 					texture.mipmap[1].onePitchP[0] = 1;
    248 					texture.mipmap[1].onePitchP[1] = CStride;
    249 					texture.mipmap[1].onePitchP[2] = 1;
    250 					texture.mipmap[1].onePitchP[3] = CStride;
    251 				}
    252 			}
    253 		}
    254 
    255 		textureType = type;
    256 	}
    257 
    258 	void Sampler::setTextureFilter(FilterType textureFilter)
    259 	{
    260 		this->textureFilter = (FilterType)min(textureFilter, maximumTextureFilterQuality);
    261 	}
    262 
    263 	void Sampler::setMipmapFilter(MipmapType mipmapFilter)
    264 	{
    265 		mipmapFilterState = (MipmapType)min(mipmapFilter, maximumMipmapFilterQuality);
    266 	}
    267 
    268 	void Sampler::setGatherEnable(bool enable)
    269 	{
    270 		gather = enable;
    271 	}
    272 
    273 	void Sampler::setAddressingModeU(AddressingMode addressingMode)
    274 	{
    275 		addressingModeU = addressingMode;
    276 	}
    277 
    278 	void Sampler::setAddressingModeV(AddressingMode addressingMode)
    279 	{
    280 		addressingModeV = addressingMode;
    281 	}
    282 
    283 	void Sampler::setAddressingModeW(AddressingMode addressingMode)
    284 	{
    285 		addressingModeW = addressingMode;
    286 	}
    287 
    288 	void Sampler::setReadSRGB(bool sRGB)
    289 	{
    290 		this->sRGB = sRGB;
    291 	}
    292 
    293 	void Sampler::setBorderColor(const Color<float> &borderColor)
    294 	{
    295 		// FIXME: Compact into generic function   // FIXME: Clamp
    296 		short r = iround(0xFFFF * borderColor.r);
    297 		short g = iround(0xFFFF * borderColor.g);
    298 		short b = iround(0xFFFF * borderColor.b);
    299 		short a = iround(0xFFFF * borderColor.a);
    300 
    301 		texture.borderColor4[0][0] = texture.borderColor4[0][1] = texture.borderColor4[0][2] = texture.borderColor4[0][3] = r;
    302 		texture.borderColor4[1][0] = texture.borderColor4[1][1] = texture.borderColor4[1][2] = texture.borderColor4[1][3] = g;
    303 		texture.borderColor4[2][0] = texture.borderColor4[2][1] = texture.borderColor4[2][2] = texture.borderColor4[2][3] = b;
    304 		texture.borderColor4[3][0] = texture.borderColor4[3][1] = texture.borderColor4[3][2] = texture.borderColor4[3][3] = a;
    305 
    306 		texture.borderColorF[0][0] = texture.borderColorF[0][1] = texture.borderColorF[0][2] = texture.borderColorF[0][3] = borderColor.r;
    307 		texture.borderColorF[1][0] = texture.borderColorF[1][1] = texture.borderColorF[1][2] = texture.borderColorF[1][3] = borderColor.g;
    308 		texture.borderColorF[2][0] = texture.borderColorF[2][1] = texture.borderColorF[2][2] = texture.borderColorF[2][3] = borderColor.b;
    309 		texture.borderColorF[3][0] = texture.borderColorF[3][1] = texture.borderColorF[3][2] = texture.borderColorF[3][3] = borderColor.a;
    310 	}
    311 
    312 	void Sampler::setMaxAnisotropy(float maxAnisotropy)
    313 	{
    314 		texture.maxAnisotropy = maxAnisotropy;
    315 	}
    316 
    317 	void Sampler::setSwizzleR(SwizzleType swizzleR)
    318 	{
    319 		this->swizzleR = swizzleR;
    320 	}
    321 
    322 	void Sampler::setSwizzleG(SwizzleType swizzleG)
    323 	{
    324 		this->swizzleG = swizzleG;
    325 	}
    326 
    327 	void Sampler::setSwizzleB(SwizzleType swizzleB)
    328 	{
    329 		this->swizzleB = swizzleB;
    330 	}
    331 
    332 	void Sampler::setSwizzleA(SwizzleType swizzleA)
    333 	{
    334 		this->swizzleA = swizzleA;
    335 	}
    336 
    337 	void Sampler::setFilterQuality(FilterType maximumFilterQuality)
    338 	{
    339 		Sampler::maximumTextureFilterQuality = maximumFilterQuality;
    340 	}
    341 
    342 	void Sampler::setMipmapQuality(MipmapType maximumFilterQuality)
    343 	{
    344 		Sampler::maximumMipmapFilterQuality = maximumFilterQuality;
    345 	}
    346 
    347 	void Sampler::setMipmapLOD(float LOD)
    348 	{
    349 		texture.LOD = LOD;
    350 		exp2LOD = exp2(LOD);
    351 	}
    352 
    353 	bool Sampler::hasTexture() const
    354 	{
    355 		return textureType != TEXTURE_NULL;
    356 	}
    357 
    358 	bool Sampler::hasUnsignedTexture() const
    359 	{
    360 		return Surface::isUnsignedComponent(internalTextureFormat, 0) &&
    361 		       Surface::isUnsignedComponent(internalTextureFormat, 1) &&
    362 		       Surface::isUnsignedComponent(internalTextureFormat, 2) &&
    363 		       Surface::isUnsignedComponent(internalTextureFormat, 3);
    364 	}
    365 
    366 	bool Sampler::hasCubeTexture() const
    367 	{
    368 		return textureType == TEXTURE_CUBE;
    369 	}
    370 
    371 	bool Sampler::hasVolumeTexture() const
    372 	{
    373 		return textureType == TEXTURE_3D || textureType == TEXTURE_2D_ARRAY;
    374 	}
    375 
    376 	const Texture &Sampler::getTextureData()
    377 	{
    378 		return texture;
    379 	}
    380 
    381 	MipmapType Sampler::mipmapFilter() const
    382 	{
    383 		if(mipmapFilterState != MIPMAP_NONE)
    384 		{
    385 			for(int i = 1; i < MIPMAP_LEVELS; i++)
    386 			{
    387 				if(texture.mipmap[0].buffer[0] != texture.mipmap[i].buffer[0])
    388 				{
    389 					return mipmapFilterState;
    390 				}
    391 			}
    392 		}
    393 
    394 		// Only one mipmap level
    395 		return MIPMAP_NONE;
    396 	}
    397 
    398 	bool Sampler::hasNPOTTexture() const
    399 	{
    400 		if(textureType == TEXTURE_NULL)
    401 		{
    402 			return false;
    403 		}
    404 
    405 		for(int i = 0; i < MIPMAP_LEVELS; i++)
    406 		{
    407 			if(texture.mipmap[i].width[0] != texture.mipmap[i].onePitchP[1])
    408 			{
    409 				return true;   // Shifting of the texture coordinates doesn't yield the correct address, so using multiply by pitch
    410 			}
    411 		}
    412 
    413 		return !isPow2(texture.mipmap[0].width[0]) || !isPow2(texture.mipmap[0].height[0]) || !isPow2(texture.mipmap[0].depth[0]);
    414 	}
    415 
    416 	TextureType Sampler::getTextureType() const
    417 	{
    418 		return textureType;
    419 	}
    420 
    421 	FilterType Sampler::getTextureFilter() const
    422 	{
    423 		FilterType filter = textureFilter;
    424 
    425 		if(gather && Surface::componentCount(internalTextureFormat) == 1)
    426 		{
    427 			filter = FILTER_GATHER;
    428 		}
    429 
    430 		if(textureType != TEXTURE_2D || texture.maxAnisotropy == 1.0f)
    431 		{
    432 			return (FilterType)min(filter, FILTER_LINEAR);
    433 		}
    434 
    435 		return filter;
    436 	}
    437 
    438 	AddressingMode Sampler::getAddressingModeU() const
    439 	{
    440 		if(hasCubeTexture())
    441 		{
    442 			return ADDRESSING_CLAMP;
    443 		}
    444 
    445 		return addressingModeU;
    446 	}
    447 
    448 	AddressingMode Sampler::getAddressingModeV() const
    449 	{
    450 		if(hasCubeTexture())
    451 		{
    452 			return ADDRESSING_CLAMP;
    453 		}
    454 
    455 		return addressingModeV;
    456 	}
    457 
    458 	AddressingMode Sampler::getAddressingModeW() const
    459 	{
    460 		if(hasCubeTexture())
    461 		{
    462 			return ADDRESSING_CLAMP;
    463 		}
    464 
    465 		if(textureType == TEXTURE_2D_ARRAY || textureType == TEXTURE_2D)
    466 		{
    467 			return ADDRESSING_LAYER;
    468 		}
    469 
    470 		return addressingModeW;
    471 	}
    472 }
    473