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 "PixelProcessor.hpp"
     16 
     17 #include "Surface.hpp"
     18 #include "Primitive.hpp"
     19 #include "Shader/PixelPipeline.hpp"
     20 #include "Shader/PixelProgram.hpp"
     21 #include "Shader/PixelShader.hpp"
     22 #include "Shader/Constants.hpp"
     23 #include "Common/Debug.hpp"
     24 
     25 #include <string.h>
     26 
     27 namespace sw
     28 {
     29 	extern bool complementaryDepthBuffer;
     30 	extern TransparencyAntialiasing transparencyAntialiasing;
     31 	extern bool perspectiveCorrection;
     32 
     33 	bool precachePixel = false;
     34 
     35 	unsigned int PixelProcessor::States::computeHash()
     36 	{
     37 		unsigned int *state = (unsigned int*)this;
     38 		unsigned int hash = 0;
     39 
     40 		for(unsigned int i = 0; i < sizeof(States) / 4; i++)
     41 		{
     42 			hash ^= state[i];
     43 		}
     44 
     45 		return hash;
     46 	}
     47 
     48 	PixelProcessor::State::State()
     49 	{
     50 		memset(this, 0, sizeof(State));
     51 	}
     52 
     53 	bool PixelProcessor::State::operator==(const State &state) const
     54 	{
     55 		if(hash != state.hash)
     56 		{
     57 			return false;
     58 		}
     59 
     60 		return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
     61 	}
     62 
     63 	PixelProcessor::UniformBufferInfo::UniformBufferInfo()
     64 	{
     65 		buffer = nullptr;
     66 		offset = 0;
     67 	}
     68 
     69 	PixelProcessor::PixelProcessor(Context *context) : context(context)
     70 	{
     71 		setGlobalMipmapBias(0.0f);   // Round to highest LOD [0.5, 1.0]: -0.5
     72 		                             // Round to nearest LOD [0.7, 1.4]:  0.0
     73 		                             // Round to lowest LOD  [1.0, 2.0]:  0.5
     74 
     75 		routineCache = 0;
     76 		setRoutineCacheSize(1024);
     77 	}
     78 
     79 	PixelProcessor::~PixelProcessor()
     80 	{
     81 		delete routineCache;
     82 		routineCache = 0;
     83 	}
     84 
     85 	void PixelProcessor::setFloatConstant(unsigned int index, const float value[4])
     86 	{
     87 		if(index < FRAGMENT_UNIFORM_VECTORS)
     88 		{
     89 			c[index][0] = value[0];
     90 			c[index][1] = value[1];
     91 			c[index][2] = value[2];
     92 			c[index][3] = value[3];
     93 		}
     94 		else ASSERT(false);
     95 
     96 		if(index < 8)   // ps_1_x constants
     97 		{
     98 			// FIXME: Compact into generic function
     99 			short x = iround(4095 * clamp(value[0], -1.0f, 1.0f));
    100 			short y = iround(4095 * clamp(value[1], -1.0f, 1.0f));
    101 			short z = iround(4095 * clamp(value[2], -1.0f, 1.0f));
    102 			short w = iround(4095 * clamp(value[3], -1.0f, 1.0f));
    103 
    104 			cW[index][0][0] = x;
    105 			cW[index][0][1] = x;
    106 			cW[index][0][2] = x;
    107 			cW[index][0][3] = x;
    108 
    109 			cW[index][1][0] = y;
    110 			cW[index][1][1] = y;
    111 			cW[index][1][2] = y;
    112 			cW[index][1][3] = y;
    113 
    114 			cW[index][2][0] = z;
    115 			cW[index][2][1] = z;
    116 			cW[index][2][2] = z;
    117 			cW[index][2][3] = z;
    118 
    119 			cW[index][3][0] = w;
    120 			cW[index][3][1] = w;
    121 			cW[index][3][2] = w;
    122 			cW[index][3][3] = w;
    123 		}
    124 	}
    125 
    126 	void PixelProcessor::setIntegerConstant(unsigned int index, const int value[4])
    127 	{
    128 		if(index < 16)
    129 		{
    130 			i[index][0] = value[0];
    131 			i[index][1] = value[1];
    132 			i[index][2] = value[2];
    133 			i[index][3] = value[3];
    134 		}
    135 		else ASSERT(false);
    136 	}
    137 
    138 	void PixelProcessor::setBooleanConstant(unsigned int index, int boolean)
    139 	{
    140 		if(index < 16)
    141 		{
    142 			b[index] = boolean != 0;
    143 		}
    144 		else ASSERT(false);
    145 	}
    146 
    147 	void PixelProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
    148 	{
    149 		uniformBufferInfo[index].buffer = buffer;
    150 		uniformBufferInfo[index].offset = offset;
    151 	}
    152 
    153 	void PixelProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[])
    154 	{
    155 		for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
    156 		{
    157 			u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr;
    158 			uniformBuffers[i] = uniformBufferInfo[i].buffer;
    159 		}
    160 	}
    161 
    162 	void PixelProcessor::setRenderTarget(int index, Surface *renderTarget, unsigned int layer)
    163 	{
    164 		context->renderTarget[index] = renderTarget;
    165 		context->renderTargetLayer[index] = layer;
    166 	}
    167 
    168 	void PixelProcessor::setDepthBuffer(Surface *depthBuffer, unsigned int layer)
    169 	{
    170 		context->depthBuffer = depthBuffer;
    171 		context->depthBufferLayer = layer;
    172 	}
    173 
    174 	void PixelProcessor::setStencilBuffer(Surface *stencilBuffer, unsigned int layer)
    175 	{
    176 		context->stencilBuffer = stencilBuffer;
    177 		context->stencilBufferLayer = layer;
    178 	}
    179 
    180 	void PixelProcessor::setTexCoordIndex(unsigned int stage, int texCoordIndex)
    181 	{
    182 		if(stage < 8)
    183 		{
    184 			context->textureStage[stage].setTexCoordIndex(texCoordIndex);
    185 		}
    186 		else ASSERT(false);
    187 	}
    188 
    189 	void PixelProcessor::setStageOperation(unsigned int stage, TextureStage::StageOperation stageOperation)
    190 	{
    191 		if(stage < 8)
    192 		{
    193 			context->textureStage[stage].setStageOperation(stageOperation);
    194 		}
    195 		else ASSERT(false);
    196 	}
    197 
    198 	void PixelProcessor::setFirstArgument(unsigned int stage, TextureStage::SourceArgument firstArgument)
    199 	{
    200 		if(stage < 8)
    201 		{
    202 			context->textureStage[stage].setFirstArgument(firstArgument);
    203 		}
    204 		else ASSERT(false);
    205 	}
    206 
    207 	void PixelProcessor::setSecondArgument(unsigned int stage, TextureStage::SourceArgument secondArgument)
    208 	{
    209 		if(stage < 8)
    210 		{
    211 			context->textureStage[stage].setSecondArgument(secondArgument);
    212 		}
    213 		else ASSERT(false);
    214 	}
    215 
    216 	void PixelProcessor::setThirdArgument(unsigned int stage, TextureStage::SourceArgument thirdArgument)
    217 	{
    218 		if(stage < 8)
    219 		{
    220 			context->textureStage[stage].setThirdArgument(thirdArgument);
    221 		}
    222 		else ASSERT(false);
    223 	}
    224 
    225 	void PixelProcessor::setStageOperationAlpha(unsigned int stage, TextureStage::StageOperation stageOperationAlpha)
    226 	{
    227 		if(stage < 8)
    228 		{
    229 			context->textureStage[stage].setStageOperationAlpha(stageOperationAlpha);
    230 		}
    231 		else ASSERT(false);
    232 	}
    233 
    234 	void PixelProcessor::setFirstArgumentAlpha(unsigned int stage, TextureStage::SourceArgument firstArgumentAlpha)
    235 	{
    236 		if(stage < 8)
    237 		{
    238 			context->textureStage[stage].setFirstArgumentAlpha(firstArgumentAlpha);
    239 		}
    240 		else ASSERT(false);
    241 	}
    242 
    243 	void PixelProcessor::setSecondArgumentAlpha(unsigned int stage, TextureStage::SourceArgument secondArgumentAlpha)
    244 	{
    245 		if(stage < 8)
    246 		{
    247 			context->textureStage[stage].setSecondArgumentAlpha(secondArgumentAlpha);
    248 		}
    249 		else ASSERT(false);
    250 	}
    251 
    252 	void PixelProcessor::setThirdArgumentAlpha(unsigned int stage, TextureStage::SourceArgument thirdArgumentAlpha)
    253 	{
    254 		if(stage < 8)
    255 		{
    256 			context->textureStage[stage].setThirdArgumentAlpha(thirdArgumentAlpha);
    257 		}
    258 		else ASSERT(false);
    259 	}
    260 
    261 	void PixelProcessor::setFirstModifier(unsigned int stage, TextureStage::ArgumentModifier firstModifier)
    262 	{
    263 		if(stage < 8)
    264 		{
    265 			context->textureStage[stage].setFirstModifier(firstModifier);
    266 		}
    267 		else ASSERT(false);
    268 	}
    269 
    270 	void PixelProcessor::setSecondModifier(unsigned int stage, TextureStage::ArgumentModifier secondModifier)
    271 	{
    272 		if(stage < 8)
    273 		{
    274 			context->textureStage[stage].setSecondModifier(secondModifier);
    275 		}
    276 		else ASSERT(false);
    277 	}
    278 
    279 	void PixelProcessor::setThirdModifier(unsigned int stage, TextureStage::ArgumentModifier thirdModifier)
    280 	{
    281 		if(stage < 8)
    282 		{
    283 			context->textureStage[stage].setThirdModifier(thirdModifier);
    284 		}
    285 		else ASSERT(false);
    286 	}
    287 
    288 	void PixelProcessor::setFirstModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier firstModifierAlpha)
    289 	{
    290 		if(stage < 8)
    291 		{
    292 			context->textureStage[stage].setFirstModifierAlpha(firstModifierAlpha);
    293 		}
    294 		else ASSERT(false);
    295 	}
    296 
    297 	void PixelProcessor::setSecondModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier secondModifierAlpha)
    298 	{
    299 		if(stage < 8)
    300 		{
    301 			context->textureStage[stage].setSecondModifierAlpha(secondModifierAlpha);
    302 		}
    303 		else ASSERT(false);
    304 	}
    305 
    306 	void PixelProcessor::setThirdModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier thirdModifierAlpha)
    307 	{
    308 		if(stage < 8)
    309 		{
    310 			context->textureStage[stage].setThirdModifierAlpha(thirdModifierAlpha);
    311 		}
    312 		else ASSERT(false);
    313 	}
    314 
    315 	void PixelProcessor::setDestinationArgument(unsigned int stage, TextureStage::DestinationArgument destinationArgument)
    316 	{
    317 		if(stage < 8)
    318 		{
    319 			context->textureStage[stage].setDestinationArgument(destinationArgument);
    320 		}
    321 		else ASSERT(false);
    322 	}
    323 
    324 	void PixelProcessor::setConstantColor(unsigned int stage, const Color<float> &constantColor)
    325 	{
    326 		if(stage < 8)
    327 		{
    328 			context->textureStage[stage].setConstantColor(constantColor);
    329 		}
    330 		else ASSERT(false);
    331 	}
    332 
    333 	void PixelProcessor::setBumpmapMatrix(unsigned int stage, int element, float value)
    334 	{
    335 		if(stage < 8)
    336 		{
    337 			context->textureStage[stage].setBumpmapMatrix(element, value);
    338 		}
    339 		else ASSERT(false);
    340 	}
    341 
    342 	void PixelProcessor::setLuminanceScale(unsigned int stage, float value)
    343 	{
    344 		if(stage < 8)
    345 		{
    346 			context->textureStage[stage].setLuminanceScale(value);
    347 		}
    348 		else ASSERT(false);
    349 	}
    350 
    351 	void PixelProcessor::setLuminanceOffset(unsigned int stage, float value)
    352 	{
    353 		if(stage < 8)
    354 		{
    355 			context->textureStage[stage].setLuminanceOffset(value);
    356 		}
    357 		else ASSERT(false);
    358 	}
    359 
    360 	void PixelProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
    361 	{
    362 		if(sampler < TEXTURE_IMAGE_UNITS)
    363 		{
    364 			context->sampler[sampler].setTextureFilter(textureFilter);
    365 		}
    366 		else ASSERT(false);
    367 	}
    368 
    369 	void PixelProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
    370 	{
    371 		if(sampler < TEXTURE_IMAGE_UNITS)
    372 		{
    373 			context->sampler[sampler].setMipmapFilter(mipmapFilter);
    374 		}
    375 		else ASSERT(false);
    376 	}
    377 
    378 	void PixelProcessor::setGatherEnable(unsigned int sampler, bool enable)
    379 	{
    380 		if(sampler < TEXTURE_IMAGE_UNITS)
    381 		{
    382 			context->sampler[sampler].setGatherEnable(enable);
    383 		}
    384 		else ASSERT(false);
    385 	}
    386 
    387 	void PixelProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
    388 	{
    389 		if(sampler < TEXTURE_IMAGE_UNITS)
    390 		{
    391 			context->sampler[sampler].setAddressingModeU(addressMode);
    392 		}
    393 		else ASSERT(false);
    394 	}
    395 
    396 	void PixelProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
    397 	{
    398 		if(sampler < TEXTURE_IMAGE_UNITS)
    399 		{
    400 			context->sampler[sampler].setAddressingModeV(addressMode);
    401 		}
    402 		else ASSERT(false);
    403 	}
    404 
    405 	void PixelProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
    406 	{
    407 		if(sampler < TEXTURE_IMAGE_UNITS)
    408 		{
    409 			context->sampler[sampler].setAddressingModeW(addressMode);
    410 		}
    411 		else ASSERT(false);
    412 	}
    413 
    414 	void PixelProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
    415 	{
    416 		if(sampler < TEXTURE_IMAGE_UNITS)
    417 		{
    418 			context->sampler[sampler].setReadSRGB(sRGB);
    419 		}
    420 		else ASSERT(false);
    421 	}
    422 
    423 	void PixelProcessor::setMipmapLOD(unsigned int sampler, float bias)
    424 	{
    425 		if(sampler < TEXTURE_IMAGE_UNITS)
    426 		{
    427 			context->sampler[sampler].setMipmapLOD(bias);
    428 		}
    429 		else ASSERT(false);
    430 	}
    431 
    432 	void PixelProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
    433 	{
    434 		if(sampler < TEXTURE_IMAGE_UNITS)
    435 		{
    436 			context->sampler[sampler].setBorderColor(borderColor);
    437 		}
    438 		else ASSERT(false);
    439 	}
    440 
    441 	void PixelProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
    442 	{
    443 		if(sampler < TEXTURE_IMAGE_UNITS)
    444 		{
    445 			context->sampler[sampler].setMaxAnisotropy(maxAnisotropy);
    446 		}
    447 		else ASSERT(false);
    448 	}
    449 
    450 	void PixelProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
    451 	{
    452 		if(sampler < TEXTURE_IMAGE_UNITS)
    453 		{
    454 			context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
    455 		}
    456 		else ASSERT(false);
    457 	}
    458 
    459 	void PixelProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
    460 	{
    461 		if(sampler < TEXTURE_IMAGE_UNITS)
    462 		{
    463 			context->sampler[sampler].setSwizzleR(swizzleR);
    464 		}
    465 		else ASSERT(false);
    466 	}
    467 
    468 	void PixelProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
    469 	{
    470 		if(sampler < TEXTURE_IMAGE_UNITS)
    471 		{
    472 			context->sampler[sampler].setSwizzleG(swizzleG);
    473 		}
    474 		else ASSERT(false);
    475 	}
    476 
    477 	void PixelProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
    478 	{
    479 		if(sampler < TEXTURE_IMAGE_UNITS)
    480 		{
    481 			context->sampler[sampler].setSwizzleB(swizzleB);
    482 		}
    483 		else ASSERT(false);
    484 	}
    485 
    486 	void PixelProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
    487 	{
    488 		if(sampler < TEXTURE_IMAGE_UNITS)
    489 		{
    490 			context->sampler[sampler].setSwizzleA(swizzleA);
    491 		}
    492 		else ASSERT(false);
    493 	}
    494 
    495 	void PixelProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
    496 	{
    497 		if(sampler < TEXTURE_IMAGE_UNITS)
    498 		{
    499 			context->sampler[sampler].setCompareFunc(compFunc);
    500 		}
    501 		else ASSERT(false);
    502 	}
    503 
    504 	void PixelProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
    505 	{
    506 		if(sampler < TEXTURE_IMAGE_UNITS)
    507 		{
    508 			context->sampler[sampler].setBaseLevel(baseLevel);
    509 		}
    510 		else ASSERT(false);
    511 	}
    512 
    513 	void PixelProcessor::setMaxLevel(unsigned int sampler, int maxLevel)
    514 	{
    515 		if(sampler < TEXTURE_IMAGE_UNITS)
    516 		{
    517 			context->sampler[sampler].setMaxLevel(maxLevel);
    518 		}
    519 		else ASSERT(false);
    520 	}
    521 
    522 	void PixelProcessor::setMinLod(unsigned int sampler, float minLod)
    523 	{
    524 		if(sampler < TEXTURE_IMAGE_UNITS)
    525 		{
    526 			context->sampler[sampler].setMinLod(minLod);
    527 		}
    528 		else ASSERT(false);
    529 	}
    530 
    531 	void PixelProcessor::setMaxLod(unsigned int sampler, float maxLod)
    532 	{
    533 		if(sampler < TEXTURE_IMAGE_UNITS)
    534 		{
    535 			context->sampler[sampler].setMaxLod(maxLod);
    536 		}
    537 		else ASSERT(false);
    538 	}
    539 
    540 	void PixelProcessor::setWriteSRGB(bool sRGB)
    541 	{
    542 		context->setWriteSRGB(sRGB);
    543 	}
    544 
    545 	void PixelProcessor::setColorLogicOpEnabled(bool colorLogicOpEnabled)
    546 	{
    547 		context->setColorLogicOpEnabled(colorLogicOpEnabled);
    548 	}
    549 
    550 	void PixelProcessor::setLogicalOperation(LogicalOperation logicalOperation)
    551 	{
    552 		context->setLogicalOperation(logicalOperation);
    553 	}
    554 
    555 	void PixelProcessor::setDepthBufferEnable(bool depthBufferEnable)
    556 	{
    557 		context->setDepthBufferEnable(depthBufferEnable);
    558 	}
    559 
    560 	void PixelProcessor::setDepthCompare(DepthCompareMode depthCompareMode)
    561 	{
    562 		context->depthCompareMode = depthCompareMode;
    563 	}
    564 
    565 	void PixelProcessor::setAlphaCompare(AlphaCompareMode alphaCompareMode)
    566 	{
    567 		context->alphaCompareMode = alphaCompareMode;
    568 	}
    569 
    570 	void PixelProcessor::setDepthWriteEnable(bool depthWriteEnable)
    571 	{
    572 		context->depthWriteEnable = depthWriteEnable;
    573 	}
    574 
    575 	void PixelProcessor::setAlphaTestEnable(bool alphaTestEnable)
    576 	{
    577 		context->alphaTestEnable = alphaTestEnable;
    578 	}
    579 
    580 	void PixelProcessor::setCullMode(CullMode cullMode)
    581 	{
    582 		context->cullMode = cullMode;
    583 	}
    584 
    585 	void PixelProcessor::setColorWriteMask(int index, int rgbaMask)
    586 	{
    587 		context->setColorWriteMask(index, rgbaMask);
    588 	}
    589 
    590 	void PixelProcessor::setStencilEnable(bool stencilEnable)
    591 	{
    592 		context->stencilEnable = stencilEnable;
    593 	}
    594 
    595 	void PixelProcessor::setStencilCompare(StencilCompareMode stencilCompareMode)
    596 	{
    597 		context->stencilCompareMode = stencilCompareMode;
    598 	}
    599 
    600 	void PixelProcessor::setStencilReference(int stencilReference)
    601 	{
    602 		context->stencilReference = stencilReference;
    603 		stencil.set(stencilReference, context->stencilMask, context->stencilWriteMask);
    604 	}
    605 
    606 	void PixelProcessor::setStencilReferenceCCW(int stencilReferenceCCW)
    607 	{
    608 		context->stencilReferenceCCW = stencilReferenceCCW;
    609 		stencilCCW.set(stencilReferenceCCW, context->stencilMaskCCW, context->stencilWriteMaskCCW);
    610 	}
    611 
    612 	void PixelProcessor::setStencilMask(int stencilMask)
    613 	{
    614 		context->stencilMask = stencilMask;
    615 		stencil.set(context->stencilReference, stencilMask, context->stencilWriteMask);
    616 	}
    617 
    618 	void PixelProcessor::setStencilMaskCCW(int stencilMaskCCW)
    619 	{
    620 		context->stencilMaskCCW = stencilMaskCCW;
    621 		stencilCCW.set(context->stencilReferenceCCW, stencilMaskCCW, context->stencilWriteMaskCCW);
    622 	}
    623 
    624 	void PixelProcessor::setStencilFailOperation(StencilOperation stencilFailOperation)
    625 	{
    626 		context->stencilFailOperation = stencilFailOperation;
    627 	}
    628 
    629 	void PixelProcessor::setStencilPassOperation(StencilOperation stencilPassOperation)
    630 	{
    631 		context->stencilPassOperation = stencilPassOperation;
    632 	}
    633 
    634 	void PixelProcessor::setStencilZFailOperation(StencilOperation stencilZFailOperation)
    635 	{
    636 		context->stencilZFailOperation = stencilZFailOperation;
    637 	}
    638 
    639 	void PixelProcessor::setStencilWriteMask(int stencilWriteMask)
    640 	{
    641 		context->stencilWriteMask = stencilWriteMask;
    642 		stencil.set(context->stencilReference, context->stencilMask, stencilWriteMask);
    643 	}
    644 
    645 	void PixelProcessor::setStencilWriteMaskCCW(int stencilWriteMaskCCW)
    646 	{
    647 		context->stencilWriteMaskCCW = stencilWriteMaskCCW;
    648 		stencilCCW.set(context->stencilReferenceCCW, context->stencilMaskCCW, stencilWriteMaskCCW);
    649 	}
    650 
    651 	void PixelProcessor::setTwoSidedStencil(bool enable)
    652 	{
    653 		context->twoSidedStencil = enable;
    654 	}
    655 
    656 	void PixelProcessor::setStencilCompareCCW(StencilCompareMode stencilCompareMode)
    657 	{
    658 		context->stencilCompareModeCCW = stencilCompareMode;
    659 	}
    660 
    661 	void PixelProcessor::setStencilFailOperationCCW(StencilOperation stencilFailOperation)
    662 	{
    663 		context->stencilFailOperationCCW = stencilFailOperation;
    664 	}
    665 
    666 	void PixelProcessor::setStencilPassOperationCCW(StencilOperation stencilPassOperation)
    667 	{
    668 		context->stencilPassOperationCCW = stencilPassOperation;
    669 	}
    670 
    671 	void PixelProcessor::setStencilZFailOperationCCW(StencilOperation stencilZFailOperation)
    672 	{
    673 		context->stencilZFailOperationCCW = stencilZFailOperation;
    674 	}
    675 
    676 	void PixelProcessor::setTextureFactor(const Color<float> &textureFactor)
    677 	{
    678 		// FIXME: Compact into generic function   // FIXME: Clamp
    679 		short textureFactorR = iround(4095 * textureFactor.r);
    680 		short textureFactorG = iround(4095 * textureFactor.g);
    681 		short textureFactorB = iround(4095 * textureFactor.b);
    682 		short textureFactorA = iround(4095 * textureFactor.a);
    683 
    684 		factor.textureFactor4[0][0] = textureFactorR;
    685 		factor.textureFactor4[0][1] = textureFactorR;
    686 		factor.textureFactor4[0][2] = textureFactorR;
    687 		factor.textureFactor4[0][3] = textureFactorR;
    688 
    689 		factor.textureFactor4[1][0] = textureFactorG;
    690 		factor.textureFactor4[1][1] = textureFactorG;
    691 		factor.textureFactor4[1][2] = textureFactorG;
    692 		factor.textureFactor4[1][3] = textureFactorG;
    693 
    694 		factor.textureFactor4[2][0] = textureFactorB;
    695 		factor.textureFactor4[2][1] = textureFactorB;
    696 		factor.textureFactor4[2][2] = textureFactorB;
    697 		factor.textureFactor4[2][3] = textureFactorB;
    698 
    699 		factor.textureFactor4[3][0] = textureFactorA;
    700 		factor.textureFactor4[3][1] = textureFactorA;
    701 		factor.textureFactor4[3][2] = textureFactorA;
    702 		factor.textureFactor4[3][3] = textureFactorA;
    703 	}
    704 
    705 	void PixelProcessor::setBlendConstant(const Color<float> &blendConstant)
    706 	{
    707 		// FIXME: Compact into generic function   // FIXME: Clamp
    708 		short blendConstantR = iround(65535 * blendConstant.r);
    709 		short blendConstantG = iround(65535 * blendConstant.g);
    710 		short blendConstantB = iround(65535 * blendConstant.b);
    711 		short blendConstantA = iround(65535 * blendConstant.a);
    712 
    713 		factor.blendConstant4W[0][0] = blendConstantR;
    714 		factor.blendConstant4W[0][1] = blendConstantR;
    715 		factor.blendConstant4W[0][2] = blendConstantR;
    716 		factor.blendConstant4W[0][3] = blendConstantR;
    717 
    718 		factor.blendConstant4W[1][0] = blendConstantG;
    719 		factor.blendConstant4W[1][1] = blendConstantG;
    720 		factor.blendConstant4W[1][2] = blendConstantG;
    721 		factor.blendConstant4W[1][3] = blendConstantG;
    722 
    723 		factor.blendConstant4W[2][0] = blendConstantB;
    724 		factor.blendConstant4W[2][1] = blendConstantB;
    725 		factor.blendConstant4W[2][2] = blendConstantB;
    726 		factor.blendConstant4W[2][3] = blendConstantB;
    727 
    728 		factor.blendConstant4W[3][0] = blendConstantA;
    729 		factor.blendConstant4W[3][1] = blendConstantA;
    730 		factor.blendConstant4W[3][2] = blendConstantA;
    731 		factor.blendConstant4W[3][3] = blendConstantA;
    732 
    733 		// FIXME: Compact into generic function   // FIXME: Clamp
    734 		short invBlendConstantR = iround(65535 * (1 - blendConstant.r));
    735 		short invBlendConstantG = iround(65535 * (1 - blendConstant.g));
    736 		short invBlendConstantB = iround(65535 * (1 - blendConstant.b));
    737 		short invBlendConstantA = iround(65535 * (1 - blendConstant.a));
    738 
    739 		factor.invBlendConstant4W[0][0] = invBlendConstantR;
    740 		factor.invBlendConstant4W[0][1] = invBlendConstantR;
    741 		factor.invBlendConstant4W[0][2] = invBlendConstantR;
    742 		factor.invBlendConstant4W[0][3] = invBlendConstantR;
    743 
    744 		factor.invBlendConstant4W[1][0] = invBlendConstantG;
    745 		factor.invBlendConstant4W[1][1] = invBlendConstantG;
    746 		factor.invBlendConstant4W[1][2] = invBlendConstantG;
    747 		factor.invBlendConstant4W[1][3] = invBlendConstantG;
    748 
    749 		factor.invBlendConstant4W[2][0] = invBlendConstantB;
    750 		factor.invBlendConstant4W[2][1] = invBlendConstantB;
    751 		factor.invBlendConstant4W[2][2] = invBlendConstantB;
    752 		factor.invBlendConstant4W[2][3] = invBlendConstantB;
    753 
    754 		factor.invBlendConstant4W[3][0] = invBlendConstantA;
    755 		factor.invBlendConstant4W[3][1] = invBlendConstantA;
    756 		factor.invBlendConstant4W[3][2] = invBlendConstantA;
    757 		factor.invBlendConstant4W[3][3] = invBlendConstantA;
    758 
    759 		factor.blendConstant4F[0][0] = blendConstant.r;
    760 		factor.blendConstant4F[0][1] = blendConstant.r;
    761 		factor.blendConstant4F[0][2] = blendConstant.r;
    762 		factor.blendConstant4F[0][3] = blendConstant.r;
    763 
    764 		factor.blendConstant4F[1][0] = blendConstant.g;
    765 		factor.blendConstant4F[1][1] = blendConstant.g;
    766 		factor.blendConstant4F[1][2] = blendConstant.g;
    767 		factor.blendConstant4F[1][3] = blendConstant.g;
    768 
    769 		factor.blendConstant4F[2][0] = blendConstant.b;
    770 		factor.blendConstant4F[2][1] = blendConstant.b;
    771 		factor.blendConstant4F[2][2] = blendConstant.b;
    772 		factor.blendConstant4F[2][3] = blendConstant.b;
    773 
    774 		factor.blendConstant4F[3][0] = blendConstant.a;
    775 		factor.blendConstant4F[3][1] = blendConstant.a;
    776 		factor.blendConstant4F[3][2] = blendConstant.a;
    777 		factor.blendConstant4F[3][3] = blendConstant.a;
    778 
    779 		factor.invBlendConstant4F[0][0] = 1 - blendConstant.r;
    780 		factor.invBlendConstant4F[0][1] = 1 - blendConstant.r;
    781 		factor.invBlendConstant4F[0][2] = 1 - blendConstant.r;
    782 		factor.invBlendConstant4F[0][3] = 1 - blendConstant.r;
    783 
    784 		factor.invBlendConstant4F[1][0] = 1 - blendConstant.g;
    785 		factor.invBlendConstant4F[1][1] = 1 - blendConstant.g;
    786 		factor.invBlendConstant4F[1][2] = 1 - blendConstant.g;
    787 		factor.invBlendConstant4F[1][3] = 1 - blendConstant.g;
    788 
    789 		factor.invBlendConstant4F[2][0] = 1 - blendConstant.b;
    790 		factor.invBlendConstant4F[2][1] = 1 - blendConstant.b;
    791 		factor.invBlendConstant4F[2][2] = 1 - blendConstant.b;
    792 		factor.invBlendConstant4F[2][3] = 1 - blendConstant.b;
    793 
    794 		factor.invBlendConstant4F[3][0] = 1 - blendConstant.a;
    795 		factor.invBlendConstant4F[3][1] = 1 - blendConstant.a;
    796 		factor.invBlendConstant4F[3][2] = 1 - blendConstant.a;
    797 		factor.invBlendConstant4F[3][3] = 1 - blendConstant.a;
    798 	}
    799 
    800 	void PixelProcessor::setFillMode(FillMode fillMode)
    801 	{
    802 		context->fillMode = fillMode;
    803 	}
    804 
    805 	void PixelProcessor::setShadingMode(ShadingMode shadingMode)
    806 	{
    807 		context->shadingMode = shadingMode;
    808 	}
    809 
    810 	void PixelProcessor::setAlphaBlendEnable(bool alphaBlendEnable)
    811 	{
    812 		context->setAlphaBlendEnable(alphaBlendEnable);
    813 	}
    814 
    815 	void PixelProcessor::setSourceBlendFactor(BlendFactor sourceBlendFactor)
    816 	{
    817 		context->setSourceBlendFactor(sourceBlendFactor);
    818 	}
    819 
    820 	void PixelProcessor::setDestBlendFactor(BlendFactor destBlendFactor)
    821 	{
    822 		context->setDestBlendFactor(destBlendFactor);
    823 	}
    824 
    825 	void PixelProcessor::setBlendOperation(BlendOperation blendOperation)
    826 	{
    827 		context->setBlendOperation(blendOperation);
    828 	}
    829 
    830 	void PixelProcessor::setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)
    831 	{
    832 		context->setSeparateAlphaBlendEnable(separateAlphaBlendEnable);
    833 	}
    834 
    835 	void PixelProcessor::setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha)
    836 	{
    837 		context->setSourceBlendFactorAlpha(sourceBlendFactorAlpha);
    838 	}
    839 
    840 	void PixelProcessor::setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha)
    841 	{
    842 		context->setDestBlendFactorAlpha(destBlendFactorAlpha);
    843 	}
    844 
    845 	void PixelProcessor::setBlendOperationAlpha(BlendOperation blendOperationAlpha)
    846 	{
    847 		context->setBlendOperationAlpha(blendOperationAlpha);
    848 	}
    849 
    850 	void PixelProcessor::setAlphaReference(float alphaReference)
    851 	{
    852 		context->alphaReference = alphaReference;
    853 
    854 		factor.alphaReference4[0] = (word)iround(alphaReference * 0x1000 / 0xFF);
    855 		factor.alphaReference4[1] = (word)iround(alphaReference * 0x1000 / 0xFF);
    856 		factor.alphaReference4[2] = (word)iround(alphaReference * 0x1000 / 0xFF);
    857 		factor.alphaReference4[3] = (word)iround(alphaReference * 0x1000 / 0xFF);
    858 	}
    859 
    860 	void PixelProcessor::setGlobalMipmapBias(float bias)
    861 	{
    862 		context->setGlobalMipmapBias(bias);
    863 	}
    864 
    865 	void PixelProcessor::setFogStart(float start)
    866 	{
    867 		setFogRanges(start, context->fogEnd);
    868 	}
    869 
    870 	void PixelProcessor::setFogEnd(float end)
    871 	{
    872 		setFogRanges(context->fogStart, end);
    873 	}
    874 
    875 	void PixelProcessor::setFogColor(Color<float> fogColor)
    876 	{
    877 		// TODO: Compact into generic function
    878 		word fogR = (unsigned short)(65535 * fogColor.r);
    879 		word fogG = (unsigned short)(65535 * fogColor.g);
    880 		word fogB = (unsigned short)(65535 * fogColor.b);
    881 
    882 		fog.color4[0][0] = fogR;
    883 		fog.color4[0][1] = fogR;
    884 		fog.color4[0][2] = fogR;
    885 		fog.color4[0][3] = fogR;
    886 
    887 		fog.color4[1][0] = fogG;
    888 		fog.color4[1][1] = fogG;
    889 		fog.color4[1][2] = fogG;
    890 		fog.color4[1][3] = fogG;
    891 
    892 		fog.color4[2][0] = fogB;
    893 		fog.color4[2][1] = fogB;
    894 		fog.color4[2][2] = fogB;
    895 		fog.color4[2][3] = fogB;
    896 
    897 		fog.colorF[0] = replicate(fogColor.r);
    898 		fog.colorF[1] = replicate(fogColor.g);
    899 		fog.colorF[2] = replicate(fogColor.b);
    900 	}
    901 
    902 	void PixelProcessor::setFogDensity(float fogDensity)
    903 	{
    904 		fog.densityE = replicate(-fogDensity * 1.442695f);   // 1/e^x = 2^(-x*1.44)
    905 		fog.density2E = replicate(-fogDensity * fogDensity * 1.442695f);
    906 	}
    907 
    908 	void PixelProcessor::setPixelFogMode(FogMode fogMode)
    909 	{
    910 		context->pixelFogMode = fogMode;
    911 	}
    912 
    913 	void PixelProcessor::setPerspectiveCorrection(bool perspectiveEnable)
    914 	{
    915 		perspectiveCorrection = perspectiveEnable;
    916 	}
    917 
    918 	void PixelProcessor::setOcclusionEnabled(bool enable)
    919 	{
    920 		context->occlusionEnabled = enable;
    921 	}
    922 
    923 	void PixelProcessor::setRoutineCacheSize(int cacheSize)
    924 	{
    925 		delete routineCache;
    926 		routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precachePixel ? "sw-pixel" : 0);
    927 	}
    928 
    929 	void PixelProcessor::setFogRanges(float start, float end)
    930 	{
    931 		context->fogStart = start;
    932 		context->fogEnd = end;
    933 
    934 		if(start == end)
    935 		{
    936 			end += 0.001f;   // Hack: ensure there is a small range
    937 		}
    938 
    939 		float fogScale = -1.0f / (end - start);
    940 		float fogOffset = end * -fogScale;
    941 
    942 		fog.scale = replicate(fogScale);
    943 		fog.offset = replicate(fogOffset);
    944 	}
    945 
    946 	const PixelProcessor::State PixelProcessor::update() const
    947 	{
    948 		State state;
    949 
    950 		if(context->pixelShader)
    951 		{
    952 			state.shaderID = context->pixelShader->getSerialID();
    953 		}
    954 		else
    955 		{
    956 			state.shaderID = 0;
    957 		}
    958 
    959 		state.depthOverride = context->pixelShader && context->pixelShader->depthOverride();
    960 		state.shaderContainsKill = context->pixelShader ? context->pixelShader->containsKill() : false;
    961 
    962 		if(context->alphaTestActive())
    963 		{
    964 			state.alphaCompareMode = context->alphaCompareMode;
    965 
    966 			state.transparencyAntialiasing = context->getMultiSampleCount() > 1 ? transparencyAntialiasing : TRANSPARENCY_NONE;
    967 		}
    968 
    969 		state.depthWriteEnable = context->depthWriteActive();
    970 
    971 		if(context->stencilActive())
    972 		{
    973 			state.stencilActive = true;
    974 			state.stencilCompareMode = context->stencilCompareMode;
    975 			state.stencilFailOperation = context->stencilFailOperation;
    976 			state.stencilPassOperation = context->stencilPassOperation;
    977 			state.stencilZFailOperation = context->stencilZFailOperation;
    978 			state.noStencilMask = (context->stencilMask == 0xFF);
    979 			state.noStencilWriteMask = (context->stencilWriteMask == 0xFF);
    980 			state.stencilWriteMasked = (context->stencilWriteMask == 0x00);
    981 
    982 			state.twoSidedStencil = context->twoSidedStencil;
    983 			state.stencilCompareModeCCW = context->twoSidedStencil ? context->stencilCompareModeCCW : state.stencilCompareMode;
    984 			state.stencilFailOperationCCW = context->twoSidedStencil ? context->stencilFailOperationCCW : state.stencilFailOperation;
    985 			state.stencilPassOperationCCW = context->twoSidedStencil ? context->stencilPassOperationCCW : state.stencilPassOperation;
    986 			state.stencilZFailOperationCCW = context->twoSidedStencil ? context->stencilZFailOperationCCW : state.stencilZFailOperation;
    987 			state.noStencilMaskCCW = context->twoSidedStencil ? (context->stencilMaskCCW == 0xFF) : state.noStencilMask;
    988 			state.noStencilWriteMaskCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0xFF) : state.noStencilWriteMask;
    989 			state.stencilWriteMaskedCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0x00) : state.stencilWriteMasked;
    990 		}
    991 
    992 		if(context->depthBufferActive())
    993 		{
    994 			state.depthTestActive = true;
    995 			state.depthCompareMode = context->depthCompareMode;
    996 			state.quadLayoutDepthBuffer = Surface::hasQuadLayout(context->depthBuffer->getInternalFormat());
    997 		}
    998 
    999 		state.occlusionEnabled = context->occlusionEnabled;
   1000 
   1001 		state.fogActive = context->fogActive();
   1002 		state.pixelFogMode = context->pixelFogActive();
   1003 		state.wBasedFog = context->wBasedFog && context->pixelFogActive() != FOG_NONE;
   1004 		state.perspective = context->perspectiveActive();
   1005 		state.depthClamp = (context->depthBias != 0.0f) || (context->slopeDepthBias != 0.0f);
   1006 
   1007 		if(context->alphaBlendActive())
   1008 		{
   1009 			state.alphaBlendActive = true;
   1010 			state.sourceBlendFactor = context->sourceBlendFactor();
   1011 			state.destBlendFactor = context->destBlendFactor();
   1012 			state.blendOperation = context->blendOperation();
   1013 			state.sourceBlendFactorAlpha = context->sourceBlendFactorAlpha();
   1014 			state.destBlendFactorAlpha = context->destBlendFactorAlpha();
   1015 			state.blendOperationAlpha = context->blendOperationAlpha();
   1016 		}
   1017 
   1018 		state.logicalOperation = context->colorLogicOp();
   1019 
   1020 		for(int i = 0; i < RENDERTARGETS; i++)
   1021 		{
   1022 			state.colorWriteMask |= context->colorWriteActive(i) << (4 * i);
   1023 			state.targetFormat[i] = context->renderTargetInternalFormat(i);
   1024 		}
   1025 
   1026 		state.writeSRGB	= context->writeSRGB && context->renderTarget[0] && Surface::isSRGBwritable(context->renderTarget[0]->getExternalFormat());
   1027 		state.multiSample = context->getMultiSampleCount();
   1028 		state.multiSampleMask = context->multiSampleMask;
   1029 
   1030 		if(state.multiSample > 1 && context->pixelShader)
   1031 		{
   1032 			state.centroid = context->pixelShader->containsCentroid();
   1033 		}
   1034 
   1035 		if(!context->pixelShader)
   1036 		{
   1037 			for(unsigned int i = 0; i < 8; i++)
   1038 			{
   1039 				state.textureStage[i] = context->textureStage[i].textureStageState();
   1040 			}
   1041 
   1042 			state.specularAdd = context->specularActive() && context->specularEnable;
   1043 		}
   1044 
   1045 		for(unsigned int i = 0; i < 16; i++)
   1046 		{
   1047 			if(context->pixelShader)
   1048 			{
   1049 				if(context->pixelShader->usesSampler(i))
   1050 				{
   1051 					state.sampler[i] = context->sampler[i].samplerState();
   1052 				}
   1053 			}
   1054 			else
   1055 			{
   1056 				if(i < 8 && state.textureStage[i].stageOperation != TextureStage::STAGE_DISABLE)
   1057 				{
   1058 					state.sampler[i] = context->sampler[i].samplerState();
   1059 				}
   1060 				else break;
   1061 			}
   1062 		}
   1063 
   1064 		const bool point = context->isDrawPoint(true);
   1065 		const bool sprite = context->pointSpriteActive();
   1066 		const bool flatShading = (context->shadingMode == SHADING_FLAT) || point;
   1067 
   1068 		if(context->pixelShaderModel() < 0x0300)
   1069 		{
   1070 			for(int coordinate = 0; coordinate < 8; coordinate++)
   1071 			{
   1072 				for(int component = 0; component < 4; component++)
   1073 				{
   1074 					if(context->textureActive(coordinate, component))
   1075 					{
   1076 						state.texture[coordinate].component |= 1 << component;
   1077 
   1078 						if(point && !sprite)
   1079 						{
   1080 							state.texture[coordinate].flat |= 1 << component;
   1081 						}
   1082 					}
   1083 				}
   1084 
   1085 				if(context->textureTransformProject[coordinate] && context->pixelShaderModel() <= 0x0103)
   1086 				{
   1087 					if(context->textureTransformCount[coordinate] == 2)
   1088 					{
   1089 						state.texture[coordinate].project = 1;
   1090 					}
   1091 					else if(context->textureTransformCount[coordinate] == 3)
   1092 					{
   1093 						state.texture[coordinate].project = 2;
   1094 					}
   1095 					else if(context->textureTransformCount[coordinate] == 4 || context->textureTransformCount[coordinate] == 0)
   1096 					{
   1097 						state.texture[coordinate].project = 3;
   1098 					}
   1099 				}
   1100 			}
   1101 
   1102 			for(int color = 0; color < 2; color++)
   1103 			{
   1104 				for(int component = 0; component < 4; component++)
   1105 				{
   1106 					if(context->colorActive(color, component))
   1107 					{
   1108 						state.color[color].component |= 1 << component;
   1109 
   1110 						if(point || flatShading)
   1111 						{
   1112 							state.color[color].flat |= 1 << component;
   1113 						}
   1114 					}
   1115 				}
   1116 			}
   1117 
   1118 			if(context->fogActive())
   1119 			{
   1120 				state.fog.component = true;
   1121 
   1122 				if(point)
   1123 				{
   1124 					state.fog.flat = true;
   1125 				}
   1126 			}
   1127 		}
   1128 		else
   1129 		{
   1130 			for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
   1131 			{
   1132 				for(int component = 0; component < 4; component++)
   1133 				{
   1134 					const Shader::Semantic &semantic = context->pixelShader->getInput(interpolant, component);
   1135 
   1136 					if(semantic.active())
   1137 					{
   1138 						bool flat = point;
   1139 
   1140 						switch(semantic.usage)
   1141 						{
   1142 						case Shader::USAGE_TEXCOORD: flat = point && !sprite;             break;
   1143 						case Shader::USAGE_COLOR:    flat = semantic.flat || flatShading; break;
   1144 						}
   1145 
   1146 						state.interpolant[interpolant].component |= 1 << component;
   1147 
   1148 						if(flat)
   1149 						{
   1150 							state.interpolant[interpolant].flat |= 1 << component;
   1151 						}
   1152 					}
   1153 				}
   1154 			}
   1155 		}
   1156 
   1157 		if(state.centroid)
   1158 		{
   1159 			for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
   1160 			{
   1161 				for(int component = 0; component < 4; component++)
   1162 				{
   1163 					state.interpolant[interpolant].centroid = context->pixelShader->getInput(interpolant, 0).centroid;
   1164 				}
   1165 			}
   1166 		}
   1167 
   1168 		state.hash = state.computeHash();
   1169 
   1170 		return state;
   1171 	}
   1172 
   1173 	Routine *PixelProcessor::routine(const State &state)
   1174 	{
   1175 		Routine *routine = routineCache->query(state);
   1176 
   1177 		if(!routine)
   1178 		{
   1179 			const bool integerPipeline = (context->pixelShaderModel() <= 0x0104);
   1180 			QuadRasterizer *generator = nullptr;
   1181 
   1182 			if(integerPipeline)
   1183 			{
   1184 				generator = new PixelPipeline(state, context->pixelShader);
   1185 			}
   1186 			else
   1187 			{
   1188 				generator = new PixelProgram(state, context->pixelShader);
   1189 			}
   1190 
   1191 			generator->generate();
   1192 			routine = (*generator)(L"PixelRoutine_%0.8X", state.shaderID);
   1193 			delete generator;
   1194 
   1195 			routineCache->add(state, routine);
   1196 		}
   1197 
   1198 		return routine;
   1199 	}
   1200 }
   1201