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