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