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