1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "PixelProcessor.hpp" 16 17 #include "Surface.hpp" 18 #include "Primitive.hpp" 19 #include "Shader/PixelPipeline.hpp" 20 #include "Shader/PixelProgram.hpp" 21 #include "Shader/PixelShader.hpp" 22 #include "Shader/Constants.hpp" 23 #include "Common/Debug.hpp" 24 #include "Common/Memory.hpp" 25 26 #include <cstring> 27 28 namespace sw 29 { 30 extern bool complementaryDepthBuffer; 31 extern TransparencyAntialiasing transparencyAntialiasing; 32 extern bool perspectiveCorrection; 33 34 bool precachePixel = false; 35 computeHash()36 uint32_t PixelProcessor::States::computeHash() 37 { 38 uint32_t *state = reinterpret_cast<uint32_t*>(this); 39 uint32_t hash = 0; 40 41 for(unsigned int i = 0; i < sizeof(States) / sizeof(uint32_t); i++) 42 { 43 hash ^= state[i]; 44 } 45 46 return hash; 47 } 48 operator ==(const State & state) const49 bool PixelProcessor::State::operator==(const State &state) const 50 { 51 if(hash != state.hash) 52 { 53 return false; 54 } 55 56 static_assert(is_memcmparable<State>::value, "Cannot memcmp State"); 57 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0; 58 } 59 UniformBufferInfo()60 PixelProcessor::UniformBufferInfo::UniformBufferInfo() 61 { 62 buffer = nullptr; 63 offset = 0; 64 } 65 PixelProcessor(Context * context)66 PixelProcessor::PixelProcessor(Context *context) : context(context) 67 { 68 setGlobalMipmapBias(0.0f); // Round to highest LOD [0.5, 1.0]: -0.5 69 // Round to nearest LOD [0.7, 1.4]: 0.0 70 // Round to lowest LOD [1.0, 2.0]: 0.5 71 72 routineCache = 0; 73 setRoutineCacheSize(1024); 74 } 75 ~PixelProcessor()76 PixelProcessor::~PixelProcessor() 77 { 78 delete routineCache; 79 routineCache = nullptr; 80 } 81 82 // This object has to be mem aligned operator new(size_t size)83 void *PixelProcessor::operator new(size_t size) 84 { 85 ASSERT(size == sizeof(PixelProcessor)); // This operator can't be called from a derived class 86 return sw::allocate(sizeof(PixelProcessor), 16); 87 } 88 operator delete(void * mem)89 void PixelProcessor::operator delete(void *mem) 90 { 91 sw::deallocate(mem); 92 } 93 setFloatConstant(unsigned int index,const float value[4])94 void PixelProcessor::setFloatConstant(unsigned int index, const float value[4]) 95 { 96 if(index < FRAGMENT_UNIFORM_VECTORS) 97 { 98 c[index][0] = value[0]; 99 c[index][1] = value[1]; 100 c[index][2] = value[2]; 101 c[index][3] = value[3]; 102 } 103 else ASSERT(false); 104 105 if(index < 8) // ps_1_x constants 106 { 107 // TODO: Compact into generic function 108 short x = iround(4095 * clamp_s(value[0], -1.0f, 1.0f)); 109 short y = iround(4095 * clamp_s(value[1], -1.0f, 1.0f)); 110 short z = iround(4095 * clamp_s(value[2], -1.0f, 1.0f)); 111 short w = iround(4095 * clamp_s(value[3], -1.0f, 1.0f)); 112 113 cW[index][0][0] = x; 114 cW[index][0][1] = x; 115 cW[index][0][2] = x; 116 cW[index][0][3] = x; 117 118 cW[index][1][0] = y; 119 cW[index][1][1] = y; 120 cW[index][1][2] = y; 121 cW[index][1][3] = y; 122 123 cW[index][2][0] = z; 124 cW[index][2][1] = z; 125 cW[index][2][2] = z; 126 cW[index][2][3] = z; 127 128 cW[index][3][0] = w; 129 cW[index][3][1] = w; 130 cW[index][3][2] = w; 131 cW[index][3][3] = w; 132 } 133 } 134 setIntegerConstant(unsigned int index,const int value[4])135 void PixelProcessor::setIntegerConstant(unsigned int index, const int value[4]) 136 { 137 if(index < 16) 138 { 139 i[index][0] = value[0]; 140 i[index][1] = value[1]; 141 i[index][2] = value[2]; 142 i[index][3] = value[3]; 143 } 144 else ASSERT(false); 145 } 146 setBooleanConstant(unsigned int index,int boolean)147 void PixelProcessor::setBooleanConstant(unsigned int index, int boolean) 148 { 149 if(index < 16) 150 { 151 b[index] = boolean != 0; 152 } 153 else ASSERT(false); 154 } 155 setUniformBuffer(int index,sw::Resource * buffer,int offset)156 void PixelProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset) 157 { 158 uniformBufferInfo[index].buffer = buffer; 159 uniformBufferInfo[index].offset = offset; 160 } 161 lockUniformBuffers(byte ** u,sw::Resource * uniformBuffers[])162 void PixelProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]) 163 { 164 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i) 165 { 166 u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr; 167 uniformBuffers[i] = uniformBufferInfo[i].buffer; 168 } 169 } 170 setRenderTarget(int index,Surface * renderTarget,unsigned int layer)171 void PixelProcessor::setRenderTarget(int index, Surface *renderTarget, unsigned int layer) 172 { 173 context->renderTarget[index] = renderTarget; 174 context->renderTargetLayer[index] = layer; 175 } 176 setDepthBuffer(Surface * depthBuffer,unsigned int layer)177 void PixelProcessor::setDepthBuffer(Surface *depthBuffer, unsigned int layer) 178 { 179 context->depthBuffer = depthBuffer; 180 context->depthBufferLayer = layer; 181 } 182 setStencilBuffer(Surface * stencilBuffer,unsigned int layer)183 void PixelProcessor::setStencilBuffer(Surface *stencilBuffer, unsigned int layer) 184 { 185 context->stencilBuffer = stencilBuffer; 186 context->stencilBufferLayer = layer; 187 } 188 setTexCoordIndex(unsigned int stage,int texCoordIndex)189 void PixelProcessor::setTexCoordIndex(unsigned int stage, int texCoordIndex) 190 { 191 if(stage < 8) 192 { 193 context->textureStage[stage].setTexCoordIndex(texCoordIndex); 194 } 195 else ASSERT(false); 196 } 197 setStageOperation(unsigned int stage,TextureStage::StageOperation stageOperation)198 void PixelProcessor::setStageOperation(unsigned int stage, TextureStage::StageOperation stageOperation) 199 { 200 if(stage < 8) 201 { 202 context->textureStage[stage].setStageOperation(stageOperation); 203 } 204 else ASSERT(false); 205 } 206 setFirstArgument(unsigned int stage,TextureStage::SourceArgument firstArgument)207 void PixelProcessor::setFirstArgument(unsigned int stage, TextureStage::SourceArgument firstArgument) 208 { 209 if(stage < 8) 210 { 211 context->textureStage[stage].setFirstArgument(firstArgument); 212 } 213 else ASSERT(false); 214 } 215 setSecondArgument(unsigned int stage,TextureStage::SourceArgument secondArgument)216 void PixelProcessor::setSecondArgument(unsigned int stage, TextureStage::SourceArgument secondArgument) 217 { 218 if(stage < 8) 219 { 220 context->textureStage[stage].setSecondArgument(secondArgument); 221 } 222 else ASSERT(false); 223 } 224 setThirdArgument(unsigned int stage,TextureStage::SourceArgument thirdArgument)225 void PixelProcessor::setThirdArgument(unsigned int stage, TextureStage::SourceArgument thirdArgument) 226 { 227 if(stage < 8) 228 { 229 context->textureStage[stage].setThirdArgument(thirdArgument); 230 } 231 else ASSERT(false); 232 } 233 setStageOperationAlpha(unsigned int stage,TextureStage::StageOperation stageOperationAlpha)234 void PixelProcessor::setStageOperationAlpha(unsigned int stage, TextureStage::StageOperation stageOperationAlpha) 235 { 236 if(stage < 8) 237 { 238 context->textureStage[stage].setStageOperationAlpha(stageOperationAlpha); 239 } 240 else ASSERT(false); 241 } 242 setFirstArgumentAlpha(unsigned int stage,TextureStage::SourceArgument firstArgumentAlpha)243 void PixelProcessor::setFirstArgumentAlpha(unsigned int stage, TextureStage::SourceArgument firstArgumentAlpha) 244 { 245 if(stage < 8) 246 { 247 context->textureStage[stage].setFirstArgumentAlpha(firstArgumentAlpha); 248 } 249 else ASSERT(false); 250 } 251 setSecondArgumentAlpha(unsigned int stage,TextureStage::SourceArgument secondArgumentAlpha)252 void PixelProcessor::setSecondArgumentAlpha(unsigned int stage, TextureStage::SourceArgument secondArgumentAlpha) 253 { 254 if(stage < 8) 255 { 256 context->textureStage[stage].setSecondArgumentAlpha(secondArgumentAlpha); 257 } 258 else ASSERT(false); 259 } 260 setThirdArgumentAlpha(unsigned int stage,TextureStage::SourceArgument thirdArgumentAlpha)261 void PixelProcessor::setThirdArgumentAlpha(unsigned int stage, TextureStage::SourceArgument thirdArgumentAlpha) 262 { 263 if(stage < 8) 264 { 265 context->textureStage[stage].setThirdArgumentAlpha(thirdArgumentAlpha); 266 } 267 else ASSERT(false); 268 } 269 setFirstModifier(unsigned int stage,TextureStage::ArgumentModifier firstModifier)270 void PixelProcessor::setFirstModifier(unsigned int stage, TextureStage::ArgumentModifier firstModifier) 271 { 272 if(stage < 8) 273 { 274 context->textureStage[stage].setFirstModifier(firstModifier); 275 } 276 else ASSERT(false); 277 } 278 setSecondModifier(unsigned int stage,TextureStage::ArgumentModifier secondModifier)279 void PixelProcessor::setSecondModifier(unsigned int stage, TextureStage::ArgumentModifier secondModifier) 280 { 281 if(stage < 8) 282 { 283 context->textureStage[stage].setSecondModifier(secondModifier); 284 } 285 else ASSERT(false); 286 } 287 setThirdModifier(unsigned int stage,TextureStage::ArgumentModifier thirdModifier)288 void PixelProcessor::setThirdModifier(unsigned int stage, TextureStage::ArgumentModifier thirdModifier) 289 { 290 if(stage < 8) 291 { 292 context->textureStage[stage].setThirdModifier(thirdModifier); 293 } 294 else ASSERT(false); 295 } 296 setFirstModifierAlpha(unsigned int stage,TextureStage::ArgumentModifier firstModifierAlpha)297 void PixelProcessor::setFirstModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier firstModifierAlpha) 298 { 299 if(stage < 8) 300 { 301 context->textureStage[stage].setFirstModifierAlpha(firstModifierAlpha); 302 } 303 else ASSERT(false); 304 } 305 setSecondModifierAlpha(unsigned int stage,TextureStage::ArgumentModifier secondModifierAlpha)306 void PixelProcessor::setSecondModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier secondModifierAlpha) 307 { 308 if(stage < 8) 309 { 310 context->textureStage[stage].setSecondModifierAlpha(secondModifierAlpha); 311 } 312 else ASSERT(false); 313 } 314 setThirdModifierAlpha(unsigned int stage,TextureStage::ArgumentModifier thirdModifierAlpha)315 void PixelProcessor::setThirdModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier thirdModifierAlpha) 316 { 317 if(stage < 8) 318 { 319 context->textureStage[stage].setThirdModifierAlpha(thirdModifierAlpha); 320 } 321 else ASSERT(false); 322 } 323 setDestinationArgument(unsigned int stage,TextureStage::DestinationArgument destinationArgument)324 void PixelProcessor::setDestinationArgument(unsigned int stage, TextureStage::DestinationArgument destinationArgument) 325 { 326 if(stage < 8) 327 { 328 context->textureStage[stage].setDestinationArgument(destinationArgument); 329 } 330 else ASSERT(false); 331 } 332 setConstantColor(unsigned int stage,const Color<float> & constantColor)333 void PixelProcessor::setConstantColor(unsigned int stage, const Color<float> &constantColor) 334 { 335 if(stage < 8) 336 { 337 context->textureStage[stage].setConstantColor(constantColor); 338 } 339 else ASSERT(false); 340 } 341 setBumpmapMatrix(unsigned int stage,int element,float value)342 void PixelProcessor::setBumpmapMatrix(unsigned int stage, int element, float value) 343 { 344 if(stage < 8) 345 { 346 context->textureStage[stage].setBumpmapMatrix(element, value); 347 } 348 else ASSERT(false); 349 } 350 setLuminanceScale(unsigned int stage,float value)351 void PixelProcessor::setLuminanceScale(unsigned int stage, float value) 352 { 353 if(stage < 8) 354 { 355 context->textureStage[stage].setLuminanceScale(value); 356 } 357 else ASSERT(false); 358 } 359 setLuminanceOffset(unsigned int stage,float value)360 void PixelProcessor::setLuminanceOffset(unsigned int stage, float value) 361 { 362 if(stage < 8) 363 { 364 context->textureStage[stage].setLuminanceOffset(value); 365 } 366 else ASSERT(false); 367 } 368 setTextureFilter(unsigned int sampler,FilterType textureFilter)369 void PixelProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter) 370 { 371 if(sampler < TEXTURE_IMAGE_UNITS) 372 { 373 context->sampler[sampler].setTextureFilter(textureFilter); 374 } 375 else ASSERT(false); 376 } 377 setMipmapFilter(unsigned int sampler,MipmapType mipmapFilter)378 void PixelProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter) 379 { 380 if(sampler < TEXTURE_IMAGE_UNITS) 381 { 382 context->sampler[sampler].setMipmapFilter(mipmapFilter); 383 } 384 else ASSERT(false); 385 } 386 setGatherEnable(unsigned int sampler,bool enable)387 void PixelProcessor::setGatherEnable(unsigned int sampler, bool enable) 388 { 389 if(sampler < TEXTURE_IMAGE_UNITS) 390 { 391 context->sampler[sampler].setGatherEnable(enable); 392 } 393 else ASSERT(false); 394 } 395 setAddressingModeU(unsigned int sampler,AddressingMode addressMode)396 void PixelProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode) 397 { 398 if(sampler < TEXTURE_IMAGE_UNITS) 399 { 400 context->sampler[sampler].setAddressingModeU(addressMode); 401 } 402 else ASSERT(false); 403 } 404 setAddressingModeV(unsigned int sampler,AddressingMode addressMode)405 void PixelProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode) 406 { 407 if(sampler < TEXTURE_IMAGE_UNITS) 408 { 409 context->sampler[sampler].setAddressingModeV(addressMode); 410 } 411 else ASSERT(false); 412 } 413 setAddressingModeW(unsigned int sampler,AddressingMode addressMode)414 void PixelProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode) 415 { 416 if(sampler < TEXTURE_IMAGE_UNITS) 417 { 418 context->sampler[sampler].setAddressingModeW(addressMode); 419 } 420 else ASSERT(false); 421 } 422 setReadSRGB(unsigned int sampler,bool sRGB)423 void PixelProcessor::setReadSRGB(unsigned int sampler, bool sRGB) 424 { 425 if(sampler < TEXTURE_IMAGE_UNITS) 426 { 427 context->sampler[sampler].setReadSRGB(sRGB); 428 } 429 else ASSERT(false); 430 } 431 setMipmapLOD(unsigned int sampler,float bias)432 void PixelProcessor::setMipmapLOD(unsigned int sampler, float bias) 433 { 434 if(sampler < TEXTURE_IMAGE_UNITS) 435 { 436 context->sampler[sampler].setMipmapLOD(bias); 437 } 438 else ASSERT(false); 439 } 440 setBorderColor(unsigned int sampler,const Color<float> & borderColor)441 void PixelProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor) 442 { 443 if(sampler < TEXTURE_IMAGE_UNITS) 444 { 445 context->sampler[sampler].setBorderColor(borderColor); 446 } 447 else ASSERT(false); 448 } 449 setMaxAnisotropy(unsigned int sampler,float maxAnisotropy)450 void PixelProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy) 451 { 452 if(sampler < TEXTURE_IMAGE_UNITS) 453 { 454 context->sampler[sampler].setMaxAnisotropy(maxAnisotropy); 455 } 456 else ASSERT(false); 457 } 458 setHighPrecisionFiltering(unsigned int sampler,bool highPrecisionFiltering)459 void PixelProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering) 460 { 461 if(sampler < TEXTURE_IMAGE_UNITS) 462 { 463 context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering); 464 } 465 else ASSERT(false); 466 } 467 setSwizzleR(unsigned int sampler,SwizzleType swizzleR)468 void PixelProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR) 469 { 470 if(sampler < TEXTURE_IMAGE_UNITS) 471 { 472 context->sampler[sampler].setSwizzleR(swizzleR); 473 } 474 else ASSERT(false); 475 } 476 setSwizzleG(unsigned int sampler,SwizzleType swizzleG)477 void PixelProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG) 478 { 479 if(sampler < TEXTURE_IMAGE_UNITS) 480 { 481 context->sampler[sampler].setSwizzleG(swizzleG); 482 } 483 else ASSERT(false); 484 } 485 setSwizzleB(unsigned int sampler,SwizzleType swizzleB)486 void PixelProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB) 487 { 488 if(sampler < TEXTURE_IMAGE_UNITS) 489 { 490 context->sampler[sampler].setSwizzleB(swizzleB); 491 } 492 else ASSERT(false); 493 } 494 setSwizzleA(unsigned int sampler,SwizzleType swizzleA)495 void PixelProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA) 496 { 497 if(sampler < TEXTURE_IMAGE_UNITS) 498 { 499 context->sampler[sampler].setSwizzleA(swizzleA); 500 } 501 else ASSERT(false); 502 } 503 setCompareFunc(unsigned int sampler,CompareFunc compFunc)504 void PixelProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc) 505 { 506 if(sampler < TEXTURE_IMAGE_UNITS) 507 { 508 context->sampler[sampler].setCompareFunc(compFunc); 509 } 510 else ASSERT(false); 511 } 512 setBaseLevel(unsigned int sampler,int baseLevel)513 void PixelProcessor::setBaseLevel(unsigned int sampler, int baseLevel) 514 { 515 if(sampler < TEXTURE_IMAGE_UNITS) 516 { 517 context->sampler[sampler].setBaseLevel(baseLevel); 518 } 519 else ASSERT(false); 520 } 521 setMaxLevel(unsigned int sampler,int maxLevel)522 void PixelProcessor::setMaxLevel(unsigned int sampler, int maxLevel) 523 { 524 if(sampler < TEXTURE_IMAGE_UNITS) 525 { 526 context->sampler[sampler].setMaxLevel(maxLevel); 527 } 528 else ASSERT(false); 529 } 530 setMinLod(unsigned int sampler,float minLod)531 void PixelProcessor::setMinLod(unsigned int sampler, float minLod) 532 { 533 if(sampler < TEXTURE_IMAGE_UNITS) 534 { 535 context->sampler[sampler].setMinLod(minLod); 536 } 537 else ASSERT(false); 538 } 539 setMaxLod(unsigned int sampler,float maxLod)540 void PixelProcessor::setMaxLod(unsigned int sampler, float maxLod) 541 { 542 if(sampler < TEXTURE_IMAGE_UNITS) 543 { 544 context->sampler[sampler].setMaxLod(maxLod); 545 } 546 else ASSERT(false); 547 } 548 setSyncRequired(unsigned int sampler,bool isSincRequired)549 void PixelProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired) 550 { 551 if(sampler < TEXTURE_IMAGE_UNITS) 552 { 553 context->sampler[sampler].setSyncRequired(isSincRequired); 554 } 555 else ASSERT(false); 556 } 557 setWriteSRGB(bool sRGB)558 void PixelProcessor::setWriteSRGB(bool sRGB) 559 { 560 context->setWriteSRGB(sRGB); 561 } 562 setColorLogicOpEnabled(bool colorLogicOpEnabled)563 void PixelProcessor::setColorLogicOpEnabled(bool colorLogicOpEnabled) 564 { 565 context->setColorLogicOpEnabled(colorLogicOpEnabled); 566 } 567 setLogicalOperation(LogicalOperation logicalOperation)568 void PixelProcessor::setLogicalOperation(LogicalOperation logicalOperation) 569 { 570 context->setLogicalOperation(logicalOperation); 571 } 572 setDepthBufferEnable(bool depthBufferEnable)573 void PixelProcessor::setDepthBufferEnable(bool depthBufferEnable) 574 { 575 context->setDepthBufferEnable(depthBufferEnable); 576 } 577 setDepthCompare(DepthCompareMode depthCompareMode)578 void PixelProcessor::setDepthCompare(DepthCompareMode depthCompareMode) 579 { 580 context->depthCompareMode = depthCompareMode; 581 } 582 setAlphaCompare(AlphaCompareMode alphaCompareMode)583 void PixelProcessor::setAlphaCompare(AlphaCompareMode alphaCompareMode) 584 { 585 context->alphaCompareMode = alphaCompareMode; 586 } 587 setDepthWriteEnable(bool depthWriteEnable)588 void PixelProcessor::setDepthWriteEnable(bool depthWriteEnable) 589 { 590 context->depthWriteEnable = depthWriteEnable; 591 } 592 setAlphaTestEnable(bool alphaTestEnable)593 void PixelProcessor::setAlphaTestEnable(bool alphaTestEnable) 594 { 595 context->alphaTestEnable = alphaTestEnable; 596 } 597 setCullMode(CullMode cullMode,bool frontFacingCCW)598 void PixelProcessor::setCullMode(CullMode cullMode, bool frontFacingCCW) 599 { 600 context->cullMode = cullMode; 601 context->frontFacingCCW = frontFacingCCW; 602 } 603 setColorWriteMask(int index,int rgbaMask)604 void PixelProcessor::setColorWriteMask(int index, int rgbaMask) 605 { 606 context->setColorWriteMask(index, rgbaMask); 607 } 608 setStencilEnable(bool stencilEnable)609 void PixelProcessor::setStencilEnable(bool stencilEnable) 610 { 611 context->stencilEnable = stencilEnable; 612 } 613 setStencilCompare(StencilCompareMode stencilCompareMode)614 void PixelProcessor::setStencilCompare(StencilCompareMode stencilCompareMode) 615 { 616 context->stencilCompareMode = stencilCompareMode; 617 } 618 setStencilReference(int stencilReference)619 void PixelProcessor::setStencilReference(int stencilReference) 620 { 621 context->stencilReference = stencilReference; 622 stencil.set(stencilReference, context->stencilMask, context->stencilWriteMask); 623 } 624 setStencilReferenceCCW(int stencilReferenceCCW)625 void PixelProcessor::setStencilReferenceCCW(int stencilReferenceCCW) 626 { 627 context->stencilReferenceCCW = stencilReferenceCCW; 628 stencilCCW.set(stencilReferenceCCW, context->stencilMaskCCW, context->stencilWriteMaskCCW); 629 } 630 setStencilMask(int stencilMask)631 void PixelProcessor::setStencilMask(int stencilMask) 632 { 633 context->stencilMask = stencilMask; 634 stencil.set(context->stencilReference, stencilMask, context->stencilWriteMask); 635 } 636 setStencilMaskCCW(int stencilMaskCCW)637 void PixelProcessor::setStencilMaskCCW(int stencilMaskCCW) 638 { 639 context->stencilMaskCCW = stencilMaskCCW; 640 stencilCCW.set(context->stencilReferenceCCW, stencilMaskCCW, context->stencilWriteMaskCCW); 641 } 642 setStencilFailOperation(StencilOperation stencilFailOperation)643 void PixelProcessor::setStencilFailOperation(StencilOperation stencilFailOperation) 644 { 645 context->stencilFailOperation = stencilFailOperation; 646 } 647 setStencilPassOperation(StencilOperation stencilPassOperation)648 void PixelProcessor::setStencilPassOperation(StencilOperation stencilPassOperation) 649 { 650 context->stencilPassOperation = stencilPassOperation; 651 } 652 setStencilZFailOperation(StencilOperation stencilZFailOperation)653 void PixelProcessor::setStencilZFailOperation(StencilOperation stencilZFailOperation) 654 { 655 context->stencilZFailOperation = stencilZFailOperation; 656 } 657 setStencilWriteMask(int stencilWriteMask)658 void PixelProcessor::setStencilWriteMask(int stencilWriteMask) 659 { 660 context->stencilWriteMask = stencilWriteMask; 661 stencil.set(context->stencilReference, context->stencilMask, stencilWriteMask); 662 } 663 setStencilWriteMaskCCW(int stencilWriteMaskCCW)664 void PixelProcessor::setStencilWriteMaskCCW(int stencilWriteMaskCCW) 665 { 666 context->stencilWriteMaskCCW = stencilWriteMaskCCW; 667 stencilCCW.set(context->stencilReferenceCCW, context->stencilMaskCCW, stencilWriteMaskCCW); 668 } 669 setTwoSidedStencil(bool enable)670 void PixelProcessor::setTwoSidedStencil(bool enable) 671 { 672 context->twoSidedStencil = enable; 673 } 674 setStencilCompareCCW(StencilCompareMode stencilCompareMode)675 void PixelProcessor::setStencilCompareCCW(StencilCompareMode stencilCompareMode) 676 { 677 context->stencilCompareModeCCW = stencilCompareMode; 678 } 679 setStencilFailOperationCCW(StencilOperation stencilFailOperation)680 void PixelProcessor::setStencilFailOperationCCW(StencilOperation stencilFailOperation) 681 { 682 context->stencilFailOperationCCW = stencilFailOperation; 683 } 684 setStencilPassOperationCCW(StencilOperation stencilPassOperation)685 void PixelProcessor::setStencilPassOperationCCW(StencilOperation stencilPassOperation) 686 { 687 context->stencilPassOperationCCW = stencilPassOperation; 688 } 689 setStencilZFailOperationCCW(StencilOperation stencilZFailOperation)690 void PixelProcessor::setStencilZFailOperationCCW(StencilOperation stencilZFailOperation) 691 { 692 context->stencilZFailOperationCCW = stencilZFailOperation; 693 } 694 setTextureFactor(const Color<float> & textureFactor)695 void PixelProcessor::setTextureFactor(const Color<float> &textureFactor) 696 { 697 // FIXME: Compact into generic function // FIXME: Clamp 698 short textureFactorR = iround(4095 * textureFactor.r); 699 short textureFactorG = iround(4095 * textureFactor.g); 700 short textureFactorB = iround(4095 * textureFactor.b); 701 short textureFactorA = iround(4095 * textureFactor.a); 702 703 factor.textureFactor4[0][0] = textureFactorR; 704 factor.textureFactor4[0][1] = textureFactorR; 705 factor.textureFactor4[0][2] = textureFactorR; 706 factor.textureFactor4[0][3] = textureFactorR; 707 708 factor.textureFactor4[1][0] = textureFactorG; 709 factor.textureFactor4[1][1] = textureFactorG; 710 factor.textureFactor4[1][2] = textureFactorG; 711 factor.textureFactor4[1][3] = textureFactorG; 712 713 factor.textureFactor4[2][0] = textureFactorB; 714 factor.textureFactor4[2][1] = textureFactorB; 715 factor.textureFactor4[2][2] = textureFactorB; 716 factor.textureFactor4[2][3] = textureFactorB; 717 718 factor.textureFactor4[3][0] = textureFactorA; 719 factor.textureFactor4[3][1] = textureFactorA; 720 factor.textureFactor4[3][2] = textureFactorA; 721 factor.textureFactor4[3][3] = textureFactorA; 722 } 723 setBlendConstant(const Color<float> & blendConstant)724 void PixelProcessor::setBlendConstant(const Color<float> &blendConstant) 725 { 726 // FIXME: Compact into generic function // FIXME: Clamp 727 short blendConstantR = iround(65535 * blendConstant.r); 728 short blendConstantG = iround(65535 * blendConstant.g); 729 short blendConstantB = iround(65535 * blendConstant.b); 730 short blendConstantA = iround(65535 * blendConstant.a); 731 732 factor.blendConstant4W[0][0] = blendConstantR; 733 factor.blendConstant4W[0][1] = blendConstantR; 734 factor.blendConstant4W[0][2] = blendConstantR; 735 factor.blendConstant4W[0][3] = blendConstantR; 736 737 factor.blendConstant4W[1][0] = blendConstantG; 738 factor.blendConstant4W[1][1] = blendConstantG; 739 factor.blendConstant4W[1][2] = blendConstantG; 740 factor.blendConstant4W[1][3] = blendConstantG; 741 742 factor.blendConstant4W[2][0] = blendConstantB; 743 factor.blendConstant4W[2][1] = blendConstantB; 744 factor.blendConstant4W[2][2] = blendConstantB; 745 factor.blendConstant4W[2][3] = blendConstantB; 746 747 factor.blendConstant4W[3][0] = blendConstantA; 748 factor.blendConstant4W[3][1] = blendConstantA; 749 factor.blendConstant4W[3][2] = blendConstantA; 750 factor.blendConstant4W[3][3] = blendConstantA; 751 752 // FIXME: Compact into generic function // FIXME: Clamp 753 short invBlendConstantR = iround(65535 * (1 - blendConstant.r)); 754 short invBlendConstantG = iround(65535 * (1 - blendConstant.g)); 755 short invBlendConstantB = iround(65535 * (1 - blendConstant.b)); 756 short invBlendConstantA = iround(65535 * (1 - blendConstant.a)); 757 758 factor.invBlendConstant4W[0][0] = invBlendConstantR; 759 factor.invBlendConstant4W[0][1] = invBlendConstantR; 760 factor.invBlendConstant4W[0][2] = invBlendConstantR; 761 factor.invBlendConstant4W[0][3] = invBlendConstantR; 762 763 factor.invBlendConstant4W[1][0] = invBlendConstantG; 764 factor.invBlendConstant4W[1][1] = invBlendConstantG; 765 factor.invBlendConstant4W[1][2] = invBlendConstantG; 766 factor.invBlendConstant4W[1][3] = invBlendConstantG; 767 768 factor.invBlendConstant4W[2][0] = invBlendConstantB; 769 factor.invBlendConstant4W[2][1] = invBlendConstantB; 770 factor.invBlendConstant4W[2][2] = invBlendConstantB; 771 factor.invBlendConstant4W[2][3] = invBlendConstantB; 772 773 factor.invBlendConstant4W[3][0] = invBlendConstantA; 774 factor.invBlendConstant4W[3][1] = invBlendConstantA; 775 factor.invBlendConstant4W[3][2] = invBlendConstantA; 776 factor.invBlendConstant4W[3][3] = invBlendConstantA; 777 778 factor.blendConstant4F[0][0] = blendConstant.r; 779 factor.blendConstant4F[0][1] = blendConstant.r; 780 factor.blendConstant4F[0][2] = blendConstant.r; 781 factor.blendConstant4F[0][3] = blendConstant.r; 782 783 factor.blendConstant4F[1][0] = blendConstant.g; 784 factor.blendConstant4F[1][1] = blendConstant.g; 785 factor.blendConstant4F[1][2] = blendConstant.g; 786 factor.blendConstant4F[1][3] = blendConstant.g; 787 788 factor.blendConstant4F[2][0] = blendConstant.b; 789 factor.blendConstant4F[2][1] = blendConstant.b; 790 factor.blendConstant4F[2][2] = blendConstant.b; 791 factor.blendConstant4F[2][3] = blendConstant.b; 792 793 factor.blendConstant4F[3][0] = blendConstant.a; 794 factor.blendConstant4F[3][1] = blendConstant.a; 795 factor.blendConstant4F[3][2] = blendConstant.a; 796 factor.blendConstant4F[3][3] = blendConstant.a; 797 798 factor.invBlendConstant4F[0][0] = 1 - blendConstant.r; 799 factor.invBlendConstant4F[0][1] = 1 - blendConstant.r; 800 factor.invBlendConstant4F[0][2] = 1 - blendConstant.r; 801 factor.invBlendConstant4F[0][3] = 1 - blendConstant.r; 802 803 factor.invBlendConstant4F[1][0] = 1 - blendConstant.g; 804 factor.invBlendConstant4F[1][1] = 1 - blendConstant.g; 805 factor.invBlendConstant4F[1][2] = 1 - blendConstant.g; 806 factor.invBlendConstant4F[1][3] = 1 - blendConstant.g; 807 808 factor.invBlendConstant4F[2][0] = 1 - blendConstant.b; 809 factor.invBlendConstant4F[2][1] = 1 - blendConstant.b; 810 factor.invBlendConstant4F[2][2] = 1 - blendConstant.b; 811 factor.invBlendConstant4F[2][3] = 1 - blendConstant.b; 812 813 factor.invBlendConstant4F[3][0] = 1 - blendConstant.a; 814 factor.invBlendConstant4F[3][1] = 1 - blendConstant.a; 815 factor.invBlendConstant4F[3][2] = 1 - blendConstant.a; 816 factor.invBlendConstant4F[3][3] = 1 - blendConstant.a; 817 } 818 setFillMode(FillMode fillMode)819 void PixelProcessor::setFillMode(FillMode fillMode) 820 { 821 context->fillMode = fillMode; 822 } 823 setShadingMode(ShadingMode shadingMode)824 void PixelProcessor::setShadingMode(ShadingMode shadingMode) 825 { 826 context->shadingMode = shadingMode; 827 } 828 setAlphaBlendEnable(bool alphaBlendEnable)829 void PixelProcessor::setAlphaBlendEnable(bool alphaBlendEnable) 830 { 831 context->setAlphaBlendEnable(alphaBlendEnable); 832 } 833 setSourceBlendFactor(BlendFactor sourceBlendFactor)834 void PixelProcessor::setSourceBlendFactor(BlendFactor sourceBlendFactor) 835 { 836 context->setSourceBlendFactor(sourceBlendFactor); 837 } 838 setDestBlendFactor(BlendFactor destBlendFactor)839 void PixelProcessor::setDestBlendFactor(BlendFactor destBlendFactor) 840 { 841 context->setDestBlendFactor(destBlendFactor); 842 } 843 setBlendOperation(BlendOperation blendOperation)844 void PixelProcessor::setBlendOperation(BlendOperation blendOperation) 845 { 846 context->setBlendOperation(blendOperation); 847 } 848 setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)849 void PixelProcessor::setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable) 850 { 851 context->setSeparateAlphaBlendEnable(separateAlphaBlendEnable); 852 } 853 setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha)854 void PixelProcessor::setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha) 855 { 856 context->setSourceBlendFactorAlpha(sourceBlendFactorAlpha); 857 } 858 setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha)859 void PixelProcessor::setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha) 860 { 861 context->setDestBlendFactorAlpha(destBlendFactorAlpha); 862 } 863 setBlendOperationAlpha(BlendOperation blendOperationAlpha)864 void PixelProcessor::setBlendOperationAlpha(BlendOperation blendOperationAlpha) 865 { 866 context->setBlendOperationAlpha(blendOperationAlpha); 867 } 868 setAlphaReference(float alphaReference)869 void PixelProcessor::setAlphaReference(float alphaReference) 870 { 871 context->alphaReference = alphaReference; 872 873 factor.alphaReference4[0] = (word)iround(alphaReference * 0x1000 / 0xFF); 874 factor.alphaReference4[1] = (word)iround(alphaReference * 0x1000 / 0xFF); 875 factor.alphaReference4[2] = (word)iround(alphaReference * 0x1000 / 0xFF); 876 factor.alphaReference4[3] = (word)iround(alphaReference * 0x1000 / 0xFF); 877 } 878 setGlobalMipmapBias(float bias)879 void PixelProcessor::setGlobalMipmapBias(float bias) 880 { 881 context->setGlobalMipmapBias(bias); 882 } 883 setFogStart(float start)884 void PixelProcessor::setFogStart(float start) 885 { 886 setFogRanges(start, context->fogEnd); 887 } 888 setFogEnd(float end)889 void PixelProcessor::setFogEnd(float end) 890 { 891 setFogRanges(context->fogStart, end); 892 } 893 setFogColor(Color<float> fogColor)894 void PixelProcessor::setFogColor(Color<float> fogColor) 895 { 896 // TODO: Compact into generic function 897 word fogR = (unsigned short)(65535 * fogColor.r); 898 word fogG = (unsigned short)(65535 * fogColor.g); 899 word fogB = (unsigned short)(65535 * fogColor.b); 900 901 fog.color4[0][0] = fogR; 902 fog.color4[0][1] = fogR; 903 fog.color4[0][2] = fogR; 904 fog.color4[0][3] = fogR; 905 906 fog.color4[1][0] = fogG; 907 fog.color4[1][1] = fogG; 908 fog.color4[1][2] = fogG; 909 fog.color4[1][3] = fogG; 910 911 fog.color4[2][0] = fogB; 912 fog.color4[2][1] = fogB; 913 fog.color4[2][2] = fogB; 914 fog.color4[2][3] = fogB; 915 916 fog.colorF[0] = replicate(fogColor.r); 917 fog.colorF[1] = replicate(fogColor.g); 918 fog.colorF[2] = replicate(fogColor.b); 919 } 920 setFogDensity(float fogDensity)921 void PixelProcessor::setFogDensity(float fogDensity) 922 { 923 fog.densityE = replicate(-fogDensity * 1.442695f); // 1/e^x = 2^(-x*1.44) 924 fog.density2E = replicate(-fogDensity * fogDensity * 1.442695f); 925 } 926 setPixelFogMode(FogMode fogMode)927 void PixelProcessor::setPixelFogMode(FogMode fogMode) 928 { 929 context->pixelFogMode = fogMode; 930 } 931 setPerspectiveCorrection(bool perspectiveEnable)932 void PixelProcessor::setPerspectiveCorrection(bool perspectiveEnable) 933 { 934 perspectiveCorrection = perspectiveEnable; 935 } 936 setOcclusionEnabled(bool enable)937 void PixelProcessor::setOcclusionEnabled(bool enable) 938 { 939 context->occlusionEnabled = enable; 940 } 941 setRoutineCacheSize(int cacheSize)942 void PixelProcessor::setRoutineCacheSize(int cacheSize) 943 { 944 delete routineCache; 945 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536)); 946 } 947 setFogRanges(float start,float end)948 void PixelProcessor::setFogRanges(float start, float end) 949 { 950 context->fogStart = start; 951 context->fogEnd = end; 952 953 if(start == end) 954 { 955 end += 0.001f; // Hack: ensure there is a small range 956 } 957 958 float fogScale = -1.0f / (end - start); 959 float fogOffset = end * -fogScale; 960 961 fog.scale = replicate(fogScale); 962 fog.offset = replicate(fogOffset); 963 } 964 update() const965 const PixelProcessor::State PixelProcessor::update() const 966 { 967 State state; 968 969 if(context->pixelShader) 970 { 971 state.shaderID = context->pixelShader->getSerialID(); 972 } 973 else 974 { 975 state.shaderID = 0; 976 } 977 978 state.depthOverride = context->pixelShader && context->pixelShader->depthOverride(); 979 state.shaderContainsKill = context->pixelShader ? context->pixelShader->containsKill() : false; 980 981 if(context->alphaTestActive()) 982 { 983 state.alphaCompareMode = context->alphaCompareMode; 984 985 state.transparencyAntialiasing = context->getMultiSampleCount() > 1 ? transparencyAntialiasing : TRANSPARENCY_NONE; 986 } 987 988 state.depthWriteEnable = context->depthWriteActive(); 989 990 if(context->stencilActive()) 991 { 992 state.stencilActive = true; 993 state.stencilCompareMode = context->stencilCompareMode; 994 state.stencilFailOperation = context->stencilFailOperation; 995 state.stencilPassOperation = context->stencilPassOperation; 996 state.stencilZFailOperation = context->stencilZFailOperation; 997 state.noStencilMask = (context->stencilMask == 0xFF); 998 state.noStencilWriteMask = (context->stencilWriteMask == 0xFF); 999 state.stencilWriteMasked = (context->stencilWriteMask == 0x00); 1000 1001 state.twoSidedStencil = context->twoSidedStencil; 1002 state.stencilCompareModeCCW = context->twoSidedStencil ? context->stencilCompareModeCCW : state.stencilCompareMode; 1003 state.stencilFailOperationCCW = context->twoSidedStencil ? context->stencilFailOperationCCW : state.stencilFailOperation; 1004 state.stencilPassOperationCCW = context->twoSidedStencil ? context->stencilPassOperationCCW : state.stencilPassOperation; 1005 state.stencilZFailOperationCCW = context->twoSidedStencil ? context->stencilZFailOperationCCW : state.stencilZFailOperation; 1006 state.noStencilMaskCCW = context->twoSidedStencil ? (context->stencilMaskCCW == 0xFF) : state.noStencilMask; 1007 state.noStencilWriteMaskCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0xFF) : state.noStencilWriteMask; 1008 state.stencilWriteMaskedCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0x00) : state.stencilWriteMasked; 1009 } 1010 1011 if(context->depthBufferActive()) 1012 { 1013 state.depthTestActive = true; 1014 state.depthCompareMode = context->depthCompareMode; 1015 state.quadLayoutDepthBuffer = Surface::hasQuadLayout(context->depthBuffer->getInternalFormat()); 1016 } 1017 1018 state.occlusionEnabled = context->occlusionEnabled; 1019 1020 state.fogActive = context->fogActive(); 1021 state.pixelFogMode = context->pixelFogActive(); 1022 state.wBasedFog = context->wBasedFog && context->pixelFogActive() != FOG_NONE; 1023 state.perspective = context->perspectiveActive(); 1024 state.depthClamp = (context->depthBias != 0.0f) || (context->slopeDepthBias != 0.0f); 1025 1026 if(context->alphaBlendActive()) 1027 { 1028 state.alphaBlendActive = true; 1029 state.sourceBlendFactor = context->sourceBlendFactor(); 1030 state.destBlendFactor = context->destBlendFactor(); 1031 state.blendOperation = context->blendOperation(); 1032 state.sourceBlendFactorAlpha = context->sourceBlendFactorAlpha(); 1033 state.destBlendFactorAlpha = context->destBlendFactorAlpha(); 1034 state.blendOperationAlpha = context->blendOperationAlpha(); 1035 } 1036 1037 state.logicalOperation = context->colorLogicOp(); 1038 1039 for(int i = 0; i < RENDERTARGETS; i++) 1040 { 1041 state.colorWriteMask |= context->colorWriteActive(i) << (4 * i); 1042 state.targetFormat[i] = context->renderTargetInternalFormat(i); 1043 } 1044 1045 state.writeSRGB = context->writeSRGB && context->renderTarget[0] && Surface::isSRGBwritable(context->renderTarget[0]->getExternalFormat()); 1046 state.multiSample = context->getMultiSampleCount(); 1047 state.multiSampleMask = context->multiSampleMask; 1048 1049 if(state.multiSample > 1 && context->pixelShader) 1050 { 1051 state.centroid = context->pixelShader->containsCentroid(); 1052 } 1053 1054 state.frontFaceCCW = context->frontFacingCCW; 1055 1056 if(!context->pixelShader) 1057 { 1058 for(unsigned int i = 0; i < 8; i++) 1059 { 1060 state.textureStage[i] = context->textureStage[i].textureStageState(); 1061 } 1062 1063 state.specularAdd = context->specularActive() && context->specularEnable; 1064 } 1065 1066 for(unsigned int i = 0; i < 16; i++) 1067 { 1068 if(context->pixelShader) 1069 { 1070 if(context->pixelShader->usesSampler(i)) 1071 { 1072 state.sampler[i] = context->sampler[i].samplerState(); 1073 } 1074 } 1075 else 1076 { 1077 if(i < 8 && state.textureStage[i].stageOperation != TextureStage::STAGE_DISABLE) 1078 { 1079 state.sampler[i] = context->sampler[i].samplerState(); 1080 } 1081 else break; 1082 } 1083 } 1084 1085 const bool point = context->isDrawPoint(true); 1086 const bool sprite = context->pointSpriteActive(); 1087 const bool flatShading = (context->shadingMode == SHADING_FLAT) || point; 1088 1089 if(context->pixelShaderModel() < 0x0300) 1090 { 1091 for(int coordinate = 0; coordinate < 8; coordinate++) 1092 { 1093 for(int component = 0; component < 4; component++) 1094 { 1095 if(context->textureActive(coordinate, component)) 1096 { 1097 state.texture[coordinate].component |= 1 << component; 1098 1099 if(point && !sprite) 1100 { 1101 state.texture[coordinate].flat |= 1 << component; 1102 } 1103 } 1104 } 1105 1106 if(context->textureTransformProject[coordinate] && context->pixelShaderModel() <= 0x0103) 1107 { 1108 if(context->textureTransformCount[coordinate] == 2) 1109 { 1110 state.texture[coordinate].project = 1; 1111 } 1112 else if(context->textureTransformCount[coordinate] == 3) 1113 { 1114 state.texture[coordinate].project = 2; 1115 } 1116 else if(context->textureTransformCount[coordinate] == 4 || context->textureTransformCount[coordinate] == 0) 1117 { 1118 state.texture[coordinate].project = 3; 1119 } 1120 } 1121 } 1122 1123 for(int color = 0; color < 2; color++) 1124 { 1125 for(int component = 0; component < 4; component++) 1126 { 1127 if(context->colorActive(color, component)) 1128 { 1129 state.color[color].component |= 1 << component; 1130 1131 if(point || flatShading) 1132 { 1133 state.color[color].flat |= 1 << component; 1134 } 1135 } 1136 } 1137 } 1138 1139 if(context->fogActive()) 1140 { 1141 state.fog.component = true; 1142 1143 if(point) 1144 { 1145 state.fog.flat = true; 1146 } 1147 } 1148 } 1149 else 1150 { 1151 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++) 1152 { 1153 for(int component = 0; component < 4; component++) 1154 { 1155 const Shader::Semantic &semantic = context->pixelShader->getInput(interpolant, component); 1156 1157 if(semantic.active()) 1158 { 1159 bool flat = point; 1160 1161 switch(semantic.usage) 1162 { 1163 case Shader::USAGE_TEXCOORD: flat = point && !sprite; break; 1164 case Shader::USAGE_COLOR: flat = semantic.flat || flatShading; break; 1165 } 1166 1167 state.interpolant[interpolant].component |= 1 << component; 1168 1169 if(flat) 1170 { 1171 state.interpolant[interpolant].flat |= 1 << component; 1172 } 1173 } 1174 } 1175 } 1176 } 1177 1178 if(state.centroid) 1179 { 1180 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++) 1181 { 1182 for(int component = 0; component < 4; component++) 1183 { 1184 state.interpolant[interpolant].centroid = context->pixelShader->getInput(interpolant, 0).centroid; 1185 } 1186 } 1187 } 1188 1189 state.hash = state.computeHash(); 1190 1191 return state; 1192 } 1193 routine(const State & state)1194 std::shared_ptr<Routine> PixelProcessor::routine(const State &state) 1195 { 1196 auto routine = routineCache->query(state); 1197 1198 if(!routine) 1199 { 1200 const bool integerPipeline = (context->pixelShaderModel() <= 0x0104); 1201 QuadRasterizer *generator = nullptr; 1202 1203 if(integerPipeline) 1204 { 1205 generator = new PixelPipeline(state, context->pixelShader); 1206 } 1207 else 1208 { 1209 generator = new PixelProgram(state, context->pixelShader); 1210 } 1211 1212 generator->generate(); 1213 routine = (*generator)("PixelRoutine_%0.8X", state.shaderID); 1214 delete generator; 1215 1216 routineCache->add(state, routine); 1217 } 1218 1219 return routine; 1220 } 1221 } 1222