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 setSwizzleR(unsigned int sampler,SwizzleType swizzleR)447 void PixelProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR) 448 { 449 if(sampler < TEXTURE_IMAGE_UNITS) 450 { 451 context->sampler[sampler].setSwizzleR(swizzleR); 452 } 453 else ASSERT(false); 454 } 455 setSwizzleG(unsigned int sampler,SwizzleType swizzleG)456 void PixelProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG) 457 { 458 if(sampler < TEXTURE_IMAGE_UNITS) 459 { 460 context->sampler[sampler].setSwizzleG(swizzleG); 461 } 462 else ASSERT(false); 463 } 464 setSwizzleB(unsigned int sampler,SwizzleType swizzleB)465 void PixelProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB) 466 { 467 if(sampler < TEXTURE_IMAGE_UNITS) 468 { 469 context->sampler[sampler].setSwizzleB(swizzleB); 470 } 471 else ASSERT(false); 472 } 473 setSwizzleA(unsigned int sampler,SwizzleType swizzleA)474 void PixelProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA) 475 { 476 if(sampler < TEXTURE_IMAGE_UNITS) 477 { 478 context->sampler[sampler].setSwizzleA(swizzleA); 479 } 480 else ASSERT(false); 481 } 482 setWriteSRGB(bool sRGB)483 void PixelProcessor::setWriteSRGB(bool sRGB) 484 { 485 context->setWriteSRGB(sRGB); 486 } 487 setColorLogicOpEnabled(bool colorLogicOpEnabled)488 void PixelProcessor::setColorLogicOpEnabled(bool colorLogicOpEnabled) 489 { 490 context->setColorLogicOpEnabled(colorLogicOpEnabled); 491 } 492 setLogicalOperation(LogicalOperation logicalOperation)493 void PixelProcessor::setLogicalOperation(LogicalOperation logicalOperation) 494 { 495 context->setLogicalOperation(logicalOperation); 496 } 497 setDepthBufferEnable(bool depthBufferEnable)498 void PixelProcessor::setDepthBufferEnable(bool depthBufferEnable) 499 { 500 context->setDepthBufferEnable(depthBufferEnable); 501 } 502 setDepthCompare(DepthCompareMode depthCompareMode)503 void PixelProcessor::setDepthCompare(DepthCompareMode depthCompareMode) 504 { 505 context->depthCompareMode = depthCompareMode; 506 } 507 setAlphaCompare(AlphaCompareMode alphaCompareMode)508 void PixelProcessor::setAlphaCompare(AlphaCompareMode alphaCompareMode) 509 { 510 context->alphaCompareMode = alphaCompareMode; 511 } 512 setDepthWriteEnable(bool depthWriteEnable)513 void PixelProcessor::setDepthWriteEnable(bool depthWriteEnable) 514 { 515 context->depthWriteEnable = depthWriteEnable; 516 } 517 setAlphaTestEnable(bool alphaTestEnable)518 void PixelProcessor::setAlphaTestEnable(bool alphaTestEnable) 519 { 520 context->alphaTestEnable = alphaTestEnable; 521 } 522 setCullMode(CullMode cullMode)523 void PixelProcessor::setCullMode(CullMode cullMode) 524 { 525 context->cullMode = cullMode; 526 } 527 setColorWriteMask(int index,int rgbaMask)528 void PixelProcessor::setColorWriteMask(int index, int rgbaMask) 529 { 530 context->setColorWriteMask(index, rgbaMask); 531 } 532 setStencilEnable(bool stencilEnable)533 void PixelProcessor::setStencilEnable(bool stencilEnable) 534 { 535 context->stencilEnable = stencilEnable; 536 } 537 setStencilCompare(StencilCompareMode stencilCompareMode)538 void PixelProcessor::setStencilCompare(StencilCompareMode stencilCompareMode) 539 { 540 context->stencilCompareMode = stencilCompareMode; 541 } 542 setStencilReference(int stencilReference)543 void PixelProcessor::setStencilReference(int stencilReference) 544 { 545 context->stencilReference = stencilReference; 546 stencil.set(stencilReference, context->stencilMask, context->stencilWriteMask); 547 } 548 setStencilReferenceCCW(int stencilReferenceCCW)549 void PixelProcessor::setStencilReferenceCCW(int stencilReferenceCCW) 550 { 551 context->stencilReferenceCCW = stencilReferenceCCW; 552 stencilCCW.set(stencilReferenceCCW, context->stencilMaskCCW, context->stencilWriteMaskCCW); 553 } 554 setStencilMask(int stencilMask)555 void PixelProcessor::setStencilMask(int stencilMask) 556 { 557 context->stencilMask = stencilMask; 558 stencil.set(context->stencilReference, stencilMask, context->stencilWriteMask); 559 } 560 setStencilMaskCCW(int stencilMaskCCW)561 void PixelProcessor::setStencilMaskCCW(int stencilMaskCCW) 562 { 563 context->stencilMaskCCW = stencilMaskCCW; 564 stencilCCW.set(context->stencilReferenceCCW, stencilMaskCCW, context->stencilWriteMaskCCW); 565 } 566 setStencilFailOperation(StencilOperation stencilFailOperation)567 void PixelProcessor::setStencilFailOperation(StencilOperation stencilFailOperation) 568 { 569 context->stencilFailOperation = stencilFailOperation; 570 } 571 setStencilPassOperation(StencilOperation stencilPassOperation)572 void PixelProcessor::setStencilPassOperation(StencilOperation stencilPassOperation) 573 { 574 context->stencilPassOperation = stencilPassOperation; 575 } 576 setStencilZFailOperation(StencilOperation stencilZFailOperation)577 void PixelProcessor::setStencilZFailOperation(StencilOperation stencilZFailOperation) 578 { 579 context->stencilZFailOperation = stencilZFailOperation; 580 } 581 setStencilWriteMask(int stencilWriteMask)582 void PixelProcessor::setStencilWriteMask(int stencilWriteMask) 583 { 584 context->stencilWriteMask = stencilWriteMask; 585 stencil.set(context->stencilReference, context->stencilMask, stencilWriteMask); 586 } 587 setStencilWriteMaskCCW(int stencilWriteMaskCCW)588 void PixelProcessor::setStencilWriteMaskCCW(int stencilWriteMaskCCW) 589 { 590 context->stencilWriteMaskCCW = stencilWriteMaskCCW; 591 stencilCCW.set(context->stencilReferenceCCW, context->stencilMaskCCW, stencilWriteMaskCCW); 592 } 593 setTwoSidedStencil(bool enable)594 void PixelProcessor::setTwoSidedStencil(bool enable) 595 { 596 context->twoSidedStencil = enable; 597 } 598 setStencilCompareCCW(StencilCompareMode stencilCompareMode)599 void PixelProcessor::setStencilCompareCCW(StencilCompareMode stencilCompareMode) 600 { 601 context->stencilCompareModeCCW = stencilCompareMode; 602 } 603 setStencilFailOperationCCW(StencilOperation stencilFailOperation)604 void PixelProcessor::setStencilFailOperationCCW(StencilOperation stencilFailOperation) 605 { 606 context->stencilFailOperationCCW = stencilFailOperation; 607 } 608 setStencilPassOperationCCW(StencilOperation stencilPassOperation)609 void PixelProcessor::setStencilPassOperationCCW(StencilOperation stencilPassOperation) 610 { 611 context->stencilPassOperationCCW = stencilPassOperation; 612 } 613 setStencilZFailOperationCCW(StencilOperation stencilZFailOperation)614 void PixelProcessor::setStencilZFailOperationCCW(StencilOperation stencilZFailOperation) 615 { 616 context->stencilZFailOperationCCW = stencilZFailOperation; 617 } 618 setTextureFactor(const Color<float> & textureFactor)619 void PixelProcessor::setTextureFactor(const Color<float> &textureFactor) 620 { 621 // FIXME: Compact into generic function // FIXME: Clamp 622 short textureFactorR = iround(4095 * textureFactor.r); 623 short textureFactorG = iround(4095 * textureFactor.g); 624 short textureFactorB = iround(4095 * textureFactor.b); 625 short textureFactorA = iround(4095 * textureFactor.a); 626 627 factor.textureFactor4[0][0] = textureFactorR; 628 factor.textureFactor4[0][1] = textureFactorR; 629 factor.textureFactor4[0][2] = textureFactorR; 630 factor.textureFactor4[0][3] = textureFactorR; 631 632 factor.textureFactor4[1][0] = textureFactorG; 633 factor.textureFactor4[1][1] = textureFactorG; 634 factor.textureFactor4[1][2] = textureFactorG; 635 factor.textureFactor4[1][3] = textureFactorG; 636 637 factor.textureFactor4[2][0] = textureFactorB; 638 factor.textureFactor4[2][1] = textureFactorB; 639 factor.textureFactor4[2][2] = textureFactorB; 640 factor.textureFactor4[2][3] = textureFactorB; 641 642 factor.textureFactor4[3][0] = textureFactorA; 643 factor.textureFactor4[3][1] = textureFactorA; 644 factor.textureFactor4[3][2] = textureFactorA; 645 factor.textureFactor4[3][3] = textureFactorA; 646 } 647 setBlendConstant(const Color<float> & blendConstant)648 void PixelProcessor::setBlendConstant(const Color<float> &blendConstant) 649 { 650 // FIXME: Compact into generic function // FIXME: Clamp 651 short blendConstantR = iround(65535 * blendConstant.r); 652 short blendConstantG = iround(65535 * blendConstant.g); 653 short blendConstantB = iround(65535 * blendConstant.b); 654 short blendConstantA = iround(65535 * blendConstant.a); 655 656 factor.blendConstant4W[0][0] = blendConstantR; 657 factor.blendConstant4W[0][1] = blendConstantR; 658 factor.blendConstant4W[0][2] = blendConstantR; 659 factor.blendConstant4W[0][3] = blendConstantR; 660 661 factor.blendConstant4W[1][0] = blendConstantG; 662 factor.blendConstant4W[1][1] = blendConstantG; 663 factor.blendConstant4W[1][2] = blendConstantG; 664 factor.blendConstant4W[1][3] = blendConstantG; 665 666 factor.blendConstant4W[2][0] = blendConstantB; 667 factor.blendConstant4W[2][1] = blendConstantB; 668 factor.blendConstant4W[2][2] = blendConstantB; 669 factor.blendConstant4W[2][3] = blendConstantB; 670 671 factor.blendConstant4W[3][0] = blendConstantA; 672 factor.blendConstant4W[3][1] = blendConstantA; 673 factor.blendConstant4W[3][2] = blendConstantA; 674 factor.blendConstant4W[3][3] = blendConstantA; 675 676 // FIXME: Compact into generic function // FIXME: Clamp 677 short invBlendConstantR = iround(65535 * (1 - blendConstant.r)); 678 short invBlendConstantG = iround(65535 * (1 - blendConstant.g)); 679 short invBlendConstantB = iround(65535 * (1 - blendConstant.b)); 680 short invBlendConstantA = iround(65535 * (1 - blendConstant.a)); 681 682 factor.invBlendConstant4W[0][0] = invBlendConstantR; 683 factor.invBlendConstant4W[0][1] = invBlendConstantR; 684 factor.invBlendConstant4W[0][2] = invBlendConstantR; 685 factor.invBlendConstant4W[0][3] = invBlendConstantR; 686 687 factor.invBlendConstant4W[1][0] = invBlendConstantG; 688 factor.invBlendConstant4W[1][1] = invBlendConstantG; 689 factor.invBlendConstant4W[1][2] = invBlendConstantG; 690 factor.invBlendConstant4W[1][3] = invBlendConstantG; 691 692 factor.invBlendConstant4W[2][0] = invBlendConstantB; 693 factor.invBlendConstant4W[2][1] = invBlendConstantB; 694 factor.invBlendConstant4W[2][2] = invBlendConstantB; 695 factor.invBlendConstant4W[2][3] = invBlendConstantB; 696 697 factor.invBlendConstant4W[3][0] = invBlendConstantA; 698 factor.invBlendConstant4W[3][1] = invBlendConstantA; 699 factor.invBlendConstant4W[3][2] = invBlendConstantA; 700 factor.invBlendConstant4W[3][3] = invBlendConstantA; 701 702 factor.blendConstant4F[0][0] = blendConstant.r; 703 factor.blendConstant4F[0][1] = blendConstant.r; 704 factor.blendConstant4F[0][2] = blendConstant.r; 705 factor.blendConstant4F[0][3] = blendConstant.r; 706 707 factor.blendConstant4F[1][0] = blendConstant.g; 708 factor.blendConstant4F[1][1] = blendConstant.g; 709 factor.blendConstant4F[1][2] = blendConstant.g; 710 factor.blendConstant4F[1][3] = blendConstant.g; 711 712 factor.blendConstant4F[2][0] = blendConstant.b; 713 factor.blendConstant4F[2][1] = blendConstant.b; 714 factor.blendConstant4F[2][2] = blendConstant.b; 715 factor.blendConstant4F[2][3] = blendConstant.b; 716 717 factor.blendConstant4F[3][0] = blendConstant.a; 718 factor.blendConstant4F[3][1] = blendConstant.a; 719 factor.blendConstant4F[3][2] = blendConstant.a; 720 factor.blendConstant4F[3][3] = blendConstant.a; 721 722 factor.invBlendConstant4F[0][0] = 1 - blendConstant.r; 723 factor.invBlendConstant4F[0][1] = 1 - blendConstant.r; 724 factor.invBlendConstant4F[0][2] = 1 - blendConstant.r; 725 factor.invBlendConstant4F[0][3] = 1 - blendConstant.r; 726 727 factor.invBlendConstant4F[1][0] = 1 - blendConstant.g; 728 factor.invBlendConstant4F[1][1] = 1 - blendConstant.g; 729 factor.invBlendConstant4F[1][2] = 1 - blendConstant.g; 730 factor.invBlendConstant4F[1][3] = 1 - blendConstant.g; 731 732 factor.invBlendConstant4F[2][0] = 1 - blendConstant.b; 733 factor.invBlendConstant4F[2][1] = 1 - blendConstant.b; 734 factor.invBlendConstant4F[2][2] = 1 - blendConstant.b; 735 factor.invBlendConstant4F[2][3] = 1 - blendConstant.b; 736 737 factor.invBlendConstant4F[3][0] = 1 - blendConstant.a; 738 factor.invBlendConstant4F[3][1] = 1 - blendConstant.a; 739 factor.invBlendConstant4F[3][2] = 1 - blendConstant.a; 740 factor.invBlendConstant4F[3][3] = 1 - blendConstant.a; 741 } 742 setFillMode(FillMode fillMode)743 void PixelProcessor::setFillMode(FillMode fillMode) 744 { 745 context->fillMode = fillMode; 746 } 747 setShadingMode(ShadingMode shadingMode)748 void PixelProcessor::setShadingMode(ShadingMode shadingMode) 749 { 750 context->shadingMode = shadingMode; 751 } 752 setAlphaBlendEnable(bool alphaBlendEnable)753 void PixelProcessor::setAlphaBlendEnable(bool alphaBlendEnable) 754 { 755 context->setAlphaBlendEnable(alphaBlendEnable); 756 } 757 setSourceBlendFactor(BlendFactor sourceBlendFactor)758 void PixelProcessor::setSourceBlendFactor(BlendFactor sourceBlendFactor) 759 { 760 context->setSourceBlendFactor(sourceBlendFactor); 761 } 762 setDestBlendFactor(BlendFactor destBlendFactor)763 void PixelProcessor::setDestBlendFactor(BlendFactor destBlendFactor) 764 { 765 context->setDestBlendFactor(destBlendFactor); 766 } 767 setBlendOperation(BlendOperation blendOperation)768 void PixelProcessor::setBlendOperation(BlendOperation blendOperation) 769 { 770 context->setBlendOperation(blendOperation); 771 } 772 setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)773 void PixelProcessor::setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable) 774 { 775 context->setSeparateAlphaBlendEnable(separateAlphaBlendEnable); 776 } 777 setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha)778 void PixelProcessor::setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha) 779 { 780 context->setSourceBlendFactorAlpha(sourceBlendFactorAlpha); 781 } 782 setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha)783 void PixelProcessor::setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha) 784 { 785 context->setDestBlendFactorAlpha(destBlendFactorAlpha); 786 } 787 setBlendOperationAlpha(BlendOperation blendOperationAlpha)788 void PixelProcessor::setBlendOperationAlpha(BlendOperation blendOperationAlpha) 789 { 790 context->setBlendOperationAlpha(blendOperationAlpha); 791 } 792 setAlphaReference(float alphaReference)793 void PixelProcessor::setAlphaReference(float alphaReference) 794 { 795 context->alphaReference = alphaReference; 796 797 factor.alphaReference4[0] = (word)iround(alphaReference * 0x1000 / 0xFF); 798 factor.alphaReference4[1] = (word)iround(alphaReference * 0x1000 / 0xFF); 799 factor.alphaReference4[2] = (word)iround(alphaReference * 0x1000 / 0xFF); 800 factor.alphaReference4[3] = (word)iround(alphaReference * 0x1000 / 0xFF); 801 } 802 setGlobalMipmapBias(float bias)803 void PixelProcessor::setGlobalMipmapBias(float bias) 804 { 805 context->setGlobalMipmapBias(bias); 806 } 807 setFogStart(float start)808 void PixelProcessor::setFogStart(float start) 809 { 810 setFogRanges(start, context->fogEnd); 811 } 812 setFogEnd(float end)813 void PixelProcessor::setFogEnd(float end) 814 { 815 setFogRanges(context->fogStart, end); 816 } 817 setFogColor(Color<float> fogColor)818 void PixelProcessor::setFogColor(Color<float> fogColor) 819 { 820 // TODO: Compact into generic function 821 word fogR = (unsigned short)(65535 * fogColor.r); 822 word fogG = (unsigned short)(65535 * fogColor.g); 823 word fogB = (unsigned short)(65535 * fogColor.b); 824 825 fog.color4[0][0] = fogR; 826 fog.color4[0][1] = fogR; 827 fog.color4[0][2] = fogR; 828 fog.color4[0][3] = fogR; 829 830 fog.color4[1][0] = fogG; 831 fog.color4[1][1] = fogG; 832 fog.color4[1][2] = fogG; 833 fog.color4[1][3] = fogG; 834 835 fog.color4[2][0] = fogB; 836 fog.color4[2][1] = fogB; 837 fog.color4[2][2] = fogB; 838 fog.color4[2][3] = fogB; 839 840 fog.colorF[0] = replicate(fogColor.r); 841 fog.colorF[1] = replicate(fogColor.g); 842 fog.colorF[2] = replicate(fogColor.b); 843 } 844 setFogDensity(float fogDensity)845 void PixelProcessor::setFogDensity(float fogDensity) 846 { 847 fog.densityE = replicate(-fogDensity * 1.442695f); // 1/e^x = 2^(-x*1.44) 848 fog.density2E = replicate(-fogDensity * fogDensity * 1.442695f); 849 } 850 setPixelFogMode(FogMode fogMode)851 void PixelProcessor::setPixelFogMode(FogMode fogMode) 852 { 853 context->pixelFogMode = fogMode; 854 } 855 setPerspectiveCorrection(bool perspectiveEnable)856 void PixelProcessor::setPerspectiveCorrection(bool perspectiveEnable) 857 { 858 perspectiveCorrection = perspectiveEnable; 859 } 860 setOcclusionEnabled(bool enable)861 void PixelProcessor::setOcclusionEnabled(bool enable) 862 { 863 context->occlusionEnabled = enable; 864 } 865 setRoutineCacheSize(int cacheSize)866 void PixelProcessor::setRoutineCacheSize(int cacheSize) 867 { 868 delete routineCache; 869 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precachePixel ? "sw-pixel" : 0); 870 } 871 setFogRanges(float start,float end)872 void PixelProcessor::setFogRanges(float start, float end) 873 { 874 context->fogStart = start; 875 context->fogEnd = end; 876 877 if(start == end) 878 { 879 end += 0.001f; // Hack: ensure there is a small range 880 } 881 882 float fogScale = -1.0f / (end - start); 883 float fogOffset = end * -fogScale; 884 885 fog.scale = replicate(fogScale); 886 fog.offset = replicate(fogOffset); 887 } 888 update() const889 const PixelProcessor::State PixelProcessor::update() const 890 { 891 State state; 892 893 if(context->pixelShader) 894 { 895 state.shaderID = context->pixelShader->getSerialID(); 896 } 897 else 898 { 899 state.shaderID = 0; 900 } 901 902 state.depthOverride = context->pixelShader && context->pixelShader->depthOverride(); 903 state.shaderContainsKill = context->pixelShader ? context->pixelShader->containsKill() : false; 904 905 if(context->alphaTestActive()) 906 { 907 state.alphaCompareMode = context->alphaCompareMode; 908 909 state.transparencyAntialiasing = context->getMultiSampleCount() > 1 ? transparencyAntialiasing : TRANSPARENCY_NONE; 910 } 911 912 state.depthWriteEnable = context->depthWriteActive(); 913 914 if(context->stencilActive()) 915 { 916 state.stencilActive = true; 917 state.stencilCompareMode = context->stencilCompareMode; 918 state.stencilFailOperation = context->stencilFailOperation; 919 state.stencilPassOperation = context->stencilPassOperation; 920 state.stencilZFailOperation = context->stencilZFailOperation; 921 state.noStencilMask = (context->stencilMask == 0xFF); 922 state.noStencilWriteMask = (context->stencilWriteMask == 0xFF); 923 state.stencilWriteMasked = (context->stencilWriteMask == 0x00); 924 925 state.twoSidedStencil = context->twoSidedStencil; 926 state.stencilCompareModeCCW = context->twoSidedStencil ? context->stencilCompareModeCCW : state.stencilCompareMode; 927 state.stencilFailOperationCCW = context->twoSidedStencil ? context->stencilFailOperationCCW : state.stencilFailOperation; 928 state.stencilPassOperationCCW = context->twoSidedStencil ? context->stencilPassOperationCCW : state.stencilPassOperation; 929 state.stencilZFailOperationCCW = context->twoSidedStencil ? context->stencilZFailOperationCCW : state.stencilZFailOperation; 930 state.noStencilMaskCCW = context->twoSidedStencil ? (context->stencilMaskCCW == 0xFF) : state.noStencilMask; 931 state.noStencilWriteMaskCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0xFF) : state.noStencilWriteMask; 932 state.stencilWriteMaskedCCW = context->twoSidedStencil ? (context->stencilWriteMaskCCW == 0x00) : state.stencilWriteMasked; 933 } 934 935 if(context->depthBufferActive()) 936 { 937 state.depthTestActive = true; 938 state.depthCompareMode = context->depthCompareMode; 939 state.quadLayoutDepthBuffer = context->depthBuffer->getInternalFormat() != FORMAT_D32F_LOCKABLE && 940 context->depthBuffer->getInternalFormat() != FORMAT_D32FS8_TEXTURE && 941 context->depthBuffer->getInternalFormat() != FORMAT_D32FS8_SHADOW; 942 } 943 944 state.occlusionEnabled = context->occlusionEnabled; 945 946 state.fogActive = context->fogActive(); 947 state.pixelFogMode = context->pixelFogActive(); 948 state.wBasedFog = context->wBasedFog && context->pixelFogActive() != FOG_NONE; 949 state.perspective = context->perspectiveActive(); 950 951 if(context->alphaBlendActive()) 952 { 953 state.alphaBlendActive = true; 954 state.sourceBlendFactor = context->sourceBlendFactor(); 955 state.destBlendFactor = context->destBlendFactor(); 956 state.blendOperation = context->blendOperation(); 957 state.sourceBlendFactorAlpha = context->sourceBlendFactorAlpha(); 958 state.destBlendFactorAlpha = context->destBlendFactorAlpha(); 959 state.blendOperationAlpha = context->blendOperationAlpha(); 960 } 961 962 state.logicalOperation = context->colorLogicOp(); 963 964 for(int i = 0; i < RENDERTARGETS; i++) 965 { 966 state.colorWriteMask |= context->colorWriteActive(i) << (4 * i); 967 state.targetFormat[i] = context->renderTargetInternalFormat(i); 968 } 969 970 state.writeSRGB = context->writeSRGB && context->renderTarget[0] && Surface::isSRGBwritable(context->renderTarget[0]->getExternalFormat()); 971 state.multiSample = context->getMultiSampleCount(); 972 state.multiSampleMask = context->multiSampleMask; 973 974 if(state.multiSample > 1 && context->pixelShader) 975 { 976 state.centroid = context->pixelShader->containsCentroid(); 977 } 978 979 if(!context->pixelShader) 980 { 981 for(unsigned int i = 0; i < 8; i++) 982 { 983 state.textureStage[i] = context->textureStage[i].textureStageState(); 984 } 985 986 state.specularAdd = context->specularActive() && context->specularEnable; 987 } 988 989 for(unsigned int i = 0; i < 16; i++) 990 { 991 if(context->pixelShader) 992 { 993 if(context->pixelShader->usesSampler(i)) 994 { 995 state.sampler[i] = context->sampler[i].samplerState(); 996 } 997 } 998 else 999 { 1000 if(i < 8 && state.textureStage[i].stageOperation != TextureStage::STAGE_DISABLE) 1001 { 1002 state.sampler[i] = context->sampler[i].samplerState(); 1003 } 1004 else break; 1005 } 1006 } 1007 1008 const bool point = context->isDrawPoint(true); 1009 const bool sprite = context->pointSpriteActive(); 1010 const bool flatShading = (context->shadingMode == SHADING_FLAT) || point; 1011 1012 if(context->pixelShaderVersion() < 0x0300) 1013 { 1014 for(int coordinate = 0; coordinate < 8; coordinate++) 1015 { 1016 for(int component = 0; component < 4; component++) 1017 { 1018 if(context->textureActive(coordinate, component)) 1019 { 1020 state.texture[coordinate].component |= 1 << component; 1021 1022 if(point && !sprite) 1023 { 1024 state.texture[coordinate].flat |= 1 << component; 1025 } 1026 } 1027 } 1028 1029 if(context->textureTransformProject[coordinate] && context->pixelShaderVersion() <= 0x0103) 1030 { 1031 if(context->textureTransformCount[coordinate] == 2) 1032 { 1033 state.texture[coordinate].project = 1; 1034 } 1035 else if(context->textureTransformCount[coordinate] == 3) 1036 { 1037 state.texture[coordinate].project = 2; 1038 } 1039 else if(context->textureTransformCount[coordinate] == 4 || context->textureTransformCount[coordinate] == 0) 1040 { 1041 state.texture[coordinate].project = 3; 1042 } 1043 } 1044 } 1045 1046 for(int color = 0; color < 2; color++) 1047 { 1048 for(int component = 0; component < 4; component++) 1049 { 1050 if(context->colorActive(color, component)) 1051 { 1052 state.color[color].component |= 1 << component; 1053 1054 if(point || flatShading) 1055 { 1056 state.color[color].flat |= 1 << component; 1057 } 1058 } 1059 } 1060 } 1061 1062 if(context->fogActive()) 1063 { 1064 state.fog.component = true; 1065 1066 if(point) 1067 { 1068 state.fog.flat = true; 1069 } 1070 } 1071 } 1072 else 1073 { 1074 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++) 1075 { 1076 for(int component = 0; component < 4; component++) 1077 { 1078 if(context->pixelShader->semantic[interpolant][component].active()) 1079 { 1080 bool flat = point; 1081 1082 switch(context->pixelShader->semantic[interpolant][component].usage) 1083 { 1084 case Shader::USAGE_TEXCOORD: flat = point && !sprite; break; 1085 case Shader::USAGE_COLOR: flat = flatShading; break; 1086 } 1087 1088 state.interpolant[interpolant].component |= 1 << component; 1089 1090 if(flat) 1091 { 1092 state.interpolant[interpolant].flat |= 1 << component; 1093 } 1094 } 1095 } 1096 } 1097 } 1098 1099 if(state.centroid) 1100 { 1101 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++) 1102 { 1103 for(int component = 0; component < 4; component++) 1104 { 1105 state.interpolant[interpolant].centroid = context->pixelShader->semantic[interpolant][0].centroid; 1106 } 1107 } 1108 } 1109 1110 state.hash = state.computeHash(); 1111 1112 return state; 1113 } 1114 routine(const State & state)1115 Routine *PixelProcessor::routine(const State &state) 1116 { 1117 Routine *routine = routineCache->query(state); 1118 1119 if(!routine) 1120 { 1121 const bool integerPipeline = (context->pixelShaderVersion() <= 0x0104); 1122 QuadRasterizer *generator = nullptr; 1123 1124 if(integerPipeline) 1125 { 1126 generator = new PixelPipeline(state, context->pixelShader); 1127 } 1128 else 1129 { 1130 generator = new PixelProgram(state, context->pixelShader); 1131 } 1132 1133 generator->generate(); 1134 routine = (*generator)(L"PixelRoutine_%0.8X", state.shaderID); 1135 delete generator; 1136 1137 routineCache->add(state, routine); 1138 } 1139 1140 return routine; 1141 } 1142 } 1143