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 "VertexProcessor.hpp" 16 17 #include "Math.hpp" 18 #include "VertexPipeline.hpp" 19 #include "VertexProgram.hpp" 20 #include "VertexShader.hpp" 21 #include "PixelShader.hpp" 22 #include "Constants.hpp" 23 #include "Debug.hpp" 24 25 #include <string.h> 26 27 namespace sw 28 { 29 bool precacheVertex = false; 30 31 void VertexCache::clear() 32 { 33 for(int i = 0; i < 16; i++) 34 { 35 tag[i] = 0x80000000; 36 } 37 } 38 39 unsigned int VertexProcessor::States::computeHash() 40 { 41 unsigned int *state = (unsigned int*)this; 42 unsigned int hash = 0; 43 44 for(unsigned int i = 0; i < sizeof(States) / 4; i++) 45 { 46 hash ^= state[i]; 47 } 48 49 return hash; 50 } 51 52 VertexProcessor::State::State() 53 { 54 memset(this, 0, sizeof(State)); 55 } 56 57 bool VertexProcessor::State::operator==(const State &state) const 58 { 59 if(hash != state.hash) 60 { 61 return false; 62 } 63 64 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0; 65 } 66 67 VertexProcessor::TransformFeedbackInfo::TransformFeedbackInfo() 68 { 69 buffer = nullptr; 70 offset = 0; 71 reg = 0; 72 row = 0; 73 col = 0; 74 stride = 0; 75 } 76 77 VertexProcessor::UniformBufferInfo::UniformBufferInfo() 78 { 79 buffer = nullptr; 80 offset = 0; 81 } 82 83 VertexProcessor::VertexProcessor(Context *context) : context(context) 84 { 85 for(int i = 0; i < 12; i++) 86 { 87 M[i] = 1; 88 } 89 90 V = 1; 91 B = 1; 92 P = 0; 93 PB = 0; 94 PBV = 0; 95 96 for(int i = 0; i < 12; i++) 97 { 98 PBVM[i] = 0; 99 } 100 101 setLightingEnable(true); 102 setSpecularEnable(false); 103 104 for(int i = 0; i < 8; i++) 105 { 106 setLightEnable(i, false); 107 setLightPosition(i, 0); 108 } 109 110 updateMatrix = true; 111 updateViewMatrix = true; 112 updateBaseMatrix = true; 113 updateProjectionMatrix = true; 114 updateLighting = true; 115 116 for(int i = 0; i < 12; i++) 117 { 118 updateModelMatrix[i] = true; 119 } 120 121 routineCache = 0; 122 setRoutineCacheSize(1024); 123 } 124 125 VertexProcessor::~VertexProcessor() 126 { 127 delete routineCache; 128 routineCache = 0; 129 } 130 131 void VertexProcessor::setInputStream(int index, const Stream &stream) 132 { 133 context->input[index] = stream; 134 } 135 136 void VertexProcessor::resetInputStreams(bool preTransformed) 137 { 138 for(int i = 0; i < MAX_VERTEX_INPUTS; i++) 139 { 140 context->input[i].defaults(); 141 } 142 143 context->preTransformed = preTransformed; 144 } 145 146 void VertexProcessor::setFloatConstant(unsigned int index, const float value[4]) 147 { 148 if(index < VERTEX_UNIFORM_VECTORS) 149 { 150 c[index][0] = value[0]; 151 c[index][1] = value[1]; 152 c[index][2] = value[2]; 153 c[index][3] = value[3]; 154 } 155 else ASSERT(false); 156 } 157 158 void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4]) 159 { 160 if(index < 16) 161 { 162 i[index][0] = integer[0]; 163 i[index][1] = integer[1]; 164 i[index][2] = integer[2]; 165 i[index][3] = integer[3]; 166 } 167 else ASSERT(false); 168 } 169 170 void VertexProcessor::setBooleanConstant(unsigned int index, int boolean) 171 { 172 if(index < 16) 173 { 174 b[index] = boolean != 0; 175 } 176 else ASSERT(false); 177 } 178 179 void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset) 180 { 181 uniformBufferInfo[index].buffer = buffer; 182 uniformBufferInfo[index].offset = offset; 183 } 184 185 void VertexProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]) 186 { 187 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i) 188 { 189 u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr; 190 uniformBuffers[i] = uniformBufferInfo[i].buffer; 191 } 192 } 193 194 void VertexProcessor::setTransformFeedbackBuffer(int index, sw::Resource* buffer, int offset, unsigned int reg, unsigned int row, unsigned int col, size_t stride) 195 { 196 transformFeedbackInfo[index].buffer = buffer; 197 transformFeedbackInfo[index].offset = offset; 198 transformFeedbackInfo[index].reg = reg; 199 transformFeedbackInfo[index].row = row; 200 transformFeedbackInfo[index].col = col; 201 transformFeedbackInfo[index].stride = stride; 202 } 203 204 void VertexProcessor::lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s, sw::Resource* transformFeedbackBuffers[]) 205 { 206 for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i) 207 { 208 t[i] = transformFeedbackInfo[i].buffer ? static_cast<byte*>(transformFeedbackInfo[i].buffer->lock(PUBLIC, PRIVATE)) + transformFeedbackInfo[i].offset : nullptr; 209 transformFeedbackBuffers[i] = transformFeedbackInfo[i].buffer; 210 v[i] = transformFeedbackInfo[i].reg; 211 r[i] = transformFeedbackInfo[i].row; 212 c[i] = transformFeedbackInfo[i].col; 213 s[i] = transformFeedbackInfo[i].stride; 214 } 215 } 216 217 void VertexProcessor::setModelMatrix(const Matrix &M, int i) 218 { 219 if(i < 12) 220 { 221 this->M[i] = M; 222 223 updateMatrix = true; 224 updateModelMatrix[i] = true; 225 updateLighting = true; 226 } 227 else ASSERT(false); 228 } 229 230 void VertexProcessor::setViewMatrix(const Matrix &V) 231 { 232 this->V = V; 233 234 updateMatrix = true; 235 updateViewMatrix = true; 236 } 237 238 void VertexProcessor::setBaseMatrix(const Matrix &B) 239 { 240 this->B = B; 241 242 updateMatrix = true; 243 updateBaseMatrix = true; 244 } 245 246 void VertexProcessor::setProjectionMatrix(const Matrix &P) 247 { 248 this->P = P; 249 context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f); 250 251 updateMatrix = true; 252 updateProjectionMatrix = true; 253 } 254 255 void VertexProcessor::setLightingEnable(bool lightingEnable) 256 { 257 context->setLightingEnable(lightingEnable); 258 259 updateLighting = true; 260 } 261 262 void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable) 263 { 264 if(light < 8) 265 { 266 context->setLightEnable(light, lightEnable); 267 } 268 else ASSERT(false); 269 270 updateLighting = true; 271 } 272 273 void VertexProcessor::setSpecularEnable(bool specularEnable) 274 { 275 context->setSpecularEnable(specularEnable); 276 277 updateLighting = true; 278 } 279 280 void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition) 281 { 282 if(light < 8) 283 { 284 context->setLightPosition(light, lightPosition); 285 } 286 else ASSERT(false); 287 288 updateLighting = true; 289 } 290 291 void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse) 292 { 293 if(light < 8) 294 { 295 ff.lightDiffuse[light][0] = lightDiffuse.r; 296 ff.lightDiffuse[light][1] = lightDiffuse.g; 297 ff.lightDiffuse[light][2] = lightDiffuse.b; 298 ff.lightDiffuse[light][3] = lightDiffuse.a; 299 } 300 else ASSERT(false); 301 } 302 303 void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular) 304 { 305 if(light < 8) 306 { 307 ff.lightSpecular[light][0] = lightSpecular.r; 308 ff.lightSpecular[light][1] = lightSpecular.g; 309 ff.lightSpecular[light][2] = lightSpecular.b; 310 ff.lightSpecular[light][3] = lightSpecular.a; 311 } 312 else ASSERT(false); 313 } 314 315 void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient) 316 { 317 if(light < 8) 318 { 319 ff.lightAmbient[light][0] = lightAmbient.r; 320 ff.lightAmbient[light][1] = lightAmbient.g; 321 ff.lightAmbient[light][2] = lightAmbient.b; 322 ff.lightAmbient[light][3] = lightAmbient.a; 323 } 324 else ASSERT(false); 325 } 326 327 void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic) 328 { 329 if(light < 8) 330 { 331 ff.attenuationConstant[light] = replicate(constant); 332 ff.attenuationLinear[light] = replicate(linear); 333 ff.attenuationQuadratic[light] = replicate(quadratic); 334 } 335 else ASSERT(false); 336 } 337 338 void VertexProcessor::setLightRange(unsigned int light, float lightRange) 339 { 340 if(light < 8) 341 { 342 ff.lightRange[light] = lightRange; 343 } 344 else ASSERT(false); 345 } 346 347 void VertexProcessor::setFogEnable(bool fogEnable) 348 { 349 context->fogEnable = fogEnable; 350 } 351 352 void VertexProcessor::setVertexFogMode(FogMode fogMode) 353 { 354 context->vertexFogMode = fogMode; 355 } 356 357 void VertexProcessor::setInstanceID(int instanceID) 358 { 359 context->instanceID = instanceID; 360 } 361 362 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable) 363 { 364 context->setColorVertexEnable(colorVertexEnable); 365 } 366 367 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource) 368 { 369 context->setDiffuseMaterialSource(diffuseMaterialSource); 370 } 371 372 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource) 373 { 374 context->setSpecularMaterialSource(specularMaterialSource); 375 } 376 377 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource) 378 { 379 context->setAmbientMaterialSource(ambientMaterialSource); 380 } 381 382 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource) 383 { 384 context->setEmissiveMaterialSource(emissiveMaterialSource); 385 } 386 387 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient) 388 { 389 ff.globalAmbient[0] = globalAmbient.r; 390 ff.globalAmbient[1] = globalAmbient.g; 391 ff.globalAmbient[2] = globalAmbient.b; 392 ff.globalAmbient[3] = globalAmbient.a; 393 } 394 395 void VertexProcessor::setMaterialEmission(const Color<float> &emission) 396 { 397 ff.materialEmission[0] = emission.r; 398 ff.materialEmission[1] = emission.g; 399 ff.materialEmission[2] = emission.b; 400 ff.materialEmission[3] = emission.a; 401 } 402 403 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient) 404 { 405 ff.materialAmbient[0] = materialAmbient.r; 406 ff.materialAmbient[1] = materialAmbient.g; 407 ff.materialAmbient[2] = materialAmbient.b; 408 ff.materialAmbient[3] = materialAmbient.a; 409 } 410 411 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor) 412 { 413 ff.materialDiffuse[0] = diffuseColor.r; 414 ff.materialDiffuse[1] = diffuseColor.g; 415 ff.materialDiffuse[2] = diffuseColor.b; 416 ff.materialDiffuse[3] = diffuseColor.a; 417 } 418 419 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor) 420 { 421 ff.materialSpecular[0] = specularColor.r; 422 ff.materialSpecular[1] = specularColor.g; 423 ff.materialSpecular[2] = specularColor.b; 424 ff.materialSpecular[3] = specularColor.a; 425 } 426 427 void VertexProcessor::setMaterialShininess(float specularPower) 428 { 429 ff.materialShininess = specularPower; 430 } 431 432 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P) 433 { 434 if(light < 8) 435 { 436 ff.lightPosition[light][0] = P.x; 437 ff.lightPosition[light][1] = P.y; 438 ff.lightPosition[light][2] = P.z; 439 ff.lightPosition[light][3] = 1; 440 } 441 else ASSERT(false); 442 } 443 444 void VertexProcessor::setRangeFogEnable(bool enable) 445 { 446 context->rangeFogEnable = enable; 447 } 448 449 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable) 450 { 451 context->indexedVertexBlendEnable = indexedVertexBlendEnable; 452 } 453 454 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount) 455 { 456 if(vertexBlendMatrixCount <= 4) 457 { 458 context->vertexBlendMatrixCount = vertexBlendMatrixCount; 459 } 460 else ASSERT(false); 461 } 462 463 void VertexProcessor::setTextureWrap(unsigned int stage, int mask) 464 { 465 if(stage < TEXTURE_IMAGE_UNITS) 466 { 467 context->textureWrap[stage] = mask; 468 } 469 else ASSERT(false); 470 471 context->textureWrapActive = false; 472 473 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++) 474 { 475 context->textureWrapActive |= (context->textureWrap[i] != 0x00); 476 } 477 } 478 479 void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen) 480 { 481 if(stage < 8) 482 { 483 context->texGen[stage] = texGen; 484 } 485 else ASSERT(false); 486 } 487 488 void VertexProcessor::setLocalViewer(bool localViewer) 489 { 490 context->localViewer = localViewer; 491 } 492 493 void VertexProcessor::setNormalizeNormals(bool normalizeNormals) 494 { 495 context->normalizeNormals = normalizeNormals; 496 } 497 498 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T) 499 { 500 for(int i = 0; i < 4; i++) 501 { 502 for(int j = 0; j < 4; j++) 503 { 504 ff.textureTransform[stage][i][j] = T[i][j]; 505 } 506 } 507 } 508 509 void VertexProcessor::setTextureTransform(int stage, int count, bool project) 510 { 511 context->textureTransformCount[stage] = count; 512 context->textureTransformProject[stage] = project; 513 } 514 515 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter) 516 { 517 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 518 { 519 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setTextureFilter(textureFilter); 520 } 521 else ASSERT(false); 522 } 523 524 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter) 525 { 526 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 527 { 528 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapFilter(mipmapFilter); 529 } 530 else ASSERT(false); 531 } 532 533 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable) 534 { 535 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 536 { 537 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setGatherEnable(enable); 538 } 539 else ASSERT(false); 540 } 541 542 void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode) 543 { 544 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 545 { 546 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeU(addressMode); 547 } 548 else ASSERT(false); 549 } 550 551 void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode) 552 { 553 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 554 { 555 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeV(addressMode); 556 } 557 else ASSERT(false); 558 } 559 560 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode) 561 { 562 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 563 { 564 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeW(addressMode); 565 } 566 else ASSERT(false); 567 } 568 569 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB) 570 { 571 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 572 { 573 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setReadSRGB(sRGB); 574 } 575 else ASSERT(false); 576 } 577 578 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias) 579 { 580 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 581 { 582 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapLOD(bias); 583 } 584 else ASSERT(false); 585 } 586 587 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor) 588 { 589 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 590 { 591 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBorderColor(borderColor); 592 } 593 else ASSERT(false); 594 } 595 596 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy) 597 { 598 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 599 { 600 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy); 601 } 602 else ASSERT(false); 603 } 604 605 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR) 606 { 607 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 608 { 609 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR); 610 } 611 else ASSERT(false); 612 } 613 614 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG) 615 { 616 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 617 { 618 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG); 619 } 620 else ASSERT(false); 621 } 622 623 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB) 624 { 625 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 626 { 627 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB); 628 } 629 else ASSERT(false); 630 } 631 632 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA) 633 { 634 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 635 { 636 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA); 637 } 638 else ASSERT(false); 639 } 640 641 void VertexProcessor::setPointSize(float pointSize) 642 { 643 point.pointSize = replicate(pointSize); 644 } 645 646 void VertexProcessor::setPointSizeMin(float pointSizeMin) 647 { 648 point.pointSizeMin = pointSizeMin; 649 } 650 651 void VertexProcessor::setPointSizeMax(float pointSizeMax) 652 { 653 point.pointSizeMax = pointSizeMax; 654 } 655 656 void VertexProcessor::setPointScaleA(float pointScaleA) 657 { 658 point.pointScaleA = pointScaleA; 659 } 660 661 void VertexProcessor::setPointScaleB(float pointScaleB) 662 { 663 point.pointScaleB = pointScaleB; 664 } 665 666 void VertexProcessor::setPointScaleC(float pointScaleC) 667 { 668 point.pointScaleC = pointScaleC; 669 } 670 671 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable) 672 { 673 context->transformFeedbackQueryEnabled = enable; 674 } 675 676 void VertexProcessor::enableTransformFeedback(uint64_t enable) 677 { 678 context->transformFeedbackEnabled = enable; 679 } 680 681 const Matrix &VertexProcessor::getModelTransform(int i) 682 { 683 updateTransform(); 684 return PBVM[i]; 685 } 686 687 const Matrix &VertexProcessor::getViewTransform() 688 { 689 updateTransform(); 690 return PBV; 691 } 692 693 bool VertexProcessor::isFixedFunction() 694 { 695 return !context->vertexShader; 696 } 697 698 void VertexProcessor::setTransform(const Matrix &M, int i) 699 { 700 ff.transformT[i][0][0] = M[0][0]; 701 ff.transformT[i][0][1] = M[1][0]; 702 ff.transformT[i][0][2] = M[2][0]; 703 ff.transformT[i][0][3] = M[3][0]; 704 705 ff.transformT[i][1][0] = M[0][1]; 706 ff.transformT[i][1][1] = M[1][1]; 707 ff.transformT[i][1][2] = M[2][1]; 708 ff.transformT[i][1][3] = M[3][1]; 709 710 ff.transformT[i][2][0] = M[0][2]; 711 ff.transformT[i][2][1] = M[1][2]; 712 ff.transformT[i][2][2] = M[2][2]; 713 ff.transformT[i][2][3] = M[3][2]; 714 715 ff.transformT[i][3][0] = M[0][3]; 716 ff.transformT[i][3][1] = M[1][3]; 717 ff.transformT[i][3][2] = M[2][3]; 718 ff.transformT[i][3][3] = M[3][3]; 719 } 720 721 void VertexProcessor::setCameraTransform(const Matrix &M, int i) 722 { 723 ff.cameraTransformT[i][0][0] = M[0][0]; 724 ff.cameraTransformT[i][0][1] = M[1][0]; 725 ff.cameraTransformT[i][0][2] = M[2][0]; 726 ff.cameraTransformT[i][0][3] = M[3][0]; 727 728 ff.cameraTransformT[i][1][0] = M[0][1]; 729 ff.cameraTransformT[i][1][1] = M[1][1]; 730 ff.cameraTransformT[i][1][2] = M[2][1]; 731 ff.cameraTransformT[i][1][3] = M[3][1]; 732 733 ff.cameraTransformT[i][2][0] = M[0][2]; 734 ff.cameraTransformT[i][2][1] = M[1][2]; 735 ff.cameraTransformT[i][2][2] = M[2][2]; 736 ff.cameraTransformT[i][2][3] = M[3][2]; 737 738 ff.cameraTransformT[i][3][0] = M[0][3]; 739 ff.cameraTransformT[i][3][1] = M[1][3]; 740 ff.cameraTransformT[i][3][2] = M[2][3]; 741 ff.cameraTransformT[i][3][3] = M[3][3]; 742 } 743 744 void VertexProcessor::setNormalTransform(const Matrix &M, int i) 745 { 746 ff.normalTransformT[i][0][0] = M[0][0]; 747 ff.normalTransformT[i][0][1] = M[1][0]; 748 ff.normalTransformT[i][0][2] = M[2][0]; 749 ff.normalTransformT[i][0][3] = M[3][0]; 750 751 ff.normalTransformT[i][1][0] = M[0][1]; 752 ff.normalTransformT[i][1][1] = M[1][1]; 753 ff.normalTransformT[i][1][2] = M[2][1]; 754 ff.normalTransformT[i][1][3] = M[3][1]; 755 756 ff.normalTransformT[i][2][0] = M[0][2]; 757 ff.normalTransformT[i][2][1] = M[1][2]; 758 ff.normalTransformT[i][2][2] = M[2][2]; 759 ff.normalTransformT[i][2][3] = M[3][2]; 760 761 ff.normalTransformT[i][3][0] = M[0][3]; 762 ff.normalTransformT[i][3][1] = M[1][3]; 763 ff.normalTransformT[i][3][2] = M[2][3]; 764 ff.normalTransformT[i][3][3] = M[3][3]; 765 } 766 767 void VertexProcessor::updateTransform() 768 { 769 if(!updateMatrix) return; 770 771 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1); 772 773 if(updateProjectionMatrix) 774 { 775 PB = P * B; 776 PBV = PB * V; 777 778 for(int i = 0; i < activeMatrices; i++) 779 { 780 PBVM[i] = PBV * M[i]; 781 updateModelMatrix[i] = false; 782 } 783 784 updateProjectionMatrix = false; 785 updateBaseMatrix = false; 786 updateViewMatrix = false; 787 } 788 789 if(updateBaseMatrix) 790 { 791 PB = P * B; 792 PBV = PB * V; 793 794 for(int i = 0; i < activeMatrices; i++) 795 { 796 PBVM[i] = PBV * M[i]; 797 updateModelMatrix[i] = false; 798 } 799 800 updateBaseMatrix = false; 801 updateViewMatrix = false; 802 } 803 804 if(updateViewMatrix) 805 { 806 PBV = PB * V; 807 808 for(int i = 0; i < activeMatrices; i++) 809 { 810 PBVM[i] = PBV * M[i]; 811 updateModelMatrix[i] = false; 812 } 813 814 updateViewMatrix = false; 815 } 816 817 for(int i = 0; i < activeMatrices; i++) 818 { 819 if(updateModelMatrix[i]) 820 { 821 PBVM[i] = PBV * M[i]; 822 updateModelMatrix[i] = false; 823 } 824 } 825 826 for(int i = 0; i < activeMatrices; i++) 827 { 828 setTransform(PBVM[i], i); 829 setCameraTransform(B * V * M[i], i); 830 setNormalTransform(~!(B * V * M[i]), i); 831 } 832 833 updateMatrix = false; 834 } 835 836 void VertexProcessor::setRoutineCacheSize(int cacheSize) 837 { 838 delete routineCache; 839 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0); 840 } 841 842 const VertexProcessor::State VertexProcessor::update(DrawType drawType) 843 { 844 if(isFixedFunction()) 845 { 846 updateTransform(); 847 848 if(updateLighting) 849 { 850 for(int i = 0; i < 8; i++) 851 { 852 if(context->vertexLightActive(i)) 853 { 854 // Light position in camera coordinates 855 setLightViewPosition(i, B * V * context->getLightPosition(i)); 856 } 857 } 858 859 updateLighting = false; 860 } 861 } 862 863 State state; 864 865 if(context->vertexShader) 866 { 867 state.shaderID = context->vertexShader->getSerialID(); 868 } 869 else 870 { 871 state.shaderID = 0; 872 } 873 874 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300; 875 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false; 876 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos; 877 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts; 878 879 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive(); 880 state.indexedVertexBlendEnable = context->indexedVertexBlendActive(); 881 state.vertexNormalActive = context->vertexNormalActive(); 882 state.normalizeNormals = context->normalizeNormalsActive(); 883 state.vertexLightingActive = context->vertexLightingActive(); 884 state.diffuseActive = context->diffuseActive(); 885 state.specularActive = context->specularActive(); 886 state.vertexSpecularActive = context->vertexSpecularActive(); 887 888 state.vertexLightActive = context->vertexLightActive(0) << 0 | 889 context->vertexLightActive(1) << 1 | 890 context->vertexLightActive(2) << 2 | 891 context->vertexLightActive(3) << 3 | 892 context->vertexLightActive(4) << 4 | 893 context->vertexLightActive(5) << 5 | 894 context->vertexLightActive(6) << 6 | 895 context->vertexLightActive(7) << 7; 896 897 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive(); 898 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive(); 899 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive(); 900 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive(); 901 state.fogActive = context->fogActive(); 902 state.vertexFogMode = context->vertexFogModeActive(); 903 state.rangeFogActive = context->rangeFogActive(); 904 state.localViewerActive = context->localViewerActive(); 905 state.pointSizeActive = context->pointSizeActive(); 906 state.pointScaleActive = context->pointScaleActive(); 907 908 state.preTransformed = context->preTransformed; 909 state.superSampling = context->getSuperSampleCount() > 1; 910 state.multiSampling = context->getMultiSampleCount() > 1; 911 912 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled; 913 state.transformFeedbackEnabled = context->transformFeedbackEnabled; 914 915 // Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback, 916 // which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type. 917 DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF); 918 state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST); 919 920 for(int i = 0; i < MAX_VERTEX_INPUTS; i++) 921 { 922 state.input[i].type = context->input[i].type; 923 state.input[i].count = context->input[i].count; 924 state.input[i].normalized = context->input[i].normalized; 925 } 926 927 if(!context->vertexShader) 928 { 929 for(int i = 0; i < 8; i++) 930 { 931 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0); 932 state.textureState[i].texGenActive = context->texGenActive(i); 933 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i); 934 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i); 935 } 936 } 937 else 938 { 939 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++) 940 { 941 if(context->vertexShader->usesSampler(i)) 942 { 943 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState(); 944 } 945 } 946 } 947 948 if(context->vertexShader) // FIXME: Also when pre-transformed? 949 { 950 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++) 951 { 952 state.output[i].xWrite = context->vertexShader->output[i][0].active(); 953 state.output[i].yWrite = context->vertexShader->output[i][1].active(); 954 state.output[i].zWrite = context->vertexShader->output[i][2].active(); 955 state.output[i].wWrite = context->vertexShader->output[i][3].active(); 956 } 957 } 958 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300) 959 { 960 state.output[Pos].write = 0xF; 961 962 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0])) 963 { 964 state.output[C0].write = 0xF; 965 } 966 967 if(context->specularActive()) 968 { 969 state.output[C1].write = 0xF; 970 } 971 972 for(int stage = 0; stage < 8; stage++) 973 { 974 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01; 975 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02; 976 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04; 977 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08; 978 } 979 980 if(context->fogActive()) 981 { 982 state.output[Fog].xWrite = true; 983 } 984 985 if(context->pointSizeActive()) 986 { 987 state.output[Pts].yWrite = true; 988 } 989 } 990 else 991 { 992 state.output[Pos].write = 0xF; 993 994 for(int i = 0; i < 2; i++) 995 { 996 if(context->input[Color0 + i]) 997 { 998 state.output[C0 + i].write = 0xF; 999 } 1000 } 1001 1002 for(int i = 0; i < 8; i++) 1003 { 1004 if(context->input[TexCoord0 + i]) 1005 { 1006 state.output[T0 + i].write = 0xF; 1007 } 1008 } 1009 1010 if(context->input[PointSize]) 1011 { 1012 state.output[Pts].yWrite = true; 1013 } 1014 } 1015 1016 if(context->vertexShaderVersion() < 0x0300) 1017 { 1018 state.output[C0].clamp = 0xF; 1019 state.output[C1].clamp = 0xF; 1020 state.output[Fog].xClamp = true; 1021 } 1022 1023 state.hash = state.computeHash(); 1024 1025 return state; 1026 } 1027 1028 Routine *VertexProcessor::routine(const State &state) 1029 { 1030 Routine *routine = routineCache->query(state); 1031 1032 if(!routine) // Create one 1033 { 1034 VertexRoutine *generator = 0; 1035 1036 if(state.fixedFunction) 1037 { 1038 generator = new VertexPipeline(state); 1039 } 1040 else 1041 { 1042 generator = new VertexProgram(state, context->vertexShader); 1043 } 1044 1045 generator->generate(); 1046 routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID); 1047 delete generator; 1048 1049 routineCache->add(state, routine); 1050 } 1051 1052 return routine; 1053 } 1054 } 1055