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 "Shader/VertexPipeline.hpp" 18 #include "Shader/VertexProgram.hpp" 19 #include "Shader/VertexShader.hpp" 20 #include "Shader/PixelShader.hpp" 21 #include "Shader/Constants.hpp" 22 #include "Common/Math.hpp" 23 #include "Common/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, unsigned int 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::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering) 606 { 607 if(sampler < TEXTURE_IMAGE_UNITS) 608 { 609 context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering); 610 } 611 else ASSERT(false); 612 } 613 614 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR) 615 { 616 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 617 { 618 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR); 619 } 620 else ASSERT(false); 621 } 622 623 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG) 624 { 625 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 626 { 627 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG); 628 } 629 else ASSERT(false); 630 } 631 632 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB) 633 { 634 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 635 { 636 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB); 637 } 638 else ASSERT(false); 639 } 640 641 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA) 642 { 643 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 644 { 645 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA); 646 } 647 else ASSERT(false); 648 } 649 650 void VertexProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc) 651 { 652 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 653 { 654 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setCompareFunc(compFunc); 655 } 656 else ASSERT(false); 657 } 658 659 void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel) 660 { 661 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 662 { 663 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBaseLevel(baseLevel); 664 } 665 else ASSERT(false); 666 } 667 668 void VertexProcessor::setMaxLevel(unsigned int sampler, int maxLevel) 669 { 670 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 671 { 672 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLevel(maxLevel); 673 } 674 else ASSERT(false); 675 } 676 677 void VertexProcessor::setMinLod(unsigned int sampler, float minLod) 678 { 679 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 680 { 681 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod); 682 } 683 else ASSERT(false); 684 } 685 686 void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod) 687 { 688 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 689 { 690 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod); 691 } 692 else ASSERT(false); 693 } 694 695 void VertexProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired) 696 { 697 if(sampler < TEXTURE_IMAGE_UNITS) 698 { 699 context->sampler[sampler].setSyncRequired(isSincRequired); 700 } 701 else ASSERT(false); 702 } 703 704 void VertexProcessor::setPointSize(float pointSize) 705 { 706 point.pointSize = replicate(pointSize); 707 } 708 709 void VertexProcessor::setPointSizeMin(float pointSizeMin) 710 { 711 point.pointSizeMin = pointSizeMin; 712 } 713 714 void VertexProcessor::setPointSizeMax(float pointSizeMax) 715 { 716 point.pointSizeMax = pointSizeMax; 717 } 718 719 void VertexProcessor::setPointScaleA(float pointScaleA) 720 { 721 point.pointScaleA = pointScaleA; 722 } 723 724 void VertexProcessor::setPointScaleB(float pointScaleB) 725 { 726 point.pointScaleB = pointScaleB; 727 } 728 729 void VertexProcessor::setPointScaleC(float pointScaleC) 730 { 731 point.pointScaleC = pointScaleC; 732 } 733 734 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable) 735 { 736 context->transformFeedbackQueryEnabled = enable; 737 } 738 739 void VertexProcessor::enableTransformFeedback(uint64_t enable) 740 { 741 context->transformFeedbackEnabled = enable; 742 } 743 744 const Matrix &VertexProcessor::getModelTransform(int i) 745 { 746 updateTransform(); 747 return PBVM[i]; 748 } 749 750 const Matrix &VertexProcessor::getViewTransform() 751 { 752 updateTransform(); 753 return PBV; 754 } 755 756 bool VertexProcessor::isFixedFunction() 757 { 758 return !context->vertexShader; 759 } 760 761 void VertexProcessor::setTransform(const Matrix &M, int i) 762 { 763 ff.transformT[i][0][0] = M[0][0]; 764 ff.transformT[i][0][1] = M[1][0]; 765 ff.transformT[i][0][2] = M[2][0]; 766 ff.transformT[i][0][3] = M[3][0]; 767 768 ff.transformT[i][1][0] = M[0][1]; 769 ff.transformT[i][1][1] = M[1][1]; 770 ff.transformT[i][1][2] = M[2][1]; 771 ff.transformT[i][1][3] = M[3][1]; 772 773 ff.transformT[i][2][0] = M[0][2]; 774 ff.transformT[i][2][1] = M[1][2]; 775 ff.transformT[i][2][2] = M[2][2]; 776 ff.transformT[i][2][3] = M[3][2]; 777 778 ff.transformT[i][3][0] = M[0][3]; 779 ff.transformT[i][3][1] = M[1][3]; 780 ff.transformT[i][3][2] = M[2][3]; 781 ff.transformT[i][3][3] = M[3][3]; 782 } 783 784 void VertexProcessor::setCameraTransform(const Matrix &M, int i) 785 { 786 ff.cameraTransformT[i][0][0] = M[0][0]; 787 ff.cameraTransformT[i][0][1] = M[1][0]; 788 ff.cameraTransformT[i][0][2] = M[2][0]; 789 ff.cameraTransformT[i][0][3] = M[3][0]; 790 791 ff.cameraTransformT[i][1][0] = M[0][1]; 792 ff.cameraTransformT[i][1][1] = M[1][1]; 793 ff.cameraTransformT[i][1][2] = M[2][1]; 794 ff.cameraTransformT[i][1][3] = M[3][1]; 795 796 ff.cameraTransformT[i][2][0] = M[0][2]; 797 ff.cameraTransformT[i][2][1] = M[1][2]; 798 ff.cameraTransformT[i][2][2] = M[2][2]; 799 ff.cameraTransformT[i][2][3] = M[3][2]; 800 801 ff.cameraTransformT[i][3][0] = M[0][3]; 802 ff.cameraTransformT[i][3][1] = M[1][3]; 803 ff.cameraTransformT[i][3][2] = M[2][3]; 804 ff.cameraTransformT[i][3][3] = M[3][3]; 805 } 806 807 void VertexProcessor::setNormalTransform(const Matrix &M, int i) 808 { 809 ff.normalTransformT[i][0][0] = M[0][0]; 810 ff.normalTransformT[i][0][1] = M[1][0]; 811 ff.normalTransformT[i][0][2] = M[2][0]; 812 ff.normalTransformT[i][0][3] = M[3][0]; 813 814 ff.normalTransformT[i][1][0] = M[0][1]; 815 ff.normalTransformT[i][1][1] = M[1][1]; 816 ff.normalTransformT[i][1][2] = M[2][1]; 817 ff.normalTransformT[i][1][3] = M[3][1]; 818 819 ff.normalTransformT[i][2][0] = M[0][2]; 820 ff.normalTransformT[i][2][1] = M[1][2]; 821 ff.normalTransformT[i][2][2] = M[2][2]; 822 ff.normalTransformT[i][2][3] = M[3][2]; 823 824 ff.normalTransformT[i][3][0] = M[0][3]; 825 ff.normalTransformT[i][3][1] = M[1][3]; 826 ff.normalTransformT[i][3][2] = M[2][3]; 827 ff.normalTransformT[i][3][3] = M[3][3]; 828 } 829 830 void VertexProcessor::updateTransform() 831 { 832 if(!updateMatrix) return; 833 834 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1); 835 836 if(updateProjectionMatrix) 837 { 838 PB = P * B; 839 PBV = PB * V; 840 841 for(int i = 0; i < activeMatrices; i++) 842 { 843 PBVM[i] = PBV * M[i]; 844 updateModelMatrix[i] = false; 845 } 846 847 updateProjectionMatrix = false; 848 updateBaseMatrix = false; 849 updateViewMatrix = false; 850 } 851 852 if(updateBaseMatrix) 853 { 854 PB = P * B; 855 PBV = PB * V; 856 857 for(int i = 0; i < activeMatrices; i++) 858 { 859 PBVM[i] = PBV * M[i]; 860 updateModelMatrix[i] = false; 861 } 862 863 updateBaseMatrix = false; 864 updateViewMatrix = false; 865 } 866 867 if(updateViewMatrix) 868 { 869 PBV = PB * V; 870 871 for(int i = 0; i < activeMatrices; i++) 872 { 873 PBVM[i] = PBV * M[i]; 874 updateModelMatrix[i] = false; 875 } 876 877 updateViewMatrix = false; 878 } 879 880 for(int i = 0; i < activeMatrices; i++) 881 { 882 if(updateModelMatrix[i]) 883 { 884 PBVM[i] = PBV * M[i]; 885 updateModelMatrix[i] = false; 886 } 887 } 888 889 for(int i = 0; i < activeMatrices; i++) 890 { 891 setTransform(PBVM[i], i); 892 setCameraTransform(B * V * M[i], i); 893 setNormalTransform(~!(B * V * M[i]), i); 894 } 895 896 updateMatrix = false; 897 } 898 899 void VertexProcessor::setRoutineCacheSize(int cacheSize) 900 { 901 delete routineCache; 902 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0); 903 } 904 905 const VertexProcessor::State VertexProcessor::update(DrawType drawType) 906 { 907 if(isFixedFunction()) 908 { 909 updateTransform(); 910 911 if(updateLighting) 912 { 913 for(int i = 0; i < 8; i++) 914 { 915 if(context->vertexLightActive(i)) 916 { 917 // Light position in camera coordinates 918 setLightViewPosition(i, B * V * context->getLightPosition(i)); 919 } 920 } 921 922 updateLighting = false; 923 } 924 } 925 926 State state; 927 928 if(context->vertexShader) 929 { 930 state.shaderID = context->vertexShader->getSerialID(); 931 } 932 else 933 { 934 state.shaderID = 0; 935 } 936 937 state.fixedFunction = !context->vertexShader && context->pixelShaderModel() < 0x0300; 938 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false; 939 state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos; 940 state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts; 941 942 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive(); 943 state.indexedVertexBlendEnable = context->indexedVertexBlendActive(); 944 state.vertexNormalActive = context->vertexNormalActive(); 945 state.normalizeNormals = context->normalizeNormalsActive(); 946 state.vertexLightingActive = context->vertexLightingActive(); 947 state.diffuseActive = context->diffuseActive(); 948 state.specularActive = context->specularActive(); 949 state.vertexSpecularActive = context->vertexSpecularActive(); 950 951 state.vertexLightActive = context->vertexLightActive(0) << 0 | 952 context->vertexLightActive(1) << 1 | 953 context->vertexLightActive(2) << 2 | 954 context->vertexLightActive(3) << 3 | 955 context->vertexLightActive(4) << 4 | 956 context->vertexLightActive(5) << 5 | 957 context->vertexLightActive(6) << 6 | 958 context->vertexLightActive(7) << 7; 959 960 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive(); 961 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive(); 962 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive(); 963 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive(); 964 state.fogActive = context->fogActive(); 965 state.vertexFogMode = context->vertexFogModeActive(); 966 state.rangeFogActive = context->rangeFogActive(); 967 state.localViewerActive = context->localViewerActive(); 968 state.pointSizeActive = context->pointSizeActive(); 969 state.pointScaleActive = context->pointScaleActive(); 970 971 state.preTransformed = context->preTransformed; 972 state.superSampling = context->getSuperSampleCount() > 1; 973 state.multiSampling = context->getMultiSampleCount() > 1; 974 975 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled; 976 state.transformFeedbackEnabled = context->transformFeedbackEnabled; 977 978 // Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback, 979 // which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type. 980 DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF); 981 state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST); 982 983 for(int i = 0; i < MAX_VERTEX_INPUTS; i++) 984 { 985 state.input[i].type = context->input[i].type; 986 state.input[i].count = context->input[i].count; 987 state.input[i].normalized = context->input[i].normalized; 988 state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT; 989 } 990 991 if(!context->vertexShader) 992 { 993 for(int i = 0; i < 8; i++) 994 { 995 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0); 996 state.textureState[i].texGenActive = context->texGenActive(i); 997 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i); 998 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i); 999 } 1000 } 1001 else 1002 { 1003 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++) 1004 { 1005 if(context->vertexShader->usesSampler(i)) 1006 { 1007 state.sampler[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState(); 1008 } 1009 } 1010 } 1011 1012 if(context->vertexShader) // FIXME: Also when pre-transformed? 1013 { 1014 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++) 1015 { 1016 state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active(); 1017 state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active(); 1018 state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active(); 1019 state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active(); 1020 } 1021 } 1022 else if(!context->preTransformed || context->pixelShaderModel() < 0x0300) 1023 { 1024 state.output[Pos].write = 0xF; 1025 1026 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0])) 1027 { 1028 state.output[C0].write = 0xF; 1029 } 1030 1031 if(context->specularActive()) 1032 { 1033 state.output[C1].write = 0xF; 1034 } 1035 1036 for(int stage = 0; stage < 8; stage++) 1037 { 1038 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01; 1039 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02; 1040 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04; 1041 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08; 1042 } 1043 1044 if(context->fogActive()) 1045 { 1046 state.output[Fog].xWrite = true; 1047 } 1048 1049 if(context->pointSizeActive()) 1050 { 1051 state.output[Pts].yWrite = true; 1052 } 1053 } 1054 else 1055 { 1056 state.output[Pos].write = 0xF; 1057 1058 for(int i = 0; i < 2; i++) 1059 { 1060 if(context->input[Color0 + i]) 1061 { 1062 state.output[C0 + i].write = 0xF; 1063 } 1064 } 1065 1066 for(int i = 0; i < 8; i++) 1067 { 1068 if(context->input[TexCoord0 + i]) 1069 { 1070 state.output[T0 + i].write = 0xF; 1071 } 1072 } 1073 1074 if(context->input[PointSize]) 1075 { 1076 state.output[Pts].yWrite = true; 1077 } 1078 } 1079 1080 if(context->vertexShaderModel() < 0x0300) 1081 { 1082 state.output[C0].clamp = 0xF; 1083 state.output[C1].clamp = 0xF; 1084 state.output[Fog].xClamp = true; 1085 } 1086 1087 state.hash = state.computeHash(); 1088 1089 return state; 1090 } 1091 1092 Routine *VertexProcessor::routine(const State &state) 1093 { 1094 Routine *routine = routineCache->query(state); 1095 1096 if(!routine) // Create one 1097 { 1098 VertexRoutine *generator = nullptr; 1099 1100 if(state.fixedFunction) 1101 { 1102 generator = new VertexPipeline(state); 1103 } 1104 else 1105 { 1106 generator = new VertexProgram(state, context->vertexShader); 1107 } 1108 1109 generator->generate(); 1110 routine = (*generator)("VertexRoutine_%0.8X", state.shaderID); 1111 delete generator; 1112 1113 routineCache->add(state, routine); 1114 } 1115 1116 return routine; 1117 } 1118 } 1119