blob: c927d5d13d80259a082dc688e81fe02e71d75468 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman89401822014-05-06 15:04:28 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// 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
John Bauman89401822014-05-06 15:04:28 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman89401822014-05-06 15:04:28 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// 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.
John Bauman89401822014-05-06 15:04:28 -040014
15#include "PixelProcessor.hpp"
16
John Bauman89401822014-05-06 15:04:28 -040017#include "Surface.hpp"
18#include "Primitive.hpp"
Nicolas Capens708c24b2017-10-26 13:07:10 -040019#include "Shader/PixelPipeline.hpp"
20#include "Shader/PixelProgram.hpp"
21#include "Shader/PixelShader.hpp"
22#include "Shader/Constants.hpp"
23#include "Common/Debug.hpp"
John Bauman89401822014-05-06 15:04:28 -040024
Nicolas Capens92eb0412019-08-20 14:13:17 -040025#include <cstring>
John Bauman66b8ab22014-05-06 15:57:45 -040026
John Bauman89401822014-05-06 15:04:28 -040027namespace sw
28{
29 extern bool complementaryDepthBuffer;
Nicolas Capensa0f4be82014-10-22 14:35:30 -040030 extern TransparencyAntialiasing transparencyAntialiasing;
John Bauman89401822014-05-06 15:04:28 -040031 extern bool perspectiveCorrection;
32
John Bauman66b8ab22014-05-06 15:57:45 -040033 bool precachePixel = false;
34
Nicolas Capens92eb0412019-08-20 14:13:17 -040035 uint32_t PixelProcessor::States::computeHash()
John Bauman89401822014-05-06 15:04:28 -040036 {
Nicolas Capens92eb0412019-08-20 14:13:17 -040037 uint32_t *state = reinterpret_cast<uint32_t*>(this);
38 uint32_t hash = 0;
John Bauman89401822014-05-06 15:04:28 -040039
Nicolas Capens92eb0412019-08-20 14:13:17 -040040 for(unsigned int i = 0; i < sizeof(States) / sizeof(uint32_t); i++)
John Bauman89401822014-05-06 15:04:28 -040041 {
42 hash ^= state[i];
43 }
44
45 return hash;
46 }
47
John Bauman89401822014-05-06 15:04:28 -040048 bool PixelProcessor::State::operator==(const State &state) const
49 {
50 if(hash != state.hash)
51 {
52 return false;
53 }
54
Nicolas Capens92eb0412019-08-20 14:13:17 -040055 static_assert(is_memcmparable<State>::value, "Cannot memcmp State");
John Bauman89401822014-05-06 15:04:28 -040056 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
57 }
58
Alexis Hetuc6a57cb2016-04-07 10:48:31 -040059 PixelProcessor::UniformBufferInfo::UniformBufferInfo()
60 {
61 buffer = nullptr;
62 offset = 0;
63 }
64
John Bauman89401822014-05-06 15:04:28 -040065 PixelProcessor::PixelProcessor(Context *context) : context(context)
66 {
67 setGlobalMipmapBias(0.0f); // Round to highest LOD [0.5, 1.0]: -0.5
68 // Round to nearest LOD [0.7, 1.4]: 0.0
69 // Round to lowest LOD [1.0, 2.0]: 0.5
70
71 routineCache = 0;
72 setRoutineCacheSize(1024);
73 }
74
75 PixelProcessor::~PixelProcessor()
76 {
77 delete routineCache;
Nicolas Capens92eb0412019-08-20 14:13:17 -040078 routineCache = nullptr;
John Bauman89401822014-05-06 15:04:28 -040079 }
80
81 void PixelProcessor::setFloatConstant(unsigned int index, const float value[4])
82 {
Alexis Hetu04c967a2015-07-08 15:56:17 -040083 if(index < FRAGMENT_UNIFORM_VECTORS)
John Bauman89401822014-05-06 15:04:28 -040084 {
85 c[index][0] = value[0];
86 c[index][1] = value[1];
87 c[index][2] = value[2];
88 c[index][3] = value[3];
89 }
90 else ASSERT(false);
91
92 if(index < 8) // ps_1_x constants
93 {
Nicolas Capensd55d9972018-10-18 13:47:29 -040094 // TODO: Compact into generic function
95 short x = iround(4095 * clamp_s(value[0], -1.0f, 1.0f));
96 short y = iround(4095 * clamp_s(value[1], -1.0f, 1.0f));
97 short z = iround(4095 * clamp_s(value[2], -1.0f, 1.0f));
98 short w = iround(4095 * clamp_s(value[3], -1.0f, 1.0f));
John Bauman89401822014-05-06 15:04:28 -040099
100 cW[index][0][0] = x;
101 cW[index][0][1] = x;
102 cW[index][0][2] = x;
103 cW[index][0][3] = x;
104
105 cW[index][1][0] = y;
106 cW[index][1][1] = y;
107 cW[index][1][2] = y;
108 cW[index][1][3] = y;
109
110 cW[index][2][0] = z;
111 cW[index][2][1] = z;
112 cW[index][2][2] = z;
113 cW[index][2][3] = z;
114
115 cW[index][3][0] = w;
116 cW[index][3][1] = w;
117 cW[index][3][2] = w;
118 cW[index][3][3] = w;
119 }
120 }
121
122 void PixelProcessor::setIntegerConstant(unsigned int index, const int value[4])
123 {
124 if(index < 16)
125 {
126 i[index][0] = value[0];
127 i[index][1] = value[1];
128 i[index][2] = value[2];
129 i[index][3] = value[3];
130 }
131 else ASSERT(false);
132 }
133
134 void PixelProcessor::setBooleanConstant(unsigned int index, int boolean)
135 {
136 if(index < 16)
137 {
138 b[index] = boolean != 0;
139 }
140 else ASSERT(false);
141 }
142
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400143 void PixelProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
144 {
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400145 uniformBufferInfo[index].buffer = buffer;
146 uniformBufferInfo[index].offset = offset;
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400147 }
148
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400149 void PixelProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[])
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400150 {
151 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
152 {
Alexis Hetuc6a57cb2016-04-07 10:48:31 -0400153 u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr;
154 uniformBuffers[i] = uniformBufferInfo[i].buffer;
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400155 }
156 }
157
Nicolas Capens8af24c52017-12-11 14:45:01 -0500158 void PixelProcessor::setRenderTarget(int index, Surface *renderTarget, unsigned int layer)
John Bauman89401822014-05-06 15:04:28 -0400159 {
160 context->renderTarget[index] = renderTarget;
Nicolas Capens8af24c52017-12-11 14:45:01 -0500161 context->renderTargetLayer[index] = layer;
John Bauman89401822014-05-06 15:04:28 -0400162 }
163
Nicolas Capens8af24c52017-12-11 14:45:01 -0500164 void PixelProcessor::setDepthBuffer(Surface *depthBuffer, unsigned int layer)
John Bauman89401822014-05-06 15:04:28 -0400165 {
Nicolas Capens3751c1e2016-03-21 14:14:14 -0400166 context->depthBuffer = depthBuffer;
Nicolas Capens8af24c52017-12-11 14:45:01 -0500167 context->depthBufferLayer = layer;
Nicolas Capens3751c1e2016-03-21 14:14:14 -0400168 }
169
Nicolas Capens8af24c52017-12-11 14:45:01 -0500170 void PixelProcessor::setStencilBuffer(Surface *stencilBuffer, unsigned int layer)
Nicolas Capens3751c1e2016-03-21 14:14:14 -0400171 {
172 context->stencilBuffer = stencilBuffer;
Nicolas Capens8af24c52017-12-11 14:45:01 -0500173 context->stencilBufferLayer = layer;
John Bauman89401822014-05-06 15:04:28 -0400174 }
175
176 void PixelProcessor::setTexCoordIndex(unsigned int stage, int texCoordIndex)
177 {
178 if(stage < 8)
179 {
180 context->textureStage[stage].setTexCoordIndex(texCoordIndex);
181 }
182 else ASSERT(false);
183 }
184
185 void PixelProcessor::setStageOperation(unsigned int stage, TextureStage::StageOperation stageOperation)
186 {
187 if(stage < 8)
188 {
189 context->textureStage[stage].setStageOperation(stageOperation);
190 }
191 else ASSERT(false);
192 }
193
194 void PixelProcessor::setFirstArgument(unsigned int stage, TextureStage::SourceArgument firstArgument)
195 {
196 if(stage < 8)
197 {
198 context->textureStage[stage].setFirstArgument(firstArgument);
199 }
200 else ASSERT(false);
201 }
202
203 void PixelProcessor::setSecondArgument(unsigned int stage, TextureStage::SourceArgument secondArgument)
204 {
205 if(stage < 8)
206 {
207 context->textureStage[stage].setSecondArgument(secondArgument);
208 }
209 else ASSERT(false);
210 }
211
212 void PixelProcessor::setThirdArgument(unsigned int stage, TextureStage::SourceArgument thirdArgument)
213 {
214 if(stage < 8)
215 {
216 context->textureStage[stage].setThirdArgument(thirdArgument);
217 }
218 else ASSERT(false);
219 }
220
221 void PixelProcessor::setStageOperationAlpha(unsigned int stage, TextureStage::StageOperation stageOperationAlpha)
222 {
223 if(stage < 8)
224 {
225 context->textureStage[stage].setStageOperationAlpha(stageOperationAlpha);
226 }
227 else ASSERT(false);
228 }
229
230 void PixelProcessor::setFirstArgumentAlpha(unsigned int stage, TextureStage::SourceArgument firstArgumentAlpha)
231 {
232 if(stage < 8)
233 {
234 context->textureStage[stage].setFirstArgumentAlpha(firstArgumentAlpha);
235 }
236 else ASSERT(false);
237 }
238
239 void PixelProcessor::setSecondArgumentAlpha(unsigned int stage, TextureStage::SourceArgument secondArgumentAlpha)
240 {
241 if(stage < 8)
242 {
243 context->textureStage[stage].setSecondArgumentAlpha(secondArgumentAlpha);
244 }
245 else ASSERT(false);
246 }
247
248 void PixelProcessor::setThirdArgumentAlpha(unsigned int stage, TextureStage::SourceArgument thirdArgumentAlpha)
249 {
250 if(stage < 8)
251 {
252 context->textureStage[stage].setThirdArgumentAlpha(thirdArgumentAlpha);
253 }
254 else ASSERT(false);
255 }
256
257 void PixelProcessor::setFirstModifier(unsigned int stage, TextureStage::ArgumentModifier firstModifier)
258 {
259 if(stage < 8)
260 {
261 context->textureStage[stage].setFirstModifier(firstModifier);
262 }
263 else ASSERT(false);
264 }
265
266 void PixelProcessor::setSecondModifier(unsigned int stage, TextureStage::ArgumentModifier secondModifier)
267 {
268 if(stage < 8)
269 {
270 context->textureStage[stage].setSecondModifier(secondModifier);
271 }
272 else ASSERT(false);
273 }
274
275 void PixelProcessor::setThirdModifier(unsigned int stage, TextureStage::ArgumentModifier thirdModifier)
276 {
277 if(stage < 8)
278 {
279 context->textureStage[stage].setThirdModifier(thirdModifier);
280 }
281 else ASSERT(false);
282 }
283
284 void PixelProcessor::setFirstModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier firstModifierAlpha)
285 {
286 if(stage < 8)
287 {
288 context->textureStage[stage].setFirstModifierAlpha(firstModifierAlpha);
289 }
290 else ASSERT(false);
291 }
292
293 void PixelProcessor::setSecondModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier secondModifierAlpha)
294 {
295 if(stage < 8)
296 {
297 context->textureStage[stage].setSecondModifierAlpha(secondModifierAlpha);
298 }
299 else ASSERT(false);
300 }
301
302 void PixelProcessor::setThirdModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier thirdModifierAlpha)
303 {
304 if(stage < 8)
305 {
306 context->textureStage[stage].setThirdModifierAlpha(thirdModifierAlpha);
307 }
308 else ASSERT(false);
309 }
310
311 void PixelProcessor::setDestinationArgument(unsigned int stage, TextureStage::DestinationArgument destinationArgument)
312 {
313 if(stage < 8)
314 {
315 context->textureStage[stage].setDestinationArgument(destinationArgument);
316 }
317 else ASSERT(false);
318 }
319
320 void PixelProcessor::setConstantColor(unsigned int stage, const Color<float> &constantColor)
321 {
322 if(stage < 8)
323 {
324 context->textureStage[stage].setConstantColor(constantColor);
325 }
326 else ASSERT(false);
327 }
328
329 void PixelProcessor::setBumpmapMatrix(unsigned int stage, int element, float value)
330 {
331 if(stage < 8)
332 {
333 context->textureStage[stage].setBumpmapMatrix(element, value);
334 }
335 else ASSERT(false);
336 }
337
338 void PixelProcessor::setLuminanceScale(unsigned int stage, float value)
339 {
340 if(stage < 8)
341 {
342 context->textureStage[stage].setLuminanceScale(value);
343 }
344 else ASSERT(false);
345 }
346
347 void PixelProcessor::setLuminanceOffset(unsigned int stage, float value)
348 {
349 if(stage < 8)
350 {
351 context->textureStage[stage].setLuminanceOffset(value);
352 }
353 else ASSERT(false);
354 }
355
356 void PixelProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
357 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400358 if(sampler < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400359 {
360 context->sampler[sampler].setTextureFilter(textureFilter);
361 }
362 else ASSERT(false);
363 }
364
365 void PixelProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
366 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400367 if(sampler < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400368 {
369 context->sampler[sampler].setMipmapFilter(mipmapFilter);
370 }
371 else ASSERT(false);
372 }
373
374 void PixelProcessor::setGatherEnable(unsigned int sampler, bool enable)
375 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400376 if(sampler < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400377 {
378 context->sampler[sampler].setGatherEnable(enable);
379 }
380 else ASSERT(false);
381 }
382
383 void PixelProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
384 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400385 if(sampler < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400386 {
387 context->sampler[sampler].setAddressingModeU(addressMode);
388 }
389 else ASSERT(false);
390 }
391
392 void PixelProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
393 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400394 if(sampler < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400395 {
396 context->sampler[sampler].setAddressingModeV(addressMode);
397 }
398 else ASSERT(false);
399 }
400
401 void PixelProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
402 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400403 if(sampler < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400404 {
405 context->sampler[sampler].setAddressingModeW(addressMode);
406 }
407 else ASSERT(false);
408 }
409
410 void PixelProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
411 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400412 if(sampler < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400413 {
414 context->sampler[sampler].setReadSRGB(sRGB);
415 }
416 else ASSERT(false);
417 }
418
419 void PixelProcessor::setMipmapLOD(unsigned int sampler, float bias)
420 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400421 if(sampler < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400422 {
423 context->sampler[sampler].setMipmapLOD(bias);
424 }
425 else ASSERT(false);
426 }
427
428 void PixelProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
429 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400430 if(sampler < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400431 {
432 context->sampler[sampler].setBorderColor(borderColor);
433 }
434 else ASSERT(false);
435 }
436
Alexis Hetu617a5d52014-11-13 10:56:20 -0500437 void PixelProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
John Bauman89401822014-05-06 15:04:28 -0400438 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400439 if(sampler < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400440 {
441 context->sampler[sampler].setMaxAnisotropy(maxAnisotropy);
442 }
443 else ASSERT(false);
444 }
445
Alexis Hetu010a4642017-07-18 14:33:04 -0400446 void PixelProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
447 {
448 if(sampler < TEXTURE_IMAGE_UNITS)
449 {
450 context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
451 }
452 else ASSERT(false);
453 }
454
Alexis Hetu1d01aa32015-09-29 11:50:05 -0400455 void PixelProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
456 {
457 if(sampler < TEXTURE_IMAGE_UNITS)
458 {
459 context->sampler[sampler].setSwizzleR(swizzleR);
460 }
461 else ASSERT(false);
462 }
463
464 void PixelProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
465 {
466 if(sampler < TEXTURE_IMAGE_UNITS)
467 {
468 context->sampler[sampler].setSwizzleG(swizzleG);
469 }
470 else ASSERT(false);
471 }
472
473 void PixelProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
474 {
475 if(sampler < TEXTURE_IMAGE_UNITS)
476 {
477 context->sampler[sampler].setSwizzleB(swizzleB);
478 }
479 else ASSERT(false);
480 }
481
482 void PixelProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
483 {
484 if(sampler < TEXTURE_IMAGE_UNITS)
485 {
486 context->sampler[sampler].setSwizzleA(swizzleA);
487 }
488 else ASSERT(false);
489 }
490
Nicolas Capensf878d502017-11-06 15:29:46 -0500491 void PixelProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
492 {
493 if(sampler < TEXTURE_IMAGE_UNITS)
494 {
495 context->sampler[sampler].setCompareFunc(compFunc);
496 }
497 else ASSERT(false);
498 }
499
Alexis Hetu95ac1872016-06-06 13:26:52 -0400500 void PixelProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
501 {
502 if(sampler < TEXTURE_IMAGE_UNITS)
503 {
504 context->sampler[sampler].setBaseLevel(baseLevel);
505 }
506 else ASSERT(false);
507 }
508
509 void PixelProcessor::setMaxLevel(unsigned int sampler, int maxLevel)
510 {
511 if(sampler < TEXTURE_IMAGE_UNITS)
512 {
513 context->sampler[sampler].setMaxLevel(maxLevel);
514 }
515 else ASSERT(false);
516 }
517
Alexis Hetu112d81f2016-06-07 12:36:35 -0400518 void PixelProcessor::setMinLod(unsigned int sampler, float minLod)
519 {
520 if(sampler < TEXTURE_IMAGE_UNITS)
521 {
522 context->sampler[sampler].setMinLod(minLod);
523 }
524 else ASSERT(false);
525 }
526
527 void PixelProcessor::setMaxLod(unsigned int sampler, float maxLod)
528 {
529 if(sampler < TEXTURE_IMAGE_UNITS)
530 {
531 context->sampler[sampler].setMaxLod(maxLod);
532 }
533 else ASSERT(false);
534 }
535
Alexis Hetu88482c32018-06-05 17:05:17 -0400536 void PixelProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired)
537 {
538 if(sampler < TEXTURE_IMAGE_UNITS)
539 {
540 context->sampler[sampler].setSyncRequired(isSincRequired);
541 }
542 else ASSERT(false);
543 }
544
John Bauman89401822014-05-06 15:04:28 -0400545 void PixelProcessor::setWriteSRGB(bool sRGB)
546 {
547 context->setWriteSRGB(sRGB);
548 }
549
Maxime Grégoired9762742015-07-08 16:43:48 -0400550 void PixelProcessor::setColorLogicOpEnabled(bool colorLogicOpEnabled)
551 {
552 context->setColorLogicOpEnabled(colorLogicOpEnabled);
553 }
554
555 void PixelProcessor::setLogicalOperation(LogicalOperation logicalOperation)
556 {
557 context->setLogicalOperation(logicalOperation);
558 }
559
John Bauman89401822014-05-06 15:04:28 -0400560 void PixelProcessor::setDepthBufferEnable(bool depthBufferEnable)
561 {
562 context->setDepthBufferEnable(depthBufferEnable);
563 }
564
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400565 void PixelProcessor::setDepthCompare(DepthCompareMode depthCompareMode)
John Bauman89401822014-05-06 15:04:28 -0400566 {
567 context->depthCompareMode = depthCompareMode;
568 }
569
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400570 void PixelProcessor::setAlphaCompare(AlphaCompareMode alphaCompareMode)
John Bauman89401822014-05-06 15:04:28 -0400571 {
572 context->alphaCompareMode = alphaCompareMode;
573 }
574
575 void PixelProcessor::setDepthWriteEnable(bool depthWriteEnable)
576 {
577 context->depthWriteEnable = depthWriteEnable;
578 }
579
580 void PixelProcessor::setAlphaTestEnable(bool alphaTestEnable)
581 {
582 context->alphaTestEnable = alphaTestEnable;
583 }
584
Nicolas Capensdd4c8632018-07-31 15:33:28 -0400585 void PixelProcessor::setCullMode(CullMode cullMode, bool frontFacingCCW)
John Bauman89401822014-05-06 15:04:28 -0400586 {
587 context->cullMode = cullMode;
Nicolas Capensdd4c8632018-07-31 15:33:28 -0400588 context->frontFacingCCW = frontFacingCCW;
John Bauman89401822014-05-06 15:04:28 -0400589 }
590
591 void PixelProcessor::setColorWriteMask(int index, int rgbaMask)
592 {
593 context->setColorWriteMask(index, rgbaMask);
594 }
595
596 void PixelProcessor::setStencilEnable(bool stencilEnable)
597 {
598 context->stencilEnable = stencilEnable;
599 }
600
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400601 void PixelProcessor::setStencilCompare(StencilCompareMode stencilCompareMode)
John Bauman89401822014-05-06 15:04:28 -0400602 {
603 context->stencilCompareMode = stencilCompareMode;
604 }
605
606 void PixelProcessor::setStencilReference(int stencilReference)
607 {
608 context->stencilReference = stencilReference;
609 stencil.set(stencilReference, context->stencilMask, context->stencilWriteMask);
610 }
611
612 void PixelProcessor::setStencilReferenceCCW(int stencilReferenceCCW)
613 {
614 context->stencilReferenceCCW = stencilReferenceCCW;
615 stencilCCW.set(stencilReferenceCCW, context->stencilMaskCCW, context->stencilWriteMaskCCW);
616 }
617
618 void PixelProcessor::setStencilMask(int stencilMask)
619 {
620 context->stencilMask = stencilMask;
621 stencil.set(context->stencilReference, stencilMask, context->stencilWriteMask);
622 }
623
624 void PixelProcessor::setStencilMaskCCW(int stencilMaskCCW)
625 {
626 context->stencilMaskCCW = stencilMaskCCW;
627 stencilCCW.set(context->stencilReferenceCCW, stencilMaskCCW, context->stencilWriteMaskCCW);
628 }
629
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400630 void PixelProcessor::setStencilFailOperation(StencilOperation stencilFailOperation)
John Bauman89401822014-05-06 15:04:28 -0400631 {
632 context->stencilFailOperation = stencilFailOperation;
633 }
634
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400635 void PixelProcessor::setStencilPassOperation(StencilOperation stencilPassOperation)
John Bauman89401822014-05-06 15:04:28 -0400636 {
637 context->stencilPassOperation = stencilPassOperation;
638 }
639
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400640 void PixelProcessor::setStencilZFailOperation(StencilOperation stencilZFailOperation)
John Bauman89401822014-05-06 15:04:28 -0400641 {
642 context->stencilZFailOperation = stencilZFailOperation;
643 }
644
645 void PixelProcessor::setStencilWriteMask(int stencilWriteMask)
646 {
647 context->stencilWriteMask = stencilWriteMask;
648 stencil.set(context->stencilReference, context->stencilMask, stencilWriteMask);
649 }
650
651 void PixelProcessor::setStencilWriteMaskCCW(int stencilWriteMaskCCW)
652 {
653 context->stencilWriteMaskCCW = stencilWriteMaskCCW;
654 stencilCCW.set(context->stencilReferenceCCW, context->stencilMaskCCW, stencilWriteMaskCCW);
655 }
656
657 void PixelProcessor::setTwoSidedStencil(bool enable)
658 {
659 context->twoSidedStencil = enable;
660 }
661
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400662 void PixelProcessor::setStencilCompareCCW(StencilCompareMode stencilCompareMode)
John Bauman89401822014-05-06 15:04:28 -0400663 {
664 context->stencilCompareModeCCW = stencilCompareMode;
665 }
666
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400667 void PixelProcessor::setStencilFailOperationCCW(StencilOperation stencilFailOperation)
John Bauman89401822014-05-06 15:04:28 -0400668 {
669 context->stencilFailOperationCCW = stencilFailOperation;
670 }
671
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400672 void PixelProcessor::setStencilPassOperationCCW(StencilOperation stencilPassOperation)
John Bauman89401822014-05-06 15:04:28 -0400673 {
674 context->stencilPassOperationCCW = stencilPassOperation;
675 }
676
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400677 void PixelProcessor::setStencilZFailOperationCCW(StencilOperation stencilZFailOperation)
John Bauman89401822014-05-06 15:04:28 -0400678 {
679 context->stencilZFailOperationCCW = stencilZFailOperation;
680 }
681
682 void PixelProcessor::setTextureFactor(const Color<float> &textureFactor)
683 {
684 // FIXME: Compact into generic function // FIXME: Clamp
685 short textureFactorR = iround(4095 * textureFactor.r);
686 short textureFactorG = iround(4095 * textureFactor.g);
687 short textureFactorB = iround(4095 * textureFactor.b);
688 short textureFactorA = iround(4095 * textureFactor.a);
689
690 factor.textureFactor4[0][0] = textureFactorR;
691 factor.textureFactor4[0][1] = textureFactorR;
692 factor.textureFactor4[0][2] = textureFactorR;
693 factor.textureFactor4[0][3] = textureFactorR;
694
695 factor.textureFactor4[1][0] = textureFactorG;
696 factor.textureFactor4[1][1] = textureFactorG;
697 factor.textureFactor4[1][2] = textureFactorG;
698 factor.textureFactor4[1][3] = textureFactorG;
699
700 factor.textureFactor4[2][0] = textureFactorB;
701 factor.textureFactor4[2][1] = textureFactorB;
702 factor.textureFactor4[2][2] = textureFactorB;
703 factor.textureFactor4[2][3] = textureFactorB;
704
705 factor.textureFactor4[3][0] = textureFactorA;
706 factor.textureFactor4[3][1] = textureFactorA;
707 factor.textureFactor4[3][2] = textureFactorA;
708 factor.textureFactor4[3][3] = textureFactorA;
709 }
710
711 void PixelProcessor::setBlendConstant(const Color<float> &blendConstant)
712 {
713 // FIXME: Compact into generic function // FIXME: Clamp
714 short blendConstantR = iround(65535 * blendConstant.r);
715 short blendConstantG = iround(65535 * blendConstant.g);
716 short blendConstantB = iround(65535 * blendConstant.b);
717 short blendConstantA = iround(65535 * blendConstant.a);
718
719 factor.blendConstant4W[0][0] = blendConstantR;
720 factor.blendConstant4W[0][1] = blendConstantR;
721 factor.blendConstant4W[0][2] = blendConstantR;
722 factor.blendConstant4W[0][3] = blendConstantR;
723
724 factor.blendConstant4W[1][0] = blendConstantG;
725 factor.blendConstant4W[1][1] = blendConstantG;
726 factor.blendConstant4W[1][2] = blendConstantG;
727 factor.blendConstant4W[1][3] = blendConstantG;
728
729 factor.blendConstant4W[2][0] = blendConstantB;
730 factor.blendConstant4W[2][1] = blendConstantB;
731 factor.blendConstant4W[2][2] = blendConstantB;
732 factor.blendConstant4W[2][3] = blendConstantB;
733
734 factor.blendConstant4W[3][0] = blendConstantA;
735 factor.blendConstant4W[3][1] = blendConstantA;
736 factor.blendConstant4W[3][2] = blendConstantA;
737 factor.blendConstant4W[3][3] = blendConstantA;
Nicolas Capens4f172c72016-01-13 08:34:30 -0500738
John Bauman89401822014-05-06 15:04:28 -0400739 // FIXME: Compact into generic function // FIXME: Clamp
740 short invBlendConstantR = iround(65535 * (1 - blendConstant.r));
741 short invBlendConstantG = iround(65535 * (1 - blendConstant.g));
742 short invBlendConstantB = iround(65535 * (1 - blendConstant.b));
743 short invBlendConstantA = iround(65535 * (1 - blendConstant.a));
744
745 factor.invBlendConstant4W[0][0] = invBlendConstantR;
746 factor.invBlendConstant4W[0][1] = invBlendConstantR;
747 factor.invBlendConstant4W[0][2] = invBlendConstantR;
748 factor.invBlendConstant4W[0][3] = invBlendConstantR;
749
750 factor.invBlendConstant4W[1][0] = invBlendConstantG;
751 factor.invBlendConstant4W[1][1] = invBlendConstantG;
752 factor.invBlendConstant4W[1][2] = invBlendConstantG;
753 factor.invBlendConstant4W[1][3] = invBlendConstantG;
754
755 factor.invBlendConstant4W[2][0] = invBlendConstantB;
756 factor.invBlendConstant4W[2][1] = invBlendConstantB;
757 factor.invBlendConstant4W[2][2] = invBlendConstantB;
758 factor.invBlendConstant4W[2][3] = invBlendConstantB;
759
760 factor.invBlendConstant4W[3][0] = invBlendConstantA;
761 factor.invBlendConstant4W[3][1] = invBlendConstantA;
762 factor.invBlendConstant4W[3][2] = invBlendConstantA;
763 factor.invBlendConstant4W[3][3] = invBlendConstantA;
764
765 factor.blendConstant4F[0][0] = blendConstant.r;
766 factor.blendConstant4F[0][1] = blendConstant.r;
767 factor.blendConstant4F[0][2] = blendConstant.r;
768 factor.blendConstant4F[0][3] = blendConstant.r;
769
770 factor.blendConstant4F[1][0] = blendConstant.g;
771 factor.blendConstant4F[1][1] = blendConstant.g;
772 factor.blendConstant4F[1][2] = blendConstant.g;
773 factor.blendConstant4F[1][3] = blendConstant.g;
Nicolas Capens4f172c72016-01-13 08:34:30 -0500774
John Bauman89401822014-05-06 15:04:28 -0400775 factor.blendConstant4F[2][0] = blendConstant.b;
776 factor.blendConstant4F[2][1] = blendConstant.b;
777 factor.blendConstant4F[2][2] = blendConstant.b;
778 factor.blendConstant4F[2][3] = blendConstant.b;
Nicolas Capens4f172c72016-01-13 08:34:30 -0500779
John Bauman89401822014-05-06 15:04:28 -0400780 factor.blendConstant4F[3][0] = blendConstant.a;
781 factor.blendConstant4F[3][1] = blendConstant.a;
782 factor.blendConstant4F[3][2] = blendConstant.a;
783 factor.blendConstant4F[3][3] = blendConstant.a;
784
785 factor.invBlendConstant4F[0][0] = 1 - blendConstant.r;
786 factor.invBlendConstant4F[0][1] = 1 - blendConstant.r;
787 factor.invBlendConstant4F[0][2] = 1 - blendConstant.r;
788 factor.invBlendConstant4F[0][3] = 1 - blendConstant.r;
789
790 factor.invBlendConstant4F[1][0] = 1 - blendConstant.g;
791 factor.invBlendConstant4F[1][1] = 1 - blendConstant.g;
792 factor.invBlendConstant4F[1][2] = 1 - blendConstant.g;
793 factor.invBlendConstant4F[1][3] = 1 - blendConstant.g;
Nicolas Capens4f172c72016-01-13 08:34:30 -0500794
John Bauman89401822014-05-06 15:04:28 -0400795 factor.invBlendConstant4F[2][0] = 1 - blendConstant.b;
796 factor.invBlendConstant4F[2][1] = 1 - blendConstant.b;
797 factor.invBlendConstant4F[2][2] = 1 - blendConstant.b;
798 factor.invBlendConstant4F[2][3] = 1 - blendConstant.b;
Nicolas Capens4f172c72016-01-13 08:34:30 -0500799
John Bauman89401822014-05-06 15:04:28 -0400800 factor.invBlendConstant4F[3][0] = 1 - blendConstant.a;
801 factor.invBlendConstant4F[3][1] = 1 - blendConstant.a;
802 factor.invBlendConstant4F[3][2] = 1 - blendConstant.a;
803 factor.invBlendConstant4F[3][3] = 1 - blendConstant.a;
804 }
805
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400806 void PixelProcessor::setFillMode(FillMode fillMode)
John Bauman89401822014-05-06 15:04:28 -0400807 {
808 context->fillMode = fillMode;
809 }
810
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400811 void PixelProcessor::setShadingMode(ShadingMode shadingMode)
John Bauman89401822014-05-06 15:04:28 -0400812 {
813 context->shadingMode = shadingMode;
814 }
815
816 void PixelProcessor::setAlphaBlendEnable(bool alphaBlendEnable)
817 {
818 context->setAlphaBlendEnable(alphaBlendEnable);
819 }
820
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400821 void PixelProcessor::setSourceBlendFactor(BlendFactor sourceBlendFactor)
John Bauman89401822014-05-06 15:04:28 -0400822 {
823 context->setSourceBlendFactor(sourceBlendFactor);
824 }
825
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400826 void PixelProcessor::setDestBlendFactor(BlendFactor destBlendFactor)
John Bauman89401822014-05-06 15:04:28 -0400827 {
828 context->setDestBlendFactor(destBlendFactor);
829 }
830
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400831 void PixelProcessor::setBlendOperation(BlendOperation blendOperation)
John Bauman89401822014-05-06 15:04:28 -0400832 {
833 context->setBlendOperation(blendOperation);
834 }
835
836 void PixelProcessor::setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)
837 {
838 context->setSeparateAlphaBlendEnable(separateAlphaBlendEnable);
839 }
840
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400841 void PixelProcessor::setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha)
John Bauman89401822014-05-06 15:04:28 -0400842 {
843 context->setSourceBlendFactorAlpha(sourceBlendFactorAlpha);
844 }
845
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400846 void PixelProcessor::setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha)
John Bauman89401822014-05-06 15:04:28 -0400847 {
848 context->setDestBlendFactorAlpha(destBlendFactorAlpha);
849 }
850
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400851 void PixelProcessor::setBlendOperationAlpha(BlendOperation blendOperationAlpha)
John Bauman89401822014-05-06 15:04:28 -0400852 {
853 context->setBlendOperationAlpha(blendOperationAlpha);
854 }
855
Alexis Hetua818c452015-06-11 13:06:58 -0400856 void PixelProcessor::setAlphaReference(float alphaReference)
John Bauman89401822014-05-06 15:04:28 -0400857 {
858 context->alphaReference = alphaReference;
859
Alexis Hetua818c452015-06-11 13:06:58 -0400860 factor.alphaReference4[0] = (word)iround(alphaReference * 0x1000 / 0xFF);
861 factor.alphaReference4[1] = (word)iround(alphaReference * 0x1000 / 0xFF);
862 factor.alphaReference4[2] = (word)iround(alphaReference * 0x1000 / 0xFF);
863 factor.alphaReference4[3] = (word)iround(alphaReference * 0x1000 / 0xFF);
John Bauman89401822014-05-06 15:04:28 -0400864 }
865
866 void PixelProcessor::setGlobalMipmapBias(float bias)
867 {
868 context->setGlobalMipmapBias(bias);
869 }
870
871 void PixelProcessor::setFogStart(float start)
872 {
873 setFogRanges(start, context->fogEnd);
874 }
875
876 void PixelProcessor::setFogEnd(float end)
877 {
878 setFogRanges(context->fogStart, end);
879 }
880
881 void PixelProcessor::setFogColor(Color<float> fogColor)
882 {
883 // TODO: Compact into generic function
884 word fogR = (unsigned short)(65535 * fogColor.r);
885 word fogG = (unsigned short)(65535 * fogColor.g);
886 word fogB = (unsigned short)(65535 * fogColor.b);
887
888 fog.color4[0][0] = fogR;
889 fog.color4[0][1] = fogR;
890 fog.color4[0][2] = fogR;
891 fog.color4[0][3] = fogR;
892
893 fog.color4[1][0] = fogG;
894 fog.color4[1][1] = fogG;
895 fog.color4[1][2] = fogG;
896 fog.color4[1][3] = fogG;
897
898 fog.color4[2][0] = fogB;
899 fog.color4[2][1] = fogB;
900 fog.color4[2][2] = fogB;
901 fog.color4[2][3] = fogB;
902
903 fog.colorF[0] = replicate(fogColor.r);
904 fog.colorF[1] = replicate(fogColor.g);
905 fog.colorF[2] = replicate(fogColor.b);
906 }
907
908 void PixelProcessor::setFogDensity(float fogDensity)
909 {
910 fog.densityE = replicate(-fogDensity * 1.442695f); // 1/e^x = 2^(-x*1.44)
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400911 fog.density2E = replicate(-fogDensity * fogDensity * 1.442695f);
John Bauman89401822014-05-06 15:04:28 -0400912 }
913
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400914 void PixelProcessor::setPixelFogMode(FogMode fogMode)
John Bauman89401822014-05-06 15:04:28 -0400915 {
916 context->pixelFogMode = fogMode;
917 }
918
919 void PixelProcessor::setPerspectiveCorrection(bool perspectiveEnable)
920 {
921 perspectiveCorrection = perspectiveEnable;
922 }
923
924 void PixelProcessor::setOcclusionEnabled(bool enable)
925 {
926 context->occlusionEnabled = enable;
927 }
928
929 void PixelProcessor::setRoutineCacheSize(int cacheSize)
930 {
931 delete routineCache;
Alexis Hetuf2878342019-03-12 16:32:04 -0400932 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536));
John Bauman89401822014-05-06 15:04:28 -0400933 }
934
935 void PixelProcessor::setFogRanges(float start, float end)
936 {
937 context->fogStart = start;
938 context->fogEnd = end;
939
940 if(start == end)
941 {
942 end += 0.001f; // Hack: ensure there is a small range
943 }
944
945 float fogScale = -1.0f / (end - start);
946 float fogOffset = end * -fogScale;
947
948 fog.scale = replicate(fogScale);
949 fog.offset = replicate(fogOffset);
950 }
951
952 const PixelProcessor::State PixelProcessor::update() const
953 {
954 State state;
955
956 if(context->pixelShader)
957 {
John Bauman19bac1e2014-05-06 15:23:49 -0400958 state.shaderID = context->pixelShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400959 }
960 else
961 {
John Bauman19bac1e2014-05-06 15:23:49 -0400962 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400963 }
964
965 state.depthOverride = context->pixelShader && context->pixelShader->depthOverride();
John Bauman19bac1e2014-05-06 15:23:49 -0400966 state.shaderContainsKill = context->pixelShader ? context->pixelShader->containsKill() : false;
Nicolas Capens4f172c72016-01-13 08:34:30 -0500967
John Bauman89401822014-05-06 15:04:28 -0400968 if(context->alphaTestActive())
969 {
970 state.alphaCompareMode = context->alphaCompareMode;
971
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400972 state.transparencyAntialiasing = context->getMultiSampleCount() > 1 ? transparencyAntialiasing : TRANSPARENCY_NONE;
John Bauman89401822014-05-06 15:04:28 -0400973 }
974
975 state.depthWriteEnable = context->depthWriteActive();
976
977 if(context->stencilActive())
978 {
979 state.stencilActive = true;
980 state.stencilCompareMode = context->stencilCompareMode;
981 state.stencilFailOperation = context->stencilFailOperation;
982 state.stencilPassOperation = context->stencilPassOperation;
983 state.stencilZFailOperation = context->stencilZFailOperation;
984 state.noStencilMask = (context->stencilMask == 0xFF);
985 state.noStencilWriteMask = (context->stencilWriteMask == 0xFF);
986 state.stencilWriteMasked = (context->stencilWriteMask == 0x00);
987
988 state.twoSidedStencil = context->twoSidedStencil;
989 state.stencilCompareModeCCW = context->twoSidedStencil ? context->stencilCompareModeCCW : state.stencilCompareMode;
990 state.stencilFailOperationCCW = context->twoSidedStencil ? context->stencilFailOperationCCW : state.stencilFailOperation;
991 state.stencilPassOperationCCW = context->twoSidedStencil ? context->stencilPassOperationCCW : state.stencilPassOperation;
992 state.stencilZFailOperationCCW = context->twoSidedStencil ? context->stencilZFailOperationCCW : state.stencilZFailOperation;
993 state.noStencilMaskCCW = context->twoSidedStencil ? (context->stencilMaskCCW == 0xFF) : state.noStencilMask;
994 state.noStencilWriteMaskCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0xFF) : state.noStencilWriteMask;
995 state.stencilWriteMaskedCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0x00) : state.stencilWriteMasked;
996 }
997
998 if(context->depthBufferActive())
999 {
1000 state.depthTestActive = true;
1001 state.depthCompareMode = context->depthCompareMode;
Alexis Hetub9dda642016-10-06 11:25:32 -04001002 state.quadLayoutDepthBuffer = Surface::hasQuadLayout(context->depthBuffer->getInternalFormat());
John Bauman89401822014-05-06 15:04:28 -04001003 }
1004
1005 state.occlusionEnabled = context->occlusionEnabled;
1006
1007 state.fogActive = context->fogActive();
1008 state.pixelFogMode = context->pixelFogActive();
Nicolas Capensa0f4be82014-10-22 14:35:30 -04001009 state.wBasedFog = context->wBasedFog && context->pixelFogActive() != FOG_NONE;
John Bauman89401822014-05-06 15:04:28 -04001010 state.perspective = context->perspectiveActive();
Nicolas Capens3cbeac52017-09-15 11:49:31 -04001011 state.depthClamp = (context->depthBias != 0.0f) || (context->slopeDepthBias != 0.0f);
John Bauman89401822014-05-06 15:04:28 -04001012
1013 if(context->alphaBlendActive())
1014 {
1015 state.alphaBlendActive = true;
1016 state.sourceBlendFactor = context->sourceBlendFactor();
1017 state.destBlendFactor = context->destBlendFactor();
1018 state.blendOperation = context->blendOperation();
1019 state.sourceBlendFactorAlpha = context->sourceBlendFactorAlpha();
1020 state.destBlendFactorAlpha = context->destBlendFactorAlpha();
1021 state.blendOperationAlpha = context->blendOperationAlpha();
1022 }
Maxime Grégoired9762742015-07-08 16:43:48 -04001023
1024 state.logicalOperation = context->colorLogicOp();
1025
Alexis Hetu1edcd8b2015-11-05 11:12:41 -05001026 for(int i = 0; i < RENDERTARGETS; i++)
John Bauman89401822014-05-06 15:04:28 -04001027 {
Nicolas Capensc98186a2016-04-18 12:07:22 -04001028 state.colorWriteMask |= context->colorWriteActive(i) << (4 * i);
John Bauman89401822014-05-06 15:04:28 -04001029 state.targetFormat[i] = context->renderTargetInternalFormat(i);
1030 }
1031
John Bauman66b8ab22014-05-06 15:57:45 -04001032 state.writeSRGB = context->writeSRGB && context->renderTarget[0] && Surface::isSRGBwritable(context->renderTarget[0]->getExternalFormat());
1033 state.multiSample = context->getMultiSampleCount();
John Bauman89401822014-05-06 15:04:28 -04001034 state.multiSampleMask = context->multiSampleMask;
1035
1036 if(state.multiSample > 1 && context->pixelShader)
1037 {
1038 state.centroid = context->pixelShader->containsCentroid();
1039 }
1040
Nicolas Capensdd4c8632018-07-31 15:33:28 -04001041 state.frontFaceCCW = context->frontFacingCCW;
1042
John Bauman89401822014-05-06 15:04:28 -04001043 if(!context->pixelShader)
1044 {
1045 for(unsigned int i = 0; i < 8; i++)
1046 {
1047 state.textureStage[i] = context->textureStage[i].textureStageState();
1048 }
1049
1050 state.specularAdd = context->specularActive() && context->specularEnable;
1051 }
1052
1053 for(unsigned int i = 0; i < 16; i++)
1054 {
1055 if(context->pixelShader)
1056 {
1057 if(context->pixelShader->usesSampler(i))
1058 {
1059 state.sampler[i] = context->sampler[i].samplerState();
1060 }
1061 }
1062 else
1063 {
1064 if(i < 8 && state.textureStage[i].stageOperation != TextureStage::STAGE_DISABLE)
1065 {
1066 state.sampler[i] = context->sampler[i].samplerState();
1067 }
1068 else break;
1069 }
1070 }
1071
1072 const bool point = context->isDrawPoint(true);
1073 const bool sprite = context->pointSpriteActive();
Nicolas Capensa0f4be82014-10-22 14:35:30 -04001074 const bool flatShading = (context->shadingMode == SHADING_FLAT) || point;
John Bauman89401822014-05-06 15:04:28 -04001075
Alexis Hetu53ad4af2017-12-06 14:49:07 -05001076 if(context->pixelShaderModel() < 0x0300)
John Bauman89401822014-05-06 15:04:28 -04001077 {
1078 for(int coordinate = 0; coordinate < 8; coordinate++)
1079 {
1080 for(int component = 0; component < 4; component++)
1081 {
1082 if(context->textureActive(coordinate, component))
1083 {
1084 state.texture[coordinate].component |= 1 << component;
1085
1086 if(point && !sprite)
1087 {
1088 state.texture[coordinate].flat |= 1 << component;
1089 }
1090 }
1091 }
1092
Alexis Hetu53ad4af2017-12-06 14:49:07 -05001093 if(context->textureTransformProject[coordinate] && context->pixelShaderModel() <= 0x0103)
John Bauman89401822014-05-06 15:04:28 -04001094 {
1095 if(context->textureTransformCount[coordinate] == 2)
1096 {
1097 state.texture[coordinate].project = 1;
1098 }
1099 else if(context->textureTransformCount[coordinate] == 3)
1100 {
1101 state.texture[coordinate].project = 2;
1102 }
1103 else if(context->textureTransformCount[coordinate] == 4 || context->textureTransformCount[coordinate] == 0)
1104 {
1105 state.texture[coordinate].project = 3;
1106 }
1107 }
1108 }
1109
1110 for(int color = 0; color < 2; color++)
1111 {
1112 for(int component = 0; component < 4; component++)
1113 {
1114 if(context->colorActive(color, component))
1115 {
1116 state.color[color].component |= 1 << component;
Nicolas Capens4f172c72016-01-13 08:34:30 -05001117
John Bauman89401822014-05-06 15:04:28 -04001118 if(point || flatShading)
1119 {
1120 state.color[color].flat |= 1 << component;
1121 }
1122 }
1123 }
1124 }
1125
1126 if(context->fogActive())
1127 {
1128 state.fog.component = true;
Nicolas Capens4f172c72016-01-13 08:34:30 -05001129
John Bauman89401822014-05-06 15:04:28 -04001130 if(point)
1131 {
1132 state.fog.flat = true;
1133 }
1134 }
1135 }
1136 else
1137 {
Nicolas Capens3b4c93f2016-05-18 12:51:37 -04001138 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
John Bauman89401822014-05-06 15:04:28 -04001139 {
1140 for(int component = 0; component < 4; component++)
1141 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -04001142 const Shader::Semantic &semantic = context->pixelShader->getInput(interpolant, component);
Alexis Hetu12b00502016-05-20 13:01:11 -04001143
1144 if(semantic.active())
John Bauman89401822014-05-06 15:04:28 -04001145 {
1146 bool flat = point;
1147
Alexis Hetu12b00502016-05-20 13:01:11 -04001148 switch(semantic.usage)
John Bauman89401822014-05-06 15:04:28 -04001149 {
Alexis Hetu12b00502016-05-20 13:01:11 -04001150 case Shader::USAGE_TEXCOORD: flat = point && !sprite; break;
1151 case Shader::USAGE_COLOR: flat = semantic.flat || flatShading; break;
John Bauman89401822014-05-06 15:04:28 -04001152 }
1153
1154 state.interpolant[interpolant].component |= 1 << component;
1155
1156 if(flat)
1157 {
1158 state.interpolant[interpolant].flat |= 1 << component;
1159 }
1160 }
1161 }
1162 }
1163 }
1164
1165 if(state.centroid)
1166 {
Nicolas Capens3b4c93f2016-05-18 12:51:37 -04001167 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
John Bauman89401822014-05-06 15:04:28 -04001168 {
1169 for(int component = 0; component < 4; component++)
1170 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -04001171 state.interpolant[interpolant].centroid = context->pixelShader->getInput(interpolant, 0).centroid;
John Bauman89401822014-05-06 15:04:28 -04001172 }
1173 }
1174 }
1175
1176 state.hash = state.computeHash();
1177
1178 return state;
1179 }
1180
Ben Clayton6897e9b2019-07-16 17:27:27 +01001181 std::shared_ptr<Routine> PixelProcessor::routine(const State &state)
John Bauman89401822014-05-06 15:04:28 -04001182 {
Ben Clayton6897e9b2019-07-16 17:27:27 +01001183 auto routine = routineCache->query(state);
John Bauman89401822014-05-06 15:04:28 -04001184
1185 if(!routine)
1186 {
Alexis Hetu53ad4af2017-12-06 14:49:07 -05001187 const bool integerPipeline = (context->pixelShaderModel() <= 0x0104);
Nicolas Capensba53fbf2016-01-14 13:43:42 -05001188 QuadRasterizer *generator = nullptr;
Nicolas Capens4f172c72016-01-13 08:34:30 -05001189
Alexis Hetuf2a8c372015-07-13 11:08:41 -04001190 if(integerPipeline)
1191 {
1192 generator = new PixelPipeline(state, context->pixelShader);
1193 }
1194 else
1195 {
1196 generator = new PixelProgram(state, context->pixelShader);
1197 }
Nicolas Capens4f172c72016-01-13 08:34:30 -05001198
John Bauman89401822014-05-06 15:04:28 -04001199 generator->generate();
Chris Forbes878d4b02019-01-21 10:48:35 -08001200 routine = (*generator)("PixelRoutine_%0.8X", state.shaderID);
John Bauman89401822014-05-06 15:04:28 -04001201 delete generator;
1202
1203 routineCache->add(state, routine);
1204 }
1205
1206 return routine;
1207 }
1208}