• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
computeHash()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 
State()48 	PixelProcessor::State::State()
49 	{
50 		memset(this, 0, sizeof(State));
51 	}
52 
operator ==(const State & state) const53 	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 
UniformBufferInfo()63 	PixelProcessor::UniformBufferInfo::UniformBufferInfo()
64 	{
65 		buffer = nullptr;
66 		offset = 0;
67 	}
68 
PixelProcessor(Context * context)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 
~PixelProcessor()79 	PixelProcessor::~PixelProcessor()
80 	{
81 		delete routineCache;
82 		routineCache = 0;
83 	}
84 
setFloatConstant(unsigned int index,const float value[4])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 			// TODO: Compact into generic function
99 			short x = iround(4095 * clamp_s(value[0], -1.0f, 1.0f));
100 			short y = iround(4095 * clamp_s(value[1], -1.0f, 1.0f));
101 			short z = iround(4095 * clamp_s(value[2], -1.0f, 1.0f));
102 			short w = iround(4095 * clamp_s(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 
setIntegerConstant(unsigned int index,const int value[4])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 
setBooleanConstant(unsigned int index,int boolean)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 
setUniformBuffer(int index,sw::Resource * buffer,int offset)147 	void PixelProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
148 	{
149 		uniformBufferInfo[index].buffer = buffer;
150 		uniformBufferInfo[index].offset = offset;
151 	}
152 
lockUniformBuffers(byte ** u,sw::Resource * uniformBuffers[])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 
setRenderTarget(int index,Surface * renderTarget,unsigned int layer)162 	void PixelProcessor::setRenderTarget(int index, Surface *renderTarget, unsigned int layer)
163 	{
164 		context->renderTarget[index] = renderTarget;
165 		context->renderTargetLayer[index] = layer;
166 	}
167 
setDepthBuffer(Surface * depthBuffer,unsigned int layer)168 	void PixelProcessor::setDepthBuffer(Surface *depthBuffer, unsigned int layer)
169 	{
170 		context->depthBuffer = depthBuffer;
171 		context->depthBufferLayer = layer;
172 	}
173 
setStencilBuffer(Surface * stencilBuffer,unsigned int layer)174 	void PixelProcessor::setStencilBuffer(Surface *stencilBuffer, unsigned int layer)
175 	{
176 		context->stencilBuffer = stencilBuffer;
177 		context->stencilBufferLayer = layer;
178 	}
179 
setTexCoordIndex(unsigned int stage,int texCoordIndex)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 
setStageOperation(unsigned int stage,TextureStage::StageOperation stageOperation)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 
setFirstArgument(unsigned int stage,TextureStage::SourceArgument firstArgument)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 
setSecondArgument(unsigned int stage,TextureStage::SourceArgument secondArgument)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 
setThirdArgument(unsigned int stage,TextureStage::SourceArgument thirdArgument)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 
setStageOperationAlpha(unsigned int stage,TextureStage::StageOperation stageOperationAlpha)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 
setFirstArgumentAlpha(unsigned int stage,TextureStage::SourceArgument firstArgumentAlpha)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 
setSecondArgumentAlpha(unsigned int stage,TextureStage::SourceArgument secondArgumentAlpha)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 
setThirdArgumentAlpha(unsigned int stage,TextureStage::SourceArgument thirdArgumentAlpha)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 
setFirstModifier(unsigned int stage,TextureStage::ArgumentModifier firstModifier)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 
setSecondModifier(unsigned int stage,TextureStage::ArgumentModifier secondModifier)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 
setThirdModifier(unsigned int stage,TextureStage::ArgumentModifier thirdModifier)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 
setFirstModifierAlpha(unsigned int stage,TextureStage::ArgumentModifier firstModifierAlpha)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 
setSecondModifierAlpha(unsigned int stage,TextureStage::ArgumentModifier secondModifierAlpha)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 
setThirdModifierAlpha(unsigned int stage,TextureStage::ArgumentModifier thirdModifierAlpha)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 
setDestinationArgument(unsigned int stage,TextureStage::DestinationArgument destinationArgument)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 
setConstantColor(unsigned int stage,const Color<float> & constantColor)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 
setBumpmapMatrix(unsigned int stage,int element,float value)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 
setLuminanceScale(unsigned int stage,float value)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 
setLuminanceOffset(unsigned int stage,float value)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 
setTextureFilter(unsigned int sampler,FilterType textureFilter)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 
setMipmapFilter(unsigned int sampler,MipmapType mipmapFilter)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 
setGatherEnable(unsigned int sampler,bool enable)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 
setAddressingModeU(unsigned int sampler,AddressingMode addressMode)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 
setAddressingModeV(unsigned int sampler,AddressingMode addressMode)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 
setAddressingModeW(unsigned int sampler,AddressingMode addressMode)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 
setReadSRGB(unsigned int sampler,bool sRGB)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 
setMipmapLOD(unsigned int sampler,float bias)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 
setBorderColor(unsigned int sampler,const Color<float> & borderColor)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 
setMaxAnisotropy(unsigned int sampler,float maxAnisotropy)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 
setHighPrecisionFiltering(unsigned int sampler,bool highPrecisionFiltering)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 
setSwizzleR(unsigned int sampler,SwizzleType swizzleR)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 
setSwizzleG(unsigned int sampler,SwizzleType swizzleG)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 
setSwizzleB(unsigned int sampler,SwizzleType swizzleB)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 
setSwizzleA(unsigned int sampler,SwizzleType swizzleA)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 
setCompareFunc(unsigned int sampler,CompareFunc compFunc)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 
setBaseLevel(unsigned int sampler,int baseLevel)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 
setMaxLevel(unsigned int sampler,int maxLevel)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 
setMinLod(unsigned int sampler,float minLod)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 
setMaxLod(unsigned int sampler,float maxLod)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 
setSyncRequired(unsigned int sampler,bool isSincRequired)540 	void PixelProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired)
541 	{
542 		if(sampler < TEXTURE_IMAGE_UNITS)
543 		{
544 			context->sampler[sampler].setSyncRequired(isSincRequired);
545 		}
546 		else ASSERT(false);
547 	}
548 
setWriteSRGB(bool sRGB)549 	void PixelProcessor::setWriteSRGB(bool sRGB)
550 	{
551 		context->setWriteSRGB(sRGB);
552 	}
553 
setColorLogicOpEnabled(bool colorLogicOpEnabled)554 	void PixelProcessor::setColorLogicOpEnabled(bool colorLogicOpEnabled)
555 	{
556 		context->setColorLogicOpEnabled(colorLogicOpEnabled);
557 	}
558 
setLogicalOperation(LogicalOperation logicalOperation)559 	void PixelProcessor::setLogicalOperation(LogicalOperation logicalOperation)
560 	{
561 		context->setLogicalOperation(logicalOperation);
562 	}
563 
setDepthBufferEnable(bool depthBufferEnable)564 	void PixelProcessor::setDepthBufferEnable(bool depthBufferEnable)
565 	{
566 		context->setDepthBufferEnable(depthBufferEnable);
567 	}
568 
setDepthCompare(DepthCompareMode depthCompareMode)569 	void PixelProcessor::setDepthCompare(DepthCompareMode depthCompareMode)
570 	{
571 		context->depthCompareMode = depthCompareMode;
572 	}
573 
setAlphaCompare(AlphaCompareMode alphaCompareMode)574 	void PixelProcessor::setAlphaCompare(AlphaCompareMode alphaCompareMode)
575 	{
576 		context->alphaCompareMode = alphaCompareMode;
577 	}
578 
setDepthWriteEnable(bool depthWriteEnable)579 	void PixelProcessor::setDepthWriteEnable(bool depthWriteEnable)
580 	{
581 		context->depthWriteEnable = depthWriteEnable;
582 	}
583 
setAlphaTestEnable(bool alphaTestEnable)584 	void PixelProcessor::setAlphaTestEnable(bool alphaTestEnable)
585 	{
586 		context->alphaTestEnable = alphaTestEnable;
587 	}
588 
setCullMode(CullMode cullMode,bool frontFacingCCW)589 	void PixelProcessor::setCullMode(CullMode cullMode, bool frontFacingCCW)
590 	{
591 		context->cullMode = cullMode;
592 		context->frontFacingCCW = frontFacingCCW;
593 	}
594 
setColorWriteMask(int index,int rgbaMask)595 	void PixelProcessor::setColorWriteMask(int index, int rgbaMask)
596 	{
597 		context->setColorWriteMask(index, rgbaMask);
598 	}
599 
setStencilEnable(bool stencilEnable)600 	void PixelProcessor::setStencilEnable(bool stencilEnable)
601 	{
602 		context->stencilEnable = stencilEnable;
603 	}
604 
setStencilCompare(StencilCompareMode stencilCompareMode)605 	void PixelProcessor::setStencilCompare(StencilCompareMode stencilCompareMode)
606 	{
607 		context->stencilCompareMode = stencilCompareMode;
608 	}
609 
setStencilReference(int stencilReference)610 	void PixelProcessor::setStencilReference(int stencilReference)
611 	{
612 		context->stencilReference = stencilReference;
613 		stencil.set(stencilReference, context->stencilMask, context->stencilWriteMask);
614 	}
615 
setStencilReferenceCCW(int stencilReferenceCCW)616 	void PixelProcessor::setStencilReferenceCCW(int stencilReferenceCCW)
617 	{
618 		context->stencilReferenceCCW = stencilReferenceCCW;
619 		stencilCCW.set(stencilReferenceCCW, context->stencilMaskCCW, context->stencilWriteMaskCCW);
620 	}
621 
setStencilMask(int stencilMask)622 	void PixelProcessor::setStencilMask(int stencilMask)
623 	{
624 		context->stencilMask = stencilMask;
625 		stencil.set(context->stencilReference, stencilMask, context->stencilWriteMask);
626 	}
627 
setStencilMaskCCW(int stencilMaskCCW)628 	void PixelProcessor::setStencilMaskCCW(int stencilMaskCCW)
629 	{
630 		context->stencilMaskCCW = stencilMaskCCW;
631 		stencilCCW.set(context->stencilReferenceCCW, stencilMaskCCW, context->stencilWriteMaskCCW);
632 	}
633 
setStencilFailOperation(StencilOperation stencilFailOperation)634 	void PixelProcessor::setStencilFailOperation(StencilOperation stencilFailOperation)
635 	{
636 		context->stencilFailOperation = stencilFailOperation;
637 	}
638 
setStencilPassOperation(StencilOperation stencilPassOperation)639 	void PixelProcessor::setStencilPassOperation(StencilOperation stencilPassOperation)
640 	{
641 		context->stencilPassOperation = stencilPassOperation;
642 	}
643 
setStencilZFailOperation(StencilOperation stencilZFailOperation)644 	void PixelProcessor::setStencilZFailOperation(StencilOperation stencilZFailOperation)
645 	{
646 		context->stencilZFailOperation = stencilZFailOperation;
647 	}
648 
setStencilWriteMask(int stencilWriteMask)649 	void PixelProcessor::setStencilWriteMask(int stencilWriteMask)
650 	{
651 		context->stencilWriteMask = stencilWriteMask;
652 		stencil.set(context->stencilReference, context->stencilMask, stencilWriteMask);
653 	}
654 
setStencilWriteMaskCCW(int stencilWriteMaskCCW)655 	void PixelProcessor::setStencilWriteMaskCCW(int stencilWriteMaskCCW)
656 	{
657 		context->stencilWriteMaskCCW = stencilWriteMaskCCW;
658 		stencilCCW.set(context->stencilReferenceCCW, context->stencilMaskCCW, stencilWriteMaskCCW);
659 	}
660 
setTwoSidedStencil(bool enable)661 	void PixelProcessor::setTwoSidedStencil(bool enable)
662 	{
663 		context->twoSidedStencil = enable;
664 	}
665 
setStencilCompareCCW(StencilCompareMode stencilCompareMode)666 	void PixelProcessor::setStencilCompareCCW(StencilCompareMode stencilCompareMode)
667 	{
668 		context->stencilCompareModeCCW = stencilCompareMode;
669 	}
670 
setStencilFailOperationCCW(StencilOperation stencilFailOperation)671 	void PixelProcessor::setStencilFailOperationCCW(StencilOperation stencilFailOperation)
672 	{
673 		context->stencilFailOperationCCW = stencilFailOperation;
674 	}
675 
setStencilPassOperationCCW(StencilOperation stencilPassOperation)676 	void PixelProcessor::setStencilPassOperationCCW(StencilOperation stencilPassOperation)
677 	{
678 		context->stencilPassOperationCCW = stencilPassOperation;
679 	}
680 
setStencilZFailOperationCCW(StencilOperation stencilZFailOperation)681 	void PixelProcessor::setStencilZFailOperationCCW(StencilOperation stencilZFailOperation)
682 	{
683 		context->stencilZFailOperationCCW = stencilZFailOperation;
684 	}
685 
setTextureFactor(const Color<float> & textureFactor)686 	void PixelProcessor::setTextureFactor(const Color<float> &textureFactor)
687 	{
688 		// FIXME: Compact into generic function   // FIXME: Clamp
689 		short textureFactorR = iround(4095 * textureFactor.r);
690 		short textureFactorG = iround(4095 * textureFactor.g);
691 		short textureFactorB = iround(4095 * textureFactor.b);
692 		short textureFactorA = iround(4095 * textureFactor.a);
693 
694 		factor.textureFactor4[0][0] = textureFactorR;
695 		factor.textureFactor4[0][1] = textureFactorR;
696 		factor.textureFactor4[0][2] = textureFactorR;
697 		factor.textureFactor4[0][3] = textureFactorR;
698 
699 		factor.textureFactor4[1][0] = textureFactorG;
700 		factor.textureFactor4[1][1] = textureFactorG;
701 		factor.textureFactor4[1][2] = textureFactorG;
702 		factor.textureFactor4[1][3] = textureFactorG;
703 
704 		factor.textureFactor4[2][0] = textureFactorB;
705 		factor.textureFactor4[2][1] = textureFactorB;
706 		factor.textureFactor4[2][2] = textureFactorB;
707 		factor.textureFactor4[2][3] = textureFactorB;
708 
709 		factor.textureFactor4[3][0] = textureFactorA;
710 		factor.textureFactor4[3][1] = textureFactorA;
711 		factor.textureFactor4[3][2] = textureFactorA;
712 		factor.textureFactor4[3][3] = textureFactorA;
713 	}
714 
setBlendConstant(const Color<float> & blendConstant)715 	void PixelProcessor::setBlendConstant(const Color<float> &blendConstant)
716 	{
717 		// FIXME: Compact into generic function   // FIXME: Clamp
718 		short blendConstantR = iround(65535 * blendConstant.r);
719 		short blendConstantG = iround(65535 * blendConstant.g);
720 		short blendConstantB = iround(65535 * blendConstant.b);
721 		short blendConstantA = iround(65535 * blendConstant.a);
722 
723 		factor.blendConstant4W[0][0] = blendConstantR;
724 		factor.blendConstant4W[0][1] = blendConstantR;
725 		factor.blendConstant4W[0][2] = blendConstantR;
726 		factor.blendConstant4W[0][3] = blendConstantR;
727 
728 		factor.blendConstant4W[1][0] = blendConstantG;
729 		factor.blendConstant4W[1][1] = blendConstantG;
730 		factor.blendConstant4W[1][2] = blendConstantG;
731 		factor.blendConstant4W[1][3] = blendConstantG;
732 
733 		factor.blendConstant4W[2][0] = blendConstantB;
734 		factor.blendConstant4W[2][1] = blendConstantB;
735 		factor.blendConstant4W[2][2] = blendConstantB;
736 		factor.blendConstant4W[2][3] = blendConstantB;
737 
738 		factor.blendConstant4W[3][0] = blendConstantA;
739 		factor.blendConstant4W[3][1] = blendConstantA;
740 		factor.blendConstant4W[3][2] = blendConstantA;
741 		factor.blendConstant4W[3][3] = blendConstantA;
742 
743 		// FIXME: Compact into generic function   // FIXME: Clamp
744 		short invBlendConstantR = iround(65535 * (1 - blendConstant.r));
745 		short invBlendConstantG = iround(65535 * (1 - blendConstant.g));
746 		short invBlendConstantB = iround(65535 * (1 - blendConstant.b));
747 		short invBlendConstantA = iround(65535 * (1 - blendConstant.a));
748 
749 		factor.invBlendConstant4W[0][0] = invBlendConstantR;
750 		factor.invBlendConstant4W[0][1] = invBlendConstantR;
751 		factor.invBlendConstant4W[0][2] = invBlendConstantR;
752 		factor.invBlendConstant4W[0][3] = invBlendConstantR;
753 
754 		factor.invBlendConstant4W[1][0] = invBlendConstantG;
755 		factor.invBlendConstant4W[1][1] = invBlendConstantG;
756 		factor.invBlendConstant4W[1][2] = invBlendConstantG;
757 		factor.invBlendConstant4W[1][3] = invBlendConstantG;
758 
759 		factor.invBlendConstant4W[2][0] = invBlendConstantB;
760 		factor.invBlendConstant4W[2][1] = invBlendConstantB;
761 		factor.invBlendConstant4W[2][2] = invBlendConstantB;
762 		factor.invBlendConstant4W[2][3] = invBlendConstantB;
763 
764 		factor.invBlendConstant4W[3][0] = invBlendConstantA;
765 		factor.invBlendConstant4W[3][1] = invBlendConstantA;
766 		factor.invBlendConstant4W[3][2] = invBlendConstantA;
767 		factor.invBlendConstant4W[3][3] = invBlendConstantA;
768 
769 		factor.blendConstant4F[0][0] = blendConstant.r;
770 		factor.blendConstant4F[0][1] = blendConstant.r;
771 		factor.blendConstant4F[0][2] = blendConstant.r;
772 		factor.blendConstant4F[0][3] = blendConstant.r;
773 
774 		factor.blendConstant4F[1][0] = blendConstant.g;
775 		factor.blendConstant4F[1][1] = blendConstant.g;
776 		factor.blendConstant4F[1][2] = blendConstant.g;
777 		factor.blendConstant4F[1][3] = blendConstant.g;
778 
779 		factor.blendConstant4F[2][0] = blendConstant.b;
780 		factor.blendConstant4F[2][1] = blendConstant.b;
781 		factor.blendConstant4F[2][2] = blendConstant.b;
782 		factor.blendConstant4F[2][3] = blendConstant.b;
783 
784 		factor.blendConstant4F[3][0] = blendConstant.a;
785 		factor.blendConstant4F[3][1] = blendConstant.a;
786 		factor.blendConstant4F[3][2] = blendConstant.a;
787 		factor.blendConstant4F[3][3] = blendConstant.a;
788 
789 		factor.invBlendConstant4F[0][0] = 1 - blendConstant.r;
790 		factor.invBlendConstant4F[0][1] = 1 - blendConstant.r;
791 		factor.invBlendConstant4F[0][2] = 1 - blendConstant.r;
792 		factor.invBlendConstant4F[0][3] = 1 - blendConstant.r;
793 
794 		factor.invBlendConstant4F[1][0] = 1 - blendConstant.g;
795 		factor.invBlendConstant4F[1][1] = 1 - blendConstant.g;
796 		factor.invBlendConstant4F[1][2] = 1 - blendConstant.g;
797 		factor.invBlendConstant4F[1][3] = 1 - blendConstant.g;
798 
799 		factor.invBlendConstant4F[2][0] = 1 - blendConstant.b;
800 		factor.invBlendConstant4F[2][1] = 1 - blendConstant.b;
801 		factor.invBlendConstant4F[2][2] = 1 - blendConstant.b;
802 		factor.invBlendConstant4F[2][3] = 1 - blendConstant.b;
803 
804 		factor.invBlendConstant4F[3][0] = 1 - blendConstant.a;
805 		factor.invBlendConstant4F[3][1] = 1 - blendConstant.a;
806 		factor.invBlendConstant4F[3][2] = 1 - blendConstant.a;
807 		factor.invBlendConstant4F[3][3] = 1 - blendConstant.a;
808 	}
809 
setFillMode(FillMode fillMode)810 	void PixelProcessor::setFillMode(FillMode fillMode)
811 	{
812 		context->fillMode = fillMode;
813 	}
814 
setShadingMode(ShadingMode shadingMode)815 	void PixelProcessor::setShadingMode(ShadingMode shadingMode)
816 	{
817 		context->shadingMode = shadingMode;
818 	}
819 
setAlphaBlendEnable(bool alphaBlendEnable)820 	void PixelProcessor::setAlphaBlendEnable(bool alphaBlendEnable)
821 	{
822 		context->setAlphaBlendEnable(alphaBlendEnable);
823 	}
824 
setSourceBlendFactor(BlendFactor sourceBlendFactor)825 	void PixelProcessor::setSourceBlendFactor(BlendFactor sourceBlendFactor)
826 	{
827 		context->setSourceBlendFactor(sourceBlendFactor);
828 	}
829 
setDestBlendFactor(BlendFactor destBlendFactor)830 	void PixelProcessor::setDestBlendFactor(BlendFactor destBlendFactor)
831 	{
832 		context->setDestBlendFactor(destBlendFactor);
833 	}
834 
setBlendOperation(BlendOperation blendOperation)835 	void PixelProcessor::setBlendOperation(BlendOperation blendOperation)
836 	{
837 		context->setBlendOperation(blendOperation);
838 	}
839 
setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)840 	void PixelProcessor::setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)
841 	{
842 		context->setSeparateAlphaBlendEnable(separateAlphaBlendEnable);
843 	}
844 
setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha)845 	void PixelProcessor::setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha)
846 	{
847 		context->setSourceBlendFactorAlpha(sourceBlendFactorAlpha);
848 	}
849 
setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha)850 	void PixelProcessor::setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha)
851 	{
852 		context->setDestBlendFactorAlpha(destBlendFactorAlpha);
853 	}
854 
setBlendOperationAlpha(BlendOperation blendOperationAlpha)855 	void PixelProcessor::setBlendOperationAlpha(BlendOperation blendOperationAlpha)
856 	{
857 		context->setBlendOperationAlpha(blendOperationAlpha);
858 	}
859 
setAlphaReference(float alphaReference)860 	void PixelProcessor::setAlphaReference(float alphaReference)
861 	{
862 		context->alphaReference = alphaReference;
863 
864 		factor.alphaReference4[0] = (word)iround(alphaReference * 0x1000 / 0xFF);
865 		factor.alphaReference4[1] = (word)iround(alphaReference * 0x1000 / 0xFF);
866 		factor.alphaReference4[2] = (word)iround(alphaReference * 0x1000 / 0xFF);
867 		factor.alphaReference4[3] = (word)iround(alphaReference * 0x1000 / 0xFF);
868 	}
869 
setGlobalMipmapBias(float bias)870 	void PixelProcessor::setGlobalMipmapBias(float bias)
871 	{
872 		context->setGlobalMipmapBias(bias);
873 	}
874 
setFogStart(float start)875 	void PixelProcessor::setFogStart(float start)
876 	{
877 		setFogRanges(start, context->fogEnd);
878 	}
879 
setFogEnd(float end)880 	void PixelProcessor::setFogEnd(float end)
881 	{
882 		setFogRanges(context->fogStart, end);
883 	}
884 
setFogColor(Color<float> fogColor)885 	void PixelProcessor::setFogColor(Color<float> fogColor)
886 	{
887 		// TODO: Compact into generic function
888 		word fogR = (unsigned short)(65535 * fogColor.r);
889 		word fogG = (unsigned short)(65535 * fogColor.g);
890 		word fogB = (unsigned short)(65535 * fogColor.b);
891 
892 		fog.color4[0][0] = fogR;
893 		fog.color4[0][1] = fogR;
894 		fog.color4[0][2] = fogR;
895 		fog.color4[0][3] = fogR;
896 
897 		fog.color4[1][0] = fogG;
898 		fog.color4[1][1] = fogG;
899 		fog.color4[1][2] = fogG;
900 		fog.color4[1][3] = fogG;
901 
902 		fog.color4[2][0] = fogB;
903 		fog.color4[2][1] = fogB;
904 		fog.color4[2][2] = fogB;
905 		fog.color4[2][3] = fogB;
906 
907 		fog.colorF[0] = replicate(fogColor.r);
908 		fog.colorF[1] = replicate(fogColor.g);
909 		fog.colorF[2] = replicate(fogColor.b);
910 	}
911 
setFogDensity(float fogDensity)912 	void PixelProcessor::setFogDensity(float fogDensity)
913 	{
914 		fog.densityE = replicate(-fogDensity * 1.442695f);   // 1/e^x = 2^(-x*1.44)
915 		fog.density2E = replicate(-fogDensity * fogDensity * 1.442695f);
916 	}
917 
setPixelFogMode(FogMode fogMode)918 	void PixelProcessor::setPixelFogMode(FogMode fogMode)
919 	{
920 		context->pixelFogMode = fogMode;
921 	}
922 
setPerspectiveCorrection(bool perspectiveEnable)923 	void PixelProcessor::setPerspectiveCorrection(bool perspectiveEnable)
924 	{
925 		perspectiveCorrection = perspectiveEnable;
926 	}
927 
setOcclusionEnabled(bool enable)928 	void PixelProcessor::setOcclusionEnabled(bool enable)
929 	{
930 		context->occlusionEnabled = enable;
931 	}
932 
setRoutineCacheSize(int cacheSize)933 	void PixelProcessor::setRoutineCacheSize(int cacheSize)
934 	{
935 		delete routineCache;
936 		routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precachePixel ? "sw-pixel" : 0);
937 	}
938 
setFogRanges(float start,float end)939 	void PixelProcessor::setFogRanges(float start, float end)
940 	{
941 		context->fogStart = start;
942 		context->fogEnd = end;
943 
944 		if(start == end)
945 		{
946 			end += 0.001f;   // Hack: ensure there is a small range
947 		}
948 
949 		float fogScale = -1.0f / (end - start);
950 		float fogOffset = end * -fogScale;
951 
952 		fog.scale = replicate(fogScale);
953 		fog.offset = replicate(fogOffset);
954 	}
955 
update() const956 	const PixelProcessor::State PixelProcessor::update() const
957 	{
958 		State state;
959 
960 		if(context->pixelShader)
961 		{
962 			state.shaderID = context->pixelShader->getSerialID();
963 		}
964 		else
965 		{
966 			state.shaderID = 0;
967 		}
968 
969 		state.depthOverride = context->pixelShader && context->pixelShader->depthOverride();
970 		state.shaderContainsKill = context->pixelShader ? context->pixelShader->containsKill() : false;
971 
972 		if(context->alphaTestActive())
973 		{
974 			state.alphaCompareMode = context->alphaCompareMode;
975 
976 			state.transparencyAntialiasing = context->getMultiSampleCount() > 1 ? transparencyAntialiasing : TRANSPARENCY_NONE;
977 		}
978 
979 		state.depthWriteEnable = context->depthWriteActive();
980 
981 		if(context->stencilActive())
982 		{
983 			state.stencilActive = true;
984 			state.stencilCompareMode = context->stencilCompareMode;
985 			state.stencilFailOperation = context->stencilFailOperation;
986 			state.stencilPassOperation = context->stencilPassOperation;
987 			state.stencilZFailOperation = context->stencilZFailOperation;
988 			state.noStencilMask = (context->stencilMask == 0xFF);
989 			state.noStencilWriteMask = (context->stencilWriteMask == 0xFF);
990 			state.stencilWriteMasked = (context->stencilWriteMask == 0x00);
991 
992 			state.twoSidedStencil = context->twoSidedStencil;
993 			state.stencilCompareModeCCW = context->twoSidedStencil ? context->stencilCompareModeCCW : state.stencilCompareMode;
994 			state.stencilFailOperationCCW = context->twoSidedStencil ? context->stencilFailOperationCCW : state.stencilFailOperation;
995 			state.stencilPassOperationCCW = context->twoSidedStencil ? context->stencilPassOperationCCW : state.stencilPassOperation;
996 			state.stencilZFailOperationCCW = context->twoSidedStencil ? context->stencilZFailOperationCCW : state.stencilZFailOperation;
997 			state.noStencilMaskCCW = context->twoSidedStencil ? (context->stencilMaskCCW == 0xFF) : state.noStencilMask;
998 			state.noStencilWriteMaskCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0xFF) : state.noStencilWriteMask;
999 			state.stencilWriteMaskedCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0x00) : state.stencilWriteMasked;
1000 		}
1001 
1002 		if(context->depthBufferActive())
1003 		{
1004 			state.depthTestActive = true;
1005 			state.depthCompareMode = context->depthCompareMode;
1006 			state.quadLayoutDepthBuffer = Surface::hasQuadLayout(context->depthBuffer->getInternalFormat());
1007 		}
1008 
1009 		state.occlusionEnabled = context->occlusionEnabled;
1010 
1011 		state.fogActive = context->fogActive();
1012 		state.pixelFogMode = context->pixelFogActive();
1013 		state.wBasedFog = context->wBasedFog && context->pixelFogActive() != FOG_NONE;
1014 		state.perspective = context->perspectiveActive();
1015 		state.depthClamp = (context->depthBias != 0.0f) || (context->slopeDepthBias != 0.0f);
1016 
1017 		if(context->alphaBlendActive())
1018 		{
1019 			state.alphaBlendActive = true;
1020 			state.sourceBlendFactor = context->sourceBlendFactor();
1021 			state.destBlendFactor = context->destBlendFactor();
1022 			state.blendOperation = context->blendOperation();
1023 			state.sourceBlendFactorAlpha = context->sourceBlendFactorAlpha();
1024 			state.destBlendFactorAlpha = context->destBlendFactorAlpha();
1025 			state.blendOperationAlpha = context->blendOperationAlpha();
1026 		}
1027 
1028 		state.logicalOperation = context->colorLogicOp();
1029 
1030 		for(int i = 0; i < RENDERTARGETS; i++)
1031 		{
1032 			state.colorWriteMask |= context->colorWriteActive(i) << (4 * i);
1033 			state.targetFormat[i] = context->renderTargetInternalFormat(i);
1034 		}
1035 
1036 		state.writeSRGB	= context->writeSRGB && context->renderTarget[0] && Surface::isSRGBwritable(context->renderTarget[0]->getExternalFormat());
1037 		state.multiSample = context->getMultiSampleCount();
1038 		state.multiSampleMask = context->multiSampleMask;
1039 
1040 		if(state.multiSample > 1 && context->pixelShader)
1041 		{
1042 			state.centroid = context->pixelShader->containsCentroid();
1043 		}
1044 
1045 		state.frontFaceCCW = context->frontFacingCCW;
1046 
1047 		if(!context->pixelShader)
1048 		{
1049 			for(unsigned int i = 0; i < 8; i++)
1050 			{
1051 				state.textureStage[i] = context->textureStage[i].textureStageState();
1052 			}
1053 
1054 			state.specularAdd = context->specularActive() && context->specularEnable;
1055 		}
1056 
1057 		for(unsigned int i = 0; i < 16; i++)
1058 		{
1059 			if(context->pixelShader)
1060 			{
1061 				if(context->pixelShader->usesSampler(i))
1062 				{
1063 					state.sampler[i] = context->sampler[i].samplerState();
1064 				}
1065 			}
1066 			else
1067 			{
1068 				if(i < 8 && state.textureStage[i].stageOperation != TextureStage::STAGE_DISABLE)
1069 				{
1070 					state.sampler[i] = context->sampler[i].samplerState();
1071 				}
1072 				else break;
1073 			}
1074 		}
1075 
1076 		const bool point = context->isDrawPoint(true);
1077 		const bool sprite = context->pointSpriteActive();
1078 		const bool flatShading = (context->shadingMode == SHADING_FLAT) || point;
1079 
1080 		if(context->pixelShaderModel() < 0x0300)
1081 		{
1082 			for(int coordinate = 0; coordinate < 8; coordinate++)
1083 			{
1084 				for(int component = 0; component < 4; component++)
1085 				{
1086 					if(context->textureActive(coordinate, component))
1087 					{
1088 						state.texture[coordinate].component |= 1 << component;
1089 
1090 						if(point && !sprite)
1091 						{
1092 							state.texture[coordinate].flat |= 1 << component;
1093 						}
1094 					}
1095 				}
1096 
1097 				if(context->textureTransformProject[coordinate] && context->pixelShaderModel() <= 0x0103)
1098 				{
1099 					if(context->textureTransformCount[coordinate] == 2)
1100 					{
1101 						state.texture[coordinate].project = 1;
1102 					}
1103 					else if(context->textureTransformCount[coordinate] == 3)
1104 					{
1105 						state.texture[coordinate].project = 2;
1106 					}
1107 					else if(context->textureTransformCount[coordinate] == 4 || context->textureTransformCount[coordinate] == 0)
1108 					{
1109 						state.texture[coordinate].project = 3;
1110 					}
1111 				}
1112 			}
1113 
1114 			for(int color = 0; color < 2; color++)
1115 			{
1116 				for(int component = 0; component < 4; component++)
1117 				{
1118 					if(context->colorActive(color, component))
1119 					{
1120 						state.color[color].component |= 1 << component;
1121 
1122 						if(point || flatShading)
1123 						{
1124 							state.color[color].flat |= 1 << component;
1125 						}
1126 					}
1127 				}
1128 			}
1129 
1130 			if(context->fogActive())
1131 			{
1132 				state.fog.component = true;
1133 
1134 				if(point)
1135 				{
1136 					state.fog.flat = true;
1137 				}
1138 			}
1139 		}
1140 		else
1141 		{
1142 			for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
1143 			{
1144 				for(int component = 0; component < 4; component++)
1145 				{
1146 					const Shader::Semantic &semantic = context->pixelShader->getInput(interpolant, component);
1147 
1148 					if(semantic.active())
1149 					{
1150 						bool flat = point;
1151 
1152 						switch(semantic.usage)
1153 						{
1154 						case Shader::USAGE_TEXCOORD: flat = point && !sprite;             break;
1155 						case Shader::USAGE_COLOR:    flat = semantic.flat || flatShading; break;
1156 						}
1157 
1158 						state.interpolant[interpolant].component |= 1 << component;
1159 
1160 						if(flat)
1161 						{
1162 							state.interpolant[interpolant].flat |= 1 << component;
1163 						}
1164 					}
1165 				}
1166 			}
1167 		}
1168 
1169 		if(state.centroid)
1170 		{
1171 			for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
1172 			{
1173 				for(int component = 0; component < 4; component++)
1174 				{
1175 					state.interpolant[interpolant].centroid = context->pixelShader->getInput(interpolant, 0).centroid;
1176 				}
1177 			}
1178 		}
1179 
1180 		state.hash = state.computeHash();
1181 
1182 		return state;
1183 	}
1184 
routine(const State & state)1185 	Routine *PixelProcessor::routine(const State &state)
1186 	{
1187 		Routine *routine = routineCache->query(state);
1188 
1189 		if(!routine)
1190 		{
1191 			const bool integerPipeline = (context->pixelShaderModel() <= 0x0104);
1192 			QuadRasterizer *generator = nullptr;
1193 
1194 			if(integerPipeline)
1195 			{
1196 				generator = new PixelPipeline(state, context->pixelShader);
1197 			}
1198 			else
1199 			{
1200 				generator = new PixelProgram(state, context->pixelShader);
1201 			}
1202 
1203 			generator->generate();
1204 			routine = (*generator)("PixelRoutine_%0.8X", state.shaderID);
1205 			delete generator;
1206 
1207 			routineCache->add(state, routine);
1208 		}
1209 
1210 		return routine;
1211 	}
1212 }
1213