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 <cstring> 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 uint32_t PixelProcessor::States::computeHash() 36 { 37 uint32_t *state = reinterpret_cast<uint32_t*>(this); 38 uint32_t hash = 0; 39 40 for(unsigned int i = 0; i < sizeof(States) / sizeof(uint32_t); i++) 41 { 42 hash ^= state[i]; 43 } 44 45 return hash; 46 } 47 operator ==(const State & state) const48 bool PixelProcessor::State::operator==(const State &state) const 49 { 50 if(hash != state.hash) 51 { 52 return false; 53 } 54 55 static_assert(is_memcmparable<State>::value, "Cannot memcmp State"); 56 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0; 57 } 58 UniformBufferInfo()59 PixelProcessor::UniformBufferInfo::UniformBufferInfo() 60 { 61 buffer = nullptr; 62 offset = 0; 63 } 64 PixelProcessor(Context * context)65 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 ~PixelProcessor()75 PixelProcessor::~PixelProcessor() 76 { 77 delete routineCache; 78 routineCache = nullptr; 79 } 80 setFloatConstant(unsigned int index,const float value[4])81 void PixelProcessor::setFloatConstant(unsigned int index, const float value[4]) 82 { 83 if(index < FRAGMENT_UNIFORM_VECTORS) 84 { 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 { 94 // 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)); 99 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 setIntegerConstant(unsigned int index,const int value[4])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 setBooleanConstant(unsigned int index,int boolean)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 setUniformBuffer(int index,sw::Resource * buffer,int offset)143 void PixelProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset) 144 { 145 uniformBufferInfo[index].buffer = buffer; 146 uniformBufferInfo[index].offset = offset; 147 } 148 lockUniformBuffers(byte ** u,sw::Resource * uniformBuffers[])149 void PixelProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]) 150 { 151 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i) 152 { 153 u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr; 154 uniformBuffers[i] = uniformBufferInfo[i].buffer; 155 } 156 } 157 setRenderTarget(int index,Surface * renderTarget,unsigned int layer)158 void PixelProcessor::setRenderTarget(int index, Surface *renderTarget, unsigned int layer) 159 { 160 context->renderTarget[index] = renderTarget; 161 context->renderTargetLayer[index] = layer; 162 } 163 setDepthBuffer(Surface * depthBuffer,unsigned int layer)164 void PixelProcessor::setDepthBuffer(Surface *depthBuffer, unsigned int layer) 165 { 166 context->depthBuffer = depthBuffer; 167 context->depthBufferLayer = layer; 168 } 169 setStencilBuffer(Surface * stencilBuffer,unsigned int layer)170 void PixelProcessor::setStencilBuffer(Surface *stencilBuffer, unsigned int layer) 171 { 172 context->stencilBuffer = stencilBuffer; 173 context->stencilBufferLayer = layer; 174 } 175 setTexCoordIndex(unsigned int stage,int texCoordIndex)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 setStageOperation(unsigned int stage,TextureStage::StageOperation stageOperation)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 setFirstArgument(unsigned int stage,TextureStage::SourceArgument firstArgument)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 setSecondArgument(unsigned int stage,TextureStage::SourceArgument secondArgument)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 setThirdArgument(unsigned int stage,TextureStage::SourceArgument thirdArgument)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 setStageOperationAlpha(unsigned int stage,TextureStage::StageOperation stageOperationAlpha)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 setFirstArgumentAlpha(unsigned int stage,TextureStage::SourceArgument firstArgumentAlpha)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 setSecondArgumentAlpha(unsigned int stage,TextureStage::SourceArgument secondArgumentAlpha)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 setThirdArgumentAlpha(unsigned int stage,TextureStage::SourceArgument thirdArgumentAlpha)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 setFirstModifier(unsigned int stage,TextureStage::ArgumentModifier firstModifier)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 setSecondModifier(unsigned int stage,TextureStage::ArgumentModifier secondModifier)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 setThirdModifier(unsigned int stage,TextureStage::ArgumentModifier thirdModifier)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 setFirstModifierAlpha(unsigned int stage,TextureStage::ArgumentModifier firstModifierAlpha)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 setSecondModifierAlpha(unsigned int stage,TextureStage::ArgumentModifier secondModifierAlpha)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 setThirdModifierAlpha(unsigned int stage,TextureStage::ArgumentModifier thirdModifierAlpha)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 setDestinationArgument(unsigned int stage,TextureStage::DestinationArgument destinationArgument)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 setConstantColor(unsigned int stage,const Color<float> & constantColor)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 setBumpmapMatrix(unsigned int stage,int element,float value)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 setLuminanceScale(unsigned int stage,float value)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 setLuminanceOffset(unsigned int stage,float value)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 setTextureFilter(unsigned int sampler,FilterType textureFilter)356 void PixelProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter) 357 { 358 if(sampler < TEXTURE_IMAGE_UNITS) 359 { 360 context->sampler[sampler].setTextureFilter(textureFilter); 361 } 362 else ASSERT(false); 363 } 364 setMipmapFilter(unsigned int sampler,MipmapType mipmapFilter)365 void PixelProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter) 366 { 367 if(sampler < TEXTURE_IMAGE_UNITS) 368 { 369 context->sampler[sampler].setMipmapFilter(mipmapFilter); 370 } 371 else ASSERT(false); 372 } 373 setGatherEnable(unsigned int sampler,bool enable)374 void PixelProcessor::setGatherEnable(unsigned int sampler, bool enable) 375 { 376 if(sampler < TEXTURE_IMAGE_UNITS) 377 { 378 context->sampler[sampler].setGatherEnable(enable); 379 } 380 else ASSERT(false); 381 } 382 setAddressingModeU(unsigned int sampler,AddressingMode addressMode)383 void PixelProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode) 384 { 385 if(sampler < TEXTURE_IMAGE_UNITS) 386 { 387 context->sampler[sampler].setAddressingModeU(addressMode); 388 } 389 else ASSERT(false); 390 } 391 setAddressingModeV(unsigned int sampler,AddressingMode addressMode)392 void PixelProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode) 393 { 394 if(sampler < TEXTURE_IMAGE_UNITS) 395 { 396 context->sampler[sampler].setAddressingModeV(addressMode); 397 } 398 else ASSERT(false); 399 } 400 setAddressingModeW(unsigned int sampler,AddressingMode addressMode)401 void PixelProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode) 402 { 403 if(sampler < TEXTURE_IMAGE_UNITS) 404 { 405 context->sampler[sampler].setAddressingModeW(addressMode); 406 } 407 else ASSERT(false); 408 } 409 setReadSRGB(unsigned int sampler,bool sRGB)410 void PixelProcessor::setReadSRGB(unsigned int sampler, bool sRGB) 411 { 412 if(sampler < TEXTURE_IMAGE_UNITS) 413 { 414 context->sampler[sampler].setReadSRGB(sRGB); 415 } 416 else ASSERT(false); 417 } 418 setMipmapLOD(unsigned int sampler,float bias)419 void PixelProcessor::setMipmapLOD(unsigned int sampler, float bias) 420 { 421 if(sampler < TEXTURE_IMAGE_UNITS) 422 { 423 context->sampler[sampler].setMipmapLOD(bias); 424 } 425 else ASSERT(false); 426 } 427 setBorderColor(unsigned int sampler,const Color<float> & borderColor)428 void PixelProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor) 429 { 430 if(sampler < TEXTURE_IMAGE_UNITS) 431 { 432 context->sampler[sampler].setBorderColor(borderColor); 433 } 434 else ASSERT(false); 435 } 436 setMaxAnisotropy(unsigned int sampler,float maxAnisotropy)437 void PixelProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy) 438 { 439 if(sampler < TEXTURE_IMAGE_UNITS) 440 { 441 context->sampler[sampler].setMaxAnisotropy(maxAnisotropy); 442 } 443 else ASSERT(false); 444 } 445 setHighPrecisionFiltering(unsigned int sampler,bool highPrecisionFiltering)446 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 setSwizzleR(unsigned int sampler,SwizzleType swizzleR)455 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 setSwizzleG(unsigned int sampler,SwizzleType swizzleG)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 setSwizzleB(unsigned int sampler,SwizzleType swizzleB)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 setSwizzleA(unsigned int sampler,SwizzleType swizzleA)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 setCompareFunc(unsigned int sampler,CompareFunc compFunc)491 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 setBaseLevel(unsigned int sampler,int baseLevel)500 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 setMaxLevel(unsigned int sampler,int maxLevel)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 setMinLod(unsigned int sampler,float minLod)518 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 setMaxLod(unsigned int sampler,float maxLod)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 setSyncRequired(unsigned int sampler,bool isSincRequired)536 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 setWriteSRGB(bool sRGB)545 void PixelProcessor::setWriteSRGB(bool sRGB) 546 { 547 context->setWriteSRGB(sRGB); 548 } 549 setColorLogicOpEnabled(bool colorLogicOpEnabled)550 void PixelProcessor::setColorLogicOpEnabled(bool colorLogicOpEnabled) 551 { 552 context->setColorLogicOpEnabled(colorLogicOpEnabled); 553 } 554 setLogicalOperation(LogicalOperation logicalOperation)555 void PixelProcessor::setLogicalOperation(LogicalOperation logicalOperation) 556 { 557 context->setLogicalOperation(logicalOperation); 558 } 559 setDepthBufferEnable(bool depthBufferEnable)560 void PixelProcessor::setDepthBufferEnable(bool depthBufferEnable) 561 { 562 context->setDepthBufferEnable(depthBufferEnable); 563 } 564 setDepthCompare(DepthCompareMode depthCompareMode)565 void PixelProcessor::setDepthCompare(DepthCompareMode depthCompareMode) 566 { 567 context->depthCompareMode = depthCompareMode; 568 } 569 setAlphaCompare(AlphaCompareMode alphaCompareMode)570 void PixelProcessor::setAlphaCompare(AlphaCompareMode alphaCompareMode) 571 { 572 context->alphaCompareMode = alphaCompareMode; 573 } 574 setDepthWriteEnable(bool depthWriteEnable)575 void PixelProcessor::setDepthWriteEnable(bool depthWriteEnable) 576 { 577 context->depthWriteEnable = depthWriteEnable; 578 } 579 setAlphaTestEnable(bool alphaTestEnable)580 void PixelProcessor::setAlphaTestEnable(bool alphaTestEnable) 581 { 582 context->alphaTestEnable = alphaTestEnable; 583 } 584 setCullMode(CullMode cullMode,bool frontFacingCCW)585 void PixelProcessor::setCullMode(CullMode cullMode, bool frontFacingCCW) 586 { 587 context->cullMode = cullMode; 588 context->frontFacingCCW = frontFacingCCW; 589 } 590 setColorWriteMask(int index,int rgbaMask)591 void PixelProcessor::setColorWriteMask(int index, int rgbaMask) 592 { 593 context->setColorWriteMask(index, rgbaMask); 594 } 595 setStencilEnable(bool stencilEnable)596 void PixelProcessor::setStencilEnable(bool stencilEnable) 597 { 598 context->stencilEnable = stencilEnable; 599 } 600 setStencilCompare(StencilCompareMode stencilCompareMode)601 void PixelProcessor::setStencilCompare(StencilCompareMode stencilCompareMode) 602 { 603 context->stencilCompareMode = stencilCompareMode; 604 } 605 setStencilReference(int stencilReference)606 void PixelProcessor::setStencilReference(int stencilReference) 607 { 608 context->stencilReference = stencilReference; 609 stencil.set(stencilReference, context->stencilMask, context->stencilWriteMask); 610 } 611 setStencilReferenceCCW(int stencilReferenceCCW)612 void PixelProcessor::setStencilReferenceCCW(int stencilReferenceCCW) 613 { 614 context->stencilReferenceCCW = stencilReferenceCCW; 615 stencilCCW.set(stencilReferenceCCW, context->stencilMaskCCW, context->stencilWriteMaskCCW); 616 } 617 setStencilMask(int stencilMask)618 void PixelProcessor::setStencilMask(int stencilMask) 619 { 620 context->stencilMask = stencilMask; 621 stencil.set(context->stencilReference, stencilMask, context->stencilWriteMask); 622 } 623 setStencilMaskCCW(int stencilMaskCCW)624 void PixelProcessor::setStencilMaskCCW(int stencilMaskCCW) 625 { 626 context->stencilMaskCCW = stencilMaskCCW; 627 stencilCCW.set(context->stencilReferenceCCW, stencilMaskCCW, context->stencilWriteMaskCCW); 628 } 629 setStencilFailOperation(StencilOperation stencilFailOperation)630 void PixelProcessor::setStencilFailOperation(StencilOperation stencilFailOperation) 631 { 632 context->stencilFailOperation = stencilFailOperation; 633 } 634 setStencilPassOperation(StencilOperation stencilPassOperation)635 void PixelProcessor::setStencilPassOperation(StencilOperation stencilPassOperation) 636 { 637 context->stencilPassOperation = stencilPassOperation; 638 } 639 setStencilZFailOperation(StencilOperation stencilZFailOperation)640 void PixelProcessor::setStencilZFailOperation(StencilOperation stencilZFailOperation) 641 { 642 context->stencilZFailOperation = stencilZFailOperation; 643 } 644 setStencilWriteMask(int stencilWriteMask)645 void PixelProcessor::setStencilWriteMask(int stencilWriteMask) 646 { 647 context->stencilWriteMask = stencilWriteMask; 648 stencil.set(context->stencilReference, context->stencilMask, stencilWriteMask); 649 } 650 setStencilWriteMaskCCW(int stencilWriteMaskCCW)651 void PixelProcessor::setStencilWriteMaskCCW(int stencilWriteMaskCCW) 652 { 653 context->stencilWriteMaskCCW = stencilWriteMaskCCW; 654 stencilCCW.set(context->stencilReferenceCCW, context->stencilMaskCCW, stencilWriteMaskCCW); 655 } 656 setTwoSidedStencil(bool enable)657 void PixelProcessor::setTwoSidedStencil(bool enable) 658 { 659 context->twoSidedStencil = enable; 660 } 661 setStencilCompareCCW(StencilCompareMode stencilCompareMode)662 void PixelProcessor::setStencilCompareCCW(StencilCompareMode stencilCompareMode) 663 { 664 context->stencilCompareModeCCW = stencilCompareMode; 665 } 666 setStencilFailOperationCCW(StencilOperation stencilFailOperation)667 void PixelProcessor::setStencilFailOperationCCW(StencilOperation stencilFailOperation) 668 { 669 context->stencilFailOperationCCW = stencilFailOperation; 670 } 671 setStencilPassOperationCCW(StencilOperation stencilPassOperation)672 void PixelProcessor::setStencilPassOperationCCW(StencilOperation stencilPassOperation) 673 { 674 context->stencilPassOperationCCW = stencilPassOperation; 675 } 676 setStencilZFailOperationCCW(StencilOperation stencilZFailOperation)677 void PixelProcessor::setStencilZFailOperationCCW(StencilOperation stencilZFailOperation) 678 { 679 context->stencilZFailOperationCCW = stencilZFailOperation; 680 } 681 setTextureFactor(const Color<float> & textureFactor)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 setBlendConstant(const Color<float> & blendConstant)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; 738 739 // 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; 774 775 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; 779 780 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; 794 795 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; 799 800 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 setFillMode(FillMode fillMode)806 void PixelProcessor::setFillMode(FillMode fillMode) 807 { 808 context->fillMode = fillMode; 809 } 810 setShadingMode(ShadingMode shadingMode)811 void PixelProcessor::setShadingMode(ShadingMode shadingMode) 812 { 813 context->shadingMode = shadingMode; 814 } 815 setAlphaBlendEnable(bool alphaBlendEnable)816 void PixelProcessor::setAlphaBlendEnable(bool alphaBlendEnable) 817 { 818 context->setAlphaBlendEnable(alphaBlendEnable); 819 } 820 setSourceBlendFactor(BlendFactor sourceBlendFactor)821 void PixelProcessor::setSourceBlendFactor(BlendFactor sourceBlendFactor) 822 { 823 context->setSourceBlendFactor(sourceBlendFactor); 824 } 825 setDestBlendFactor(BlendFactor destBlendFactor)826 void PixelProcessor::setDestBlendFactor(BlendFactor destBlendFactor) 827 { 828 context->setDestBlendFactor(destBlendFactor); 829 } 830 setBlendOperation(BlendOperation blendOperation)831 void PixelProcessor::setBlendOperation(BlendOperation blendOperation) 832 { 833 context->setBlendOperation(blendOperation); 834 } 835 setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)836 void PixelProcessor::setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable) 837 { 838 context->setSeparateAlphaBlendEnable(separateAlphaBlendEnable); 839 } 840 setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha)841 void PixelProcessor::setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha) 842 { 843 context->setSourceBlendFactorAlpha(sourceBlendFactorAlpha); 844 } 845 setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha)846 void PixelProcessor::setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha) 847 { 848 context->setDestBlendFactorAlpha(destBlendFactorAlpha); 849 } 850 setBlendOperationAlpha(BlendOperation blendOperationAlpha)851 void PixelProcessor::setBlendOperationAlpha(BlendOperation blendOperationAlpha) 852 { 853 context->setBlendOperationAlpha(blendOperationAlpha); 854 } 855 setAlphaReference(float alphaReference)856 void PixelProcessor::setAlphaReference(float alphaReference) 857 { 858 context->alphaReference = alphaReference; 859 860 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); 864 } 865 setGlobalMipmapBias(float bias)866 void PixelProcessor::setGlobalMipmapBias(float bias) 867 { 868 context->setGlobalMipmapBias(bias); 869 } 870 setFogStart(float start)871 void PixelProcessor::setFogStart(float start) 872 { 873 setFogRanges(start, context->fogEnd); 874 } 875 setFogEnd(float end)876 void PixelProcessor::setFogEnd(float end) 877 { 878 setFogRanges(context->fogStart, end); 879 } 880 setFogColor(Color<float> fogColor)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 setFogDensity(float fogDensity)908 void PixelProcessor::setFogDensity(float fogDensity) 909 { 910 fog.densityE = replicate(-fogDensity * 1.442695f); // 1/e^x = 2^(-x*1.44) 911 fog.density2E = replicate(-fogDensity * fogDensity * 1.442695f); 912 } 913 setPixelFogMode(FogMode fogMode)914 void PixelProcessor::setPixelFogMode(FogMode fogMode) 915 { 916 context->pixelFogMode = fogMode; 917 } 918 setPerspectiveCorrection(bool perspectiveEnable)919 void PixelProcessor::setPerspectiveCorrection(bool perspectiveEnable) 920 { 921 perspectiveCorrection = perspectiveEnable; 922 } 923 setOcclusionEnabled(bool enable)924 void PixelProcessor::setOcclusionEnabled(bool enable) 925 { 926 context->occlusionEnabled = enable; 927 } 928 setRoutineCacheSize(int cacheSize)929 void PixelProcessor::setRoutineCacheSize(int cacheSize) 930 { 931 delete routineCache; 932 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536)); 933 } 934 setFogRanges(float start,float end)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 update() const952 const PixelProcessor::State PixelProcessor::update() const 953 { 954 State state; 955 956 if(context->pixelShader) 957 { 958 state.shaderID = context->pixelShader->getSerialID(); 959 } 960 else 961 { 962 state.shaderID = 0; 963 } 964 965 state.depthOverride = context->pixelShader && context->pixelShader->depthOverride(); 966 state.shaderContainsKill = context->pixelShader ? context->pixelShader->containsKill() : false; 967 968 if(context->alphaTestActive()) 969 { 970 state.alphaCompareMode = context->alphaCompareMode; 971 972 state.transparencyAntialiasing = context->getMultiSampleCount() > 1 ? transparencyAntialiasing : TRANSPARENCY_NONE; 973 } 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; 1002 state.quadLayoutDepthBuffer = Surface::hasQuadLayout(context->depthBuffer->getInternalFormat()); 1003 } 1004 1005 state.occlusionEnabled = context->occlusionEnabled; 1006 1007 state.fogActive = context->fogActive(); 1008 state.pixelFogMode = context->pixelFogActive(); 1009 state.wBasedFog = context->wBasedFog && context->pixelFogActive() != FOG_NONE; 1010 state.perspective = context->perspectiveActive(); 1011 state.depthClamp = (context->depthBias != 0.0f) || (context->slopeDepthBias != 0.0f); 1012 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 } 1023 1024 state.logicalOperation = context->colorLogicOp(); 1025 1026 for(int i = 0; i < RENDERTARGETS; i++) 1027 { 1028 state.colorWriteMask |= context->colorWriteActive(i) << (4 * i); 1029 state.targetFormat[i] = context->renderTargetInternalFormat(i); 1030 } 1031 1032 state.writeSRGB = context->writeSRGB && context->renderTarget[0] && Surface::isSRGBwritable(context->renderTarget[0]->getExternalFormat()); 1033 state.multiSample = context->getMultiSampleCount(); 1034 state.multiSampleMask = context->multiSampleMask; 1035 1036 if(state.multiSample > 1 && context->pixelShader) 1037 { 1038 state.centroid = context->pixelShader->containsCentroid(); 1039 } 1040 1041 state.frontFaceCCW = context->frontFacingCCW; 1042 1043 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(); 1074 const bool flatShading = (context->shadingMode == SHADING_FLAT) || point; 1075 1076 if(context->pixelShaderModel() < 0x0300) 1077 { 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 1093 if(context->textureTransformProject[coordinate] && context->pixelShaderModel() <= 0x0103) 1094 { 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; 1117 1118 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; 1129 1130 if(point) 1131 { 1132 state.fog.flat = true; 1133 } 1134 } 1135 } 1136 else 1137 { 1138 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++) 1139 { 1140 for(int component = 0; component < 4; component++) 1141 { 1142 const Shader::Semantic &semantic = context->pixelShader->getInput(interpolant, component); 1143 1144 if(semantic.active()) 1145 { 1146 bool flat = point; 1147 1148 switch(semantic.usage) 1149 { 1150 case Shader::USAGE_TEXCOORD: flat = point && !sprite; break; 1151 case Shader::USAGE_COLOR: flat = semantic.flat || flatShading; break; 1152 } 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 { 1167 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++) 1168 { 1169 for(int component = 0; component < 4; component++) 1170 { 1171 state.interpolant[interpolant].centroid = context->pixelShader->getInput(interpolant, 0).centroid; 1172 } 1173 } 1174 } 1175 1176 state.hash = state.computeHash(); 1177 1178 return state; 1179 } 1180 routine(const State & state)1181 std::shared_ptr<Routine> PixelProcessor::routine(const State &state) 1182 { 1183 auto routine = routineCache->query(state); 1184 1185 if(!routine) 1186 { 1187 const bool integerPipeline = (context->pixelShaderModel() <= 0x0104); 1188 QuadRasterizer *generator = nullptr; 1189 1190 if(integerPipeline) 1191 { 1192 generator = new PixelPipeline(state, context->pixelShader); 1193 } 1194 else 1195 { 1196 generator = new PixelProgram(state, context->pixelShader); 1197 } 1198 1199 generator->generate(); 1200 routine = (*generator)("PixelRoutine_%0.8X", state.shaderID); 1201 delete generator; 1202 1203 routineCache->add(state, routine); 1204 } 1205 1206 return routine; 1207 } 1208 } 1209