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