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 "TextureStage.hpp"
     16 
     17 #include "Sampler.hpp"
     18 #include "Common/Debug.hpp"
     19 
     20 #include <string.h>
     21 
     22 namespace sw
     23 {
     24 	TextureStage::State::State()
     25 	{
     26 		memset(this, 0, sizeof(State));
     27 	}
     28 
     29 	TextureStage::TextureStage() : sampler(0), previousStage(0)
     30 	{
     31 	}
     32 
     33 	TextureStage::~TextureStage()
     34 	{
     35 	}
     36 
     37 	void TextureStage::init(int stage, const Sampler *sampler, const TextureStage *previousStage)
     38 	{
     39 		this->stage = stage;
     40 
     41 		stageOperation = (stage == 0 ? STAGE_MODULATE : STAGE_DISABLE);
     42 		firstArgument = SOURCE_TEXTURE;
     43 		secondArgument = SOURCE_CURRENT;
     44 		thirdArgument = SOURCE_CURRENT;
     45 		stageOperationAlpha = (stage == 0 ? STAGE_SELECTARG1 : STAGE_DISABLE);
     46 		firstArgumentAlpha = SOURCE_DIFFUSE;
     47 		secondArgumentAlpha = SOURCE_CURRENT;
     48 		thirdArgumentAlpha = SOURCE_CURRENT;
     49 		firstModifier = MODIFIER_COLOR;
     50 		secondModifier = MODIFIER_COLOR;
     51 		thirdModifier = MODIFIER_COLOR;
     52 	    firstModifierAlpha = MODIFIER_COLOR;
     53 		secondModifierAlpha = MODIFIER_COLOR;
     54 		thirdModifierAlpha = MODIFIER_COLOR;
     55 		destinationArgument = DESTINATION_CURRENT;
     56 
     57 		texCoordIndex = stage;
     58 		this->sampler = sampler;
     59 		this->previousStage = previousStage;
     60 	}
     61 
     62 	TextureStage::State TextureStage::textureStageState() const
     63 	{
     64 		State state;
     65 
     66 		if(!isStageDisabled())
     67 		{
     68 			state.stageOperation = stageOperation;
     69 			state.firstArgument = firstArgument;
     70 			state.secondArgument = secondArgument;
     71 			state.thirdArgument = thirdArgument;
     72 			state.stageOperationAlpha = stageOperationAlpha;
     73 			state.firstArgumentAlpha = firstArgumentAlpha;
     74 			state.secondArgumentAlpha = secondArgumentAlpha;
     75 			state.thirdArgumentAlpha = thirdArgumentAlpha;
     76 			state.firstModifier = firstModifier;
     77 			state.secondModifier = secondModifier;
     78 			state.thirdModifier = thirdModifier;
     79 			state.firstModifierAlpha = firstModifierAlpha;
     80 			state.secondModifierAlpha = secondModifierAlpha;
     81 			state.thirdModifierAlpha = thirdModifierAlpha;
     82 			state.destinationArgument = destinationArgument;
     83 			state.texCoordIndex = texCoordIndex;
     84 
     85 			state.cantUnderflow = sampler->hasUnsignedTexture() || !usesTexture();
     86 			state.usesTexture = usesTexture();
     87 		}
     88 
     89 		return state;
     90 	}
     91 
     92 	void TextureStage::setConstantColor(const Color<float> &constantColor)
     93 	{
     94 		// FIXME: Compact into generic function   // FIXME: Clamp
     95 		short r = iround(4095 * constantColor.r);
     96 		short g = iround(4095 * constantColor.g);
     97 		short b = iround(4095 * constantColor.b);
     98 		short a = iround(4095 * constantColor.a);
     99 
    100 		uniforms.constantColor4[0][0] = uniforms.constantColor4[0][1] = uniforms.constantColor4[0][2] = uniforms.constantColor4[0][3] = r;
    101 		uniforms.constantColor4[1][0] = uniforms.constantColor4[1][1] = uniforms.constantColor4[1][2] = uniforms.constantColor4[1][3] = g;
    102 		uniforms.constantColor4[2][0] = uniforms.constantColor4[2][1] = uniforms.constantColor4[2][2] = uniforms.constantColor4[2][3] = b;
    103 		uniforms.constantColor4[3][0] = uniforms.constantColor4[3][1] = uniforms.constantColor4[3][2] = uniforms.constantColor4[3][3] = a;
    104 	}
    105 
    106 	void TextureStage::setBumpmapMatrix(int element, float value)
    107 	{
    108 		uniforms.bumpmapMatrix4F[element / 2][element % 2][0] = value;
    109 		uniforms.bumpmapMatrix4F[element / 2][element % 2][1] = value;
    110 		uniforms.bumpmapMatrix4F[element / 2][element % 2][2] = value;
    111 		uniforms.bumpmapMatrix4F[element / 2][element % 2][3] = value;
    112 
    113 		uniforms.bumpmapMatrix4W[element / 2][element % 2][0] = iround(4095 * value);
    114 		uniforms.bumpmapMatrix4W[element / 2][element % 2][1] = iround(4095 * value);
    115 		uniforms.bumpmapMatrix4W[element / 2][element % 2][2] = iround(4095 * value);
    116 		uniforms.bumpmapMatrix4W[element / 2][element % 2][3] = iround(4095 * value);
    117 	}
    118 
    119 	void TextureStage::setLuminanceScale(float value)
    120 	{
    121 		short scale = iround(4095 * value);
    122 
    123 		uniforms.luminanceScale4[0] = uniforms.luminanceScale4[1] = uniforms.luminanceScale4[2] = uniforms.luminanceScale4[3] = scale;
    124 	}
    125 
    126 	void TextureStage::setLuminanceOffset(float value)
    127 	{
    128 		short offset = iround(4095 * value);
    129 
    130 		uniforms.luminanceOffset4[0] = uniforms.luminanceOffset4[1] = uniforms.luminanceOffset4[2] = uniforms.luminanceOffset4[3] = offset;
    131 	}
    132 
    133 	void TextureStage::setTexCoordIndex(unsigned int texCoordIndex)
    134 	{
    135 		ASSERT(texCoordIndex < 8);
    136 
    137 		this->texCoordIndex = texCoordIndex;
    138 	}
    139 
    140 	void TextureStage::setStageOperation(StageOperation stageOperation)
    141 	{
    142 		this->stageOperation = stageOperation;
    143 	}
    144 
    145 	void TextureStage::setFirstArgument(SourceArgument firstArgument)
    146 	{
    147 		this->firstArgument = firstArgument;
    148 	}
    149 
    150 	void TextureStage::setSecondArgument(SourceArgument secondArgument)
    151 	{
    152 		this->secondArgument = secondArgument;
    153 	}
    154 
    155 	void TextureStage::setThirdArgument(SourceArgument thirdArgument)
    156 	{
    157 		this->thirdArgument = thirdArgument;
    158 	}
    159 
    160 	void TextureStage::setStageOperationAlpha(StageOperation stageOperationAlpha)
    161 	{
    162 		this->stageOperationAlpha = stageOperationAlpha;
    163 	}
    164 
    165 	void TextureStage::setFirstArgumentAlpha(SourceArgument firstArgumentAlpha)
    166 	{
    167 		this->firstArgumentAlpha = firstArgumentAlpha;
    168 	}
    169 
    170 	void TextureStage::setSecondArgumentAlpha(SourceArgument secondArgumentAlpha)
    171 	{
    172 		this->secondArgumentAlpha = secondArgumentAlpha;
    173 	}
    174 
    175 	void TextureStage::setThirdArgumentAlpha(SourceArgument thirdArgumentAlpha)
    176 	{
    177 		this->thirdArgumentAlpha= thirdArgumentAlpha;
    178 	}
    179 
    180 	void TextureStage::setFirstModifier(ArgumentModifier firstModifier)
    181 	{
    182 		this->firstModifier = firstModifier;
    183 	}
    184 
    185 	void TextureStage::setSecondModifier(ArgumentModifier secondModifier)
    186 	{
    187 		this->secondModifier = secondModifier;
    188 	}
    189 
    190 	void TextureStage::setThirdModifier(ArgumentModifier thirdModifier)
    191 	{
    192 		this->thirdModifier = thirdModifier;
    193 	}
    194 
    195 	void TextureStage::setFirstModifierAlpha(ArgumentModifier firstModifierAlpha)
    196 	{
    197 		this->firstModifierAlpha = firstModifierAlpha;
    198 	}
    199 
    200 	void TextureStage::setSecondModifierAlpha(ArgumentModifier secondModifierAlpha)
    201 	{
    202 		this->secondModifierAlpha = secondModifierAlpha;
    203 	}
    204 
    205 	void TextureStage::setThirdModifierAlpha(ArgumentModifier thirdModifierAlpha)
    206 	{
    207 		this->thirdModifierAlpha = thirdModifierAlpha;
    208 	}
    209 
    210 	void TextureStage::setDestinationArgument(DestinationArgument destinationArgument)
    211 	{
    212 		this->destinationArgument = destinationArgument;
    213 	}
    214 
    215 	bool TextureStage::usesColor(SourceArgument source) const
    216 	{
    217 		// One argument
    218 		if(stageOperation == STAGE_SELECTARG1 || stageOperation == STAGE_PREMODULATE)
    219 		{
    220 			return firstArgument == source;
    221 		}
    222 		else if(stageOperation == STAGE_SELECTARG2)
    223 		{
    224 			return secondArgument == source;
    225 		}
    226 		else if(stageOperation == STAGE_SELECTARG3)
    227 		{
    228 			return thirdArgument == source;
    229 		}
    230 		else
    231 		{
    232 			// Two arguments or more
    233 			if(firstArgument == source || secondArgument == source)
    234 			{
    235 				return true;
    236 			}
    237 
    238 			// Three arguments
    239 			if(stageOperation == STAGE_MULTIPLYADD || stageOperation == STAGE_LERP)
    240 			{
    241 				return thirdArgument == source;
    242 			}
    243 		}
    244 
    245 		return false;
    246 	}
    247 
    248 	bool TextureStage::usesAlpha(SourceArgument source) const
    249 	{
    250 		if(stageOperationAlpha == STAGE_DISABLE)
    251 		{
    252 			return false;
    253 		}
    254 
    255 		if(source == SOURCE_TEXTURE)
    256 		{
    257 			if(stageOperation == STAGE_BLENDTEXTUREALPHA ||	stageOperation == STAGE_BLENDTEXTUREALPHAPM)
    258 			{
    259 				return true;
    260 			}
    261 		}
    262 		else if(source == SOURCE_CURRENT)
    263 		{
    264 			if(stageOperation == STAGE_BLENDCURRENTALPHA)
    265 			{
    266 				return true;
    267 			}
    268 		}
    269 		else if(source == SOURCE_DIFFUSE)
    270 		{
    271 			if(stageOperation == STAGE_BLENDDIFFUSEALPHA)
    272 			{
    273 				return true;
    274 			}
    275 		}
    276 		else if(source == SOURCE_TFACTOR)
    277 		{
    278 			if(stageOperation == STAGE_BLENDFACTORALPHA)
    279 			{
    280 				return true;
    281 			}
    282 		}
    283 
    284 		// One argument
    285 		if(stageOperation == STAGE_SELECTARG1 || stageOperation == STAGE_PREMODULATE)
    286 		{
    287 			if(firstArgument == source && (firstModifier == MODIFIER_ALPHA || firstModifier == MODIFIER_INVALPHA))
    288 			{
    289 				return true;
    290 			}
    291 		}
    292 		else if(stageOperation == STAGE_SELECTARG2)
    293 		{
    294 			if(secondArgument == source && (secondModifier == MODIFIER_ALPHA || secondModifier == MODIFIER_INVALPHA))
    295 			{
    296 				return true;
    297 			}
    298 		}
    299 		else if(stageOperation == STAGE_SELECTARG3)
    300 		{
    301 			if(thirdArgument == source && (thirdModifier == MODIFIER_ALPHA || thirdModifier == MODIFIER_INVALPHA))
    302 			{
    303 				return true;
    304 			}
    305 		}
    306 		else
    307 		{
    308 			// Two arguments or more
    309 			if(firstArgument == source || secondArgument == source)
    310 			{
    311 				if(firstArgument == source && (firstModifier == MODIFIER_ALPHA || firstModifier == MODIFIER_INVALPHA))
    312 				{
    313 					return true;
    314 				}
    315 
    316 				if(secondArgument == source && (secondModifier == MODIFIER_ALPHA || secondModifier == MODIFIER_INVALPHA))
    317 				{
    318 					return true;
    319 				}
    320 			}
    321 
    322 			// Three arguments
    323 			if(stageOperation == STAGE_MULTIPLYADD || stageOperation == STAGE_LERP)
    324 			{
    325 				if(thirdArgument == source && (thirdModifier == MODIFIER_ALPHA || thirdModifier == MODIFIER_INVALPHA))
    326 				{
    327 					return true;
    328 				}
    329 			}
    330 		}
    331 
    332 		// One argument
    333 		if(stageOperationAlpha == STAGE_SELECTARG1 || stageOperationAlpha == STAGE_PREMODULATE)
    334 		{
    335 			return firstArgumentAlpha == source;
    336 		}
    337 		else if(stageOperationAlpha == STAGE_SELECTARG2)
    338 		{
    339 			return secondArgumentAlpha == source;
    340 		}
    341 		else if(stageOperationAlpha == STAGE_SELECTARG3)
    342 		{
    343 			return thirdArgumentAlpha == source;
    344 		}
    345 		else
    346 		{
    347 			// Two arguments or more
    348 			if(firstArgumentAlpha == source || secondArgumentAlpha == source)
    349 			{
    350 				return true;
    351 			}
    352 
    353 			// Three arguments
    354 			if(stageOperationAlpha == STAGE_MULTIPLYADD || stageOperationAlpha == STAGE_LERP)
    355 			{
    356 				return thirdArgumentAlpha == source;
    357 			}
    358 		}
    359 
    360 		return false;
    361 	}
    362 
    363 	bool TextureStage::uses(SourceArgument source) const
    364 	{
    365 		return usesColor(source) || usesAlpha(source);
    366 	}
    367 
    368 	bool TextureStage::usesCurrent() const
    369 	{
    370 		return uses(SOURCE_CURRENT) || (stageOperation == STAGE_BLENDCURRENTALPHA || stageOperationAlpha == STAGE_BLENDCURRENTALPHA);
    371 	}
    372 
    373 	bool TextureStage::usesDiffuse() const
    374 	{
    375 		return uses(SOURCE_DIFFUSE) || (stageOperation == STAGE_BLENDDIFFUSEALPHA || stageOperationAlpha == STAGE_BLENDDIFFUSEALPHA);
    376 	}
    377 
    378 	bool TextureStage::usesSpecular() const
    379 	{
    380 		return uses(SOURCE_SPECULAR);
    381 	}
    382 
    383 	bool TextureStage::usesTexture() const
    384 	{
    385 		return uses(SOURCE_TEXTURE) ||
    386 		       stageOperation == STAGE_BLENDTEXTUREALPHA ||
    387 		       stageOperationAlpha == STAGE_BLENDTEXTUREALPHA ||
    388 		       stageOperation == STAGE_BLENDTEXTUREALPHAPM ||
    389 		       stageOperationAlpha == STAGE_BLENDTEXTUREALPHAPM ||
    390 		       (previousStage && previousStage->stageOperation == STAGE_PREMODULATE) ||
    391 		       (previousStage && previousStage->stageOperationAlpha == STAGE_PREMODULATE);
    392 	}
    393 
    394 	bool TextureStage::isStageDisabled() const
    395 	{
    396 		bool disabled = (stageOperation == STAGE_DISABLE) || (!sampler->hasTexture() && usesTexture());
    397 
    398 		if(!previousStage || disabled)
    399 		{
    400 			return disabled;
    401 		}
    402 		else
    403 		{
    404 			return previousStage->isStageDisabled();
    405 		}
    406 	}
    407 
    408 	bool TextureStage::writesCurrent() const
    409 	{
    410 		return !isStageDisabled() && destinationArgument == DESTINATION_CURRENT && stageOperation != STAGE_BUMPENVMAP && stageOperation != STAGE_BUMPENVMAPLUMINANCE;
    411 	}
    412 }
    413