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