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