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 clear()31 void VertexCache::clear() 32 { 33 for(int i = 0; i < 16; i++) 34 { 35 tag[i] = 0x80000000; 36 } 37 } 38 computeHash()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 State()52 VertexProcessor::State::State() 53 { 54 memset(this, 0, sizeof(State)); 55 } 56 operator ==(const State & state) const57 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 TransformFeedbackInfo()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 UniformBufferInfo()77 VertexProcessor::UniformBufferInfo::UniformBufferInfo() 78 { 79 buffer = nullptr; 80 offset = 0; 81 } 82 VertexProcessor(Context * context)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 ~VertexProcessor()125 VertexProcessor::~VertexProcessor() 126 { 127 delete routineCache; 128 routineCache = 0; 129 } 130 setInputStream(int index,const Stream & stream)131 void VertexProcessor::setInputStream(int index, const Stream &stream) 132 { 133 context->input[index] = stream; 134 } 135 resetInputStreams(bool preTransformed)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 setFloatConstant(unsigned int index,const float value[4])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 setIntegerConstant(unsigned int index,const int integer[4])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 setBooleanConstant(unsigned int index,int boolean)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 setUniformBuffer(int index,sw::Resource * buffer,int offset)179 void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset) 180 { 181 uniformBufferInfo[index].buffer = buffer; 182 uniformBufferInfo[index].offset = offset; 183 } 184 lockUniformBuffers(byte ** u,sw::Resource * uniformBuffers[])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 setTransformFeedbackBuffer(int index,sw::Resource * buffer,int offset,unsigned int reg,unsigned int row,unsigned int col,unsigned int stride)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 lockTransformFeedbackBuffers(byte ** t,unsigned int * v,unsigned int * r,unsigned int * c,unsigned int * s,sw::Resource * transformFeedbackBuffers[])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 setModelMatrix(const Matrix & M,int i)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 setViewMatrix(const Matrix & V)230 void VertexProcessor::setViewMatrix(const Matrix &V) 231 { 232 this->V = V; 233 234 updateMatrix = true; 235 updateViewMatrix = true; 236 } 237 setBaseMatrix(const Matrix & B)238 void VertexProcessor::setBaseMatrix(const Matrix &B) 239 { 240 this->B = B; 241 242 updateMatrix = true; 243 updateBaseMatrix = true; 244 } 245 setProjectionMatrix(const Matrix & P)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 setLightingEnable(bool lightingEnable)255 void VertexProcessor::setLightingEnable(bool lightingEnable) 256 { 257 context->setLightingEnable(lightingEnable); 258 259 updateLighting = true; 260 } 261 setLightEnable(unsigned int light,bool lightEnable)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 setSpecularEnable(bool specularEnable)273 void VertexProcessor::setSpecularEnable(bool specularEnable) 274 { 275 context->setSpecularEnable(specularEnable); 276 277 updateLighting = true; 278 } 279 setLightPosition(unsigned int light,const Point & lightPosition)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 setLightDiffuse(unsigned int light,const Color<float> & lightDiffuse)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 setLightSpecular(unsigned int light,const Color<float> & lightSpecular)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 setLightAmbient(unsigned int light,const Color<float> & lightAmbient)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 setLightAttenuation(unsigned int light,float constant,float linear,float quadratic)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 setLightRange(unsigned int light,float lightRange)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 setFogEnable(bool fogEnable)347 void VertexProcessor::setFogEnable(bool fogEnable) 348 { 349 context->fogEnable = fogEnable; 350 } 351 setVertexFogMode(FogMode fogMode)352 void VertexProcessor::setVertexFogMode(FogMode fogMode) 353 { 354 context->vertexFogMode = fogMode; 355 } 356 setInstanceID(int instanceID)357 void VertexProcessor::setInstanceID(int instanceID) 358 { 359 context->instanceID = instanceID; 360 } 361 setColorVertexEnable(bool colorVertexEnable)362 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable) 363 { 364 context->setColorVertexEnable(colorVertexEnable); 365 } 366 setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)367 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource) 368 { 369 context->setDiffuseMaterialSource(diffuseMaterialSource); 370 } 371 setSpecularMaterialSource(MaterialSource specularMaterialSource)372 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource) 373 { 374 context->setSpecularMaterialSource(specularMaterialSource); 375 } 376 setAmbientMaterialSource(MaterialSource ambientMaterialSource)377 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource) 378 { 379 context->setAmbientMaterialSource(ambientMaterialSource); 380 } 381 setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)382 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource) 383 { 384 context->setEmissiveMaterialSource(emissiveMaterialSource); 385 } 386 setGlobalAmbient(const Color<float> & globalAmbient)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 setMaterialEmission(const Color<float> & emission)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 setMaterialAmbient(const Color<float> & materialAmbient)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 setMaterialDiffuse(const Color<float> & diffuseColor)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 setMaterialSpecular(const Color<float> & specularColor)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 setMaterialShininess(float specularPower)427 void VertexProcessor::setMaterialShininess(float specularPower) 428 { 429 ff.materialShininess = specularPower; 430 } 431 setLightViewPosition(unsigned int light,const Point & P)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 setRangeFogEnable(bool enable)444 void VertexProcessor::setRangeFogEnable(bool enable) 445 { 446 context->rangeFogEnable = enable; 447 } 448 setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)449 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable) 450 { 451 context->indexedVertexBlendEnable = indexedVertexBlendEnable; 452 } 453 setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)454 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount) 455 { 456 if(vertexBlendMatrixCount <= 4) 457 { 458 context->vertexBlendMatrixCount = vertexBlendMatrixCount; 459 } 460 else ASSERT(false); 461 } 462 setTextureWrap(unsigned int stage,int mask)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 setTexGen(unsigned int stage,TexGen texGen)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 setLocalViewer(bool localViewer)488 void VertexProcessor::setLocalViewer(bool localViewer) 489 { 490 context->localViewer = localViewer; 491 } 492 setNormalizeNormals(bool normalizeNormals)493 void VertexProcessor::setNormalizeNormals(bool normalizeNormals) 494 { 495 context->normalizeNormals = normalizeNormals; 496 } 497 setTextureMatrix(int stage,const Matrix & T)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 setTextureTransform(int stage,int count,bool project)509 void VertexProcessor::setTextureTransform(int stage, int count, bool project) 510 { 511 context->textureTransformCount[stage] = count; 512 context->textureTransformProject[stage] = project; 513 } 514 setTextureFilter(unsigned int sampler,FilterType textureFilter)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 setMipmapFilter(unsigned int sampler,MipmapType mipmapFilter)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 setGatherEnable(unsigned int sampler,bool enable)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 setAddressingModeU(unsigned int sampler,AddressingMode addressMode)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 setAddressingModeV(unsigned int sampler,AddressingMode addressMode)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 setAddressingModeW(unsigned int sampler,AddressingMode addressMode)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 setReadSRGB(unsigned int sampler,bool sRGB)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 setMipmapLOD(unsigned int sampler,float bias)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 setBorderColor(unsigned int sampler,const Color<float> & borderColor)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 setMaxAnisotropy(unsigned int sampler,float maxAnisotropy)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 setHighPrecisionFiltering(unsigned int sampler,bool highPrecisionFiltering)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 setSwizzleR(unsigned int sampler,SwizzleType swizzleR)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 setSwizzleG(unsigned int sampler,SwizzleType swizzleG)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 setSwizzleB(unsigned int sampler,SwizzleType swizzleB)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 setSwizzleA(unsigned int sampler,SwizzleType swizzleA)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 setBaseLevel(unsigned int sampler,int baseLevel)650 void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel) 651 { 652 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 653 { 654 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBaseLevel(baseLevel); 655 } 656 else ASSERT(false); 657 } 658 setMaxLevel(unsigned int sampler,int maxLevel)659 void VertexProcessor::setMaxLevel(unsigned int sampler, int maxLevel) 660 { 661 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 662 { 663 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLevel(maxLevel); 664 } 665 else ASSERT(false); 666 } 667 setMinLod(unsigned int sampler,float minLod)668 void VertexProcessor::setMinLod(unsigned int sampler, float minLod) 669 { 670 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 671 { 672 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod); 673 } 674 else ASSERT(false); 675 } 676 setMaxLod(unsigned int sampler,float maxLod)677 void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod) 678 { 679 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) 680 { 681 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod); 682 } 683 else ASSERT(false); 684 } 685 setPointSize(float pointSize)686 void VertexProcessor::setPointSize(float pointSize) 687 { 688 point.pointSize = replicate(pointSize); 689 } 690 setPointSizeMin(float pointSizeMin)691 void VertexProcessor::setPointSizeMin(float pointSizeMin) 692 { 693 point.pointSizeMin = pointSizeMin; 694 } 695 setPointSizeMax(float pointSizeMax)696 void VertexProcessor::setPointSizeMax(float pointSizeMax) 697 { 698 point.pointSizeMax = pointSizeMax; 699 } 700 setPointScaleA(float pointScaleA)701 void VertexProcessor::setPointScaleA(float pointScaleA) 702 { 703 point.pointScaleA = pointScaleA; 704 } 705 setPointScaleB(float pointScaleB)706 void VertexProcessor::setPointScaleB(float pointScaleB) 707 { 708 point.pointScaleB = pointScaleB; 709 } 710 setPointScaleC(float pointScaleC)711 void VertexProcessor::setPointScaleC(float pointScaleC) 712 { 713 point.pointScaleC = pointScaleC; 714 } 715 setTransformFeedbackQueryEnabled(bool enable)716 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable) 717 { 718 context->transformFeedbackQueryEnabled = enable; 719 } 720 enableTransformFeedback(uint64_t enable)721 void VertexProcessor::enableTransformFeedback(uint64_t enable) 722 { 723 context->transformFeedbackEnabled = enable; 724 } 725 getModelTransform(int i)726 const Matrix &VertexProcessor::getModelTransform(int i) 727 { 728 updateTransform(); 729 return PBVM[i]; 730 } 731 getViewTransform()732 const Matrix &VertexProcessor::getViewTransform() 733 { 734 updateTransform(); 735 return PBV; 736 } 737 isFixedFunction()738 bool VertexProcessor::isFixedFunction() 739 { 740 return !context->vertexShader; 741 } 742 setTransform(const Matrix & M,int i)743 void VertexProcessor::setTransform(const Matrix &M, int i) 744 { 745 ff.transformT[i][0][0] = M[0][0]; 746 ff.transformT[i][0][1] = M[1][0]; 747 ff.transformT[i][0][2] = M[2][0]; 748 ff.transformT[i][0][3] = M[3][0]; 749 750 ff.transformT[i][1][0] = M[0][1]; 751 ff.transformT[i][1][1] = M[1][1]; 752 ff.transformT[i][1][2] = M[2][1]; 753 ff.transformT[i][1][3] = M[3][1]; 754 755 ff.transformT[i][2][0] = M[0][2]; 756 ff.transformT[i][2][1] = M[1][2]; 757 ff.transformT[i][2][2] = M[2][2]; 758 ff.transformT[i][2][3] = M[3][2]; 759 760 ff.transformT[i][3][0] = M[0][3]; 761 ff.transformT[i][3][1] = M[1][3]; 762 ff.transformT[i][3][2] = M[2][3]; 763 ff.transformT[i][3][3] = M[3][3]; 764 } 765 setCameraTransform(const Matrix & M,int i)766 void VertexProcessor::setCameraTransform(const Matrix &M, int i) 767 { 768 ff.cameraTransformT[i][0][0] = M[0][0]; 769 ff.cameraTransformT[i][0][1] = M[1][0]; 770 ff.cameraTransformT[i][0][2] = M[2][0]; 771 ff.cameraTransformT[i][0][3] = M[3][0]; 772 773 ff.cameraTransformT[i][1][0] = M[0][1]; 774 ff.cameraTransformT[i][1][1] = M[1][1]; 775 ff.cameraTransformT[i][1][2] = M[2][1]; 776 ff.cameraTransformT[i][1][3] = M[3][1]; 777 778 ff.cameraTransformT[i][2][0] = M[0][2]; 779 ff.cameraTransformT[i][2][1] = M[1][2]; 780 ff.cameraTransformT[i][2][2] = M[2][2]; 781 ff.cameraTransformT[i][2][3] = M[3][2]; 782 783 ff.cameraTransformT[i][3][0] = M[0][3]; 784 ff.cameraTransformT[i][3][1] = M[1][3]; 785 ff.cameraTransformT[i][3][2] = M[2][3]; 786 ff.cameraTransformT[i][3][3] = M[3][3]; 787 } 788 setNormalTransform(const Matrix & M,int i)789 void VertexProcessor::setNormalTransform(const Matrix &M, int i) 790 { 791 ff.normalTransformT[i][0][0] = M[0][0]; 792 ff.normalTransformT[i][0][1] = M[1][0]; 793 ff.normalTransformT[i][0][2] = M[2][0]; 794 ff.normalTransformT[i][0][3] = M[3][0]; 795 796 ff.normalTransformT[i][1][0] = M[0][1]; 797 ff.normalTransformT[i][1][1] = M[1][1]; 798 ff.normalTransformT[i][1][2] = M[2][1]; 799 ff.normalTransformT[i][1][3] = M[3][1]; 800 801 ff.normalTransformT[i][2][0] = M[0][2]; 802 ff.normalTransformT[i][2][1] = M[1][2]; 803 ff.normalTransformT[i][2][2] = M[2][2]; 804 ff.normalTransformT[i][2][3] = M[3][2]; 805 806 ff.normalTransformT[i][3][0] = M[0][3]; 807 ff.normalTransformT[i][3][1] = M[1][3]; 808 ff.normalTransformT[i][3][2] = M[2][3]; 809 ff.normalTransformT[i][3][3] = M[3][3]; 810 } 811 updateTransform()812 void VertexProcessor::updateTransform() 813 { 814 if(!updateMatrix) return; 815 816 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1); 817 818 if(updateProjectionMatrix) 819 { 820 PB = P * B; 821 PBV = PB * V; 822 823 for(int i = 0; i < activeMatrices; i++) 824 { 825 PBVM[i] = PBV * M[i]; 826 updateModelMatrix[i] = false; 827 } 828 829 updateProjectionMatrix = false; 830 updateBaseMatrix = false; 831 updateViewMatrix = false; 832 } 833 834 if(updateBaseMatrix) 835 { 836 PB = P * B; 837 PBV = PB * V; 838 839 for(int i = 0; i < activeMatrices; i++) 840 { 841 PBVM[i] = PBV * M[i]; 842 updateModelMatrix[i] = false; 843 } 844 845 updateBaseMatrix = false; 846 updateViewMatrix = false; 847 } 848 849 if(updateViewMatrix) 850 { 851 PBV = PB * V; 852 853 for(int i = 0; i < activeMatrices; i++) 854 { 855 PBVM[i] = PBV * M[i]; 856 updateModelMatrix[i] = false; 857 } 858 859 updateViewMatrix = false; 860 } 861 862 for(int i = 0; i < activeMatrices; i++) 863 { 864 if(updateModelMatrix[i]) 865 { 866 PBVM[i] = PBV * M[i]; 867 updateModelMatrix[i] = false; 868 } 869 } 870 871 for(int i = 0; i < activeMatrices; i++) 872 { 873 setTransform(PBVM[i], i); 874 setCameraTransform(B * V * M[i], i); 875 setNormalTransform(~!(B * V * M[i]), i); 876 } 877 878 updateMatrix = false; 879 } 880 setRoutineCacheSize(int cacheSize)881 void VertexProcessor::setRoutineCacheSize(int cacheSize) 882 { 883 delete routineCache; 884 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0); 885 } 886 update(DrawType drawType)887 const VertexProcessor::State VertexProcessor::update(DrawType drawType) 888 { 889 if(isFixedFunction()) 890 { 891 updateTransform(); 892 893 if(updateLighting) 894 { 895 for(int i = 0; i < 8; i++) 896 { 897 if(context->vertexLightActive(i)) 898 { 899 // Light position in camera coordinates 900 setLightViewPosition(i, B * V * context->getLightPosition(i)); 901 } 902 } 903 904 updateLighting = false; 905 } 906 } 907 908 State state; 909 910 if(context->vertexShader) 911 { 912 state.shaderID = context->vertexShader->getSerialID(); 913 } 914 else 915 { 916 state.shaderID = 0; 917 } 918 919 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300; 920 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false; 921 state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos; 922 state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts; 923 924 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive(); 925 state.indexedVertexBlendEnable = context->indexedVertexBlendActive(); 926 state.vertexNormalActive = context->vertexNormalActive(); 927 state.normalizeNormals = context->normalizeNormalsActive(); 928 state.vertexLightingActive = context->vertexLightingActive(); 929 state.diffuseActive = context->diffuseActive(); 930 state.specularActive = context->specularActive(); 931 state.vertexSpecularActive = context->vertexSpecularActive(); 932 933 state.vertexLightActive = context->vertexLightActive(0) << 0 | 934 context->vertexLightActive(1) << 1 | 935 context->vertexLightActive(2) << 2 | 936 context->vertexLightActive(3) << 3 | 937 context->vertexLightActive(4) << 4 | 938 context->vertexLightActive(5) << 5 | 939 context->vertexLightActive(6) << 6 | 940 context->vertexLightActive(7) << 7; 941 942 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive(); 943 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive(); 944 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive(); 945 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive(); 946 state.fogActive = context->fogActive(); 947 state.vertexFogMode = context->vertexFogModeActive(); 948 state.rangeFogActive = context->rangeFogActive(); 949 state.localViewerActive = context->localViewerActive(); 950 state.pointSizeActive = context->pointSizeActive(); 951 state.pointScaleActive = context->pointScaleActive(); 952 953 state.preTransformed = context->preTransformed; 954 state.superSampling = context->getSuperSampleCount() > 1; 955 state.multiSampling = context->getMultiSampleCount() > 1; 956 957 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled; 958 state.transformFeedbackEnabled = context->transformFeedbackEnabled; 959 960 // Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback, 961 // which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type. 962 DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF); 963 state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST); 964 965 for(int i = 0; i < MAX_VERTEX_INPUTS; i++) 966 { 967 state.input[i].type = context->input[i].type; 968 state.input[i].count = context->input[i].count; 969 state.input[i].normalized = context->input[i].normalized; 970 state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT; 971 } 972 973 if(!context->vertexShader) 974 { 975 for(int i = 0; i < 8; i++) 976 { 977 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0); 978 state.textureState[i].texGenActive = context->texGenActive(i); 979 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i); 980 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i); 981 } 982 } 983 else 984 { 985 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++) 986 { 987 if(context->vertexShader->usesSampler(i)) 988 { 989 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState(); 990 } 991 } 992 } 993 994 if(context->vertexShader) // FIXME: Also when pre-transformed? 995 { 996 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++) 997 { 998 state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active(); 999 state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active(); 1000 state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active(); 1001 state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active(); 1002 } 1003 } 1004 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300) 1005 { 1006 state.output[Pos].write = 0xF; 1007 1008 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0])) 1009 { 1010 state.output[C0].write = 0xF; 1011 } 1012 1013 if(context->specularActive()) 1014 { 1015 state.output[C1].write = 0xF; 1016 } 1017 1018 for(int stage = 0; stage < 8; stage++) 1019 { 1020 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01; 1021 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02; 1022 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04; 1023 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08; 1024 } 1025 1026 if(context->fogActive()) 1027 { 1028 state.output[Fog].xWrite = true; 1029 } 1030 1031 if(context->pointSizeActive()) 1032 { 1033 state.output[Pts].yWrite = true; 1034 } 1035 } 1036 else 1037 { 1038 state.output[Pos].write = 0xF; 1039 1040 for(int i = 0; i < 2; i++) 1041 { 1042 if(context->input[Color0 + i]) 1043 { 1044 state.output[C0 + i].write = 0xF; 1045 } 1046 } 1047 1048 for(int i = 0; i < 8; i++) 1049 { 1050 if(context->input[TexCoord0 + i]) 1051 { 1052 state.output[T0 + i].write = 0xF; 1053 } 1054 } 1055 1056 if(context->input[PointSize]) 1057 { 1058 state.output[Pts].yWrite = true; 1059 } 1060 } 1061 1062 if(context->vertexShaderVersion() < 0x0300) 1063 { 1064 state.output[C0].clamp = 0xF; 1065 state.output[C1].clamp = 0xF; 1066 state.output[Fog].xClamp = true; 1067 } 1068 1069 state.hash = state.computeHash(); 1070 1071 return state; 1072 } 1073 routine(const State & state)1074 Routine *VertexProcessor::routine(const State &state) 1075 { 1076 Routine *routine = routineCache->query(state); 1077 1078 if(!routine) // Create one 1079 { 1080 VertexRoutine *generator = nullptr; 1081 1082 if(state.fixedFunction) 1083 { 1084 generator = new VertexPipeline(state); 1085 } 1086 else 1087 { 1088 generator = new VertexProgram(state, context->vertexShader); 1089 } 1090 1091 generator->generate(); 1092 routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID); 1093 delete generator; 1094 1095 routineCache->add(state, routine); 1096 } 1097 1098 return routine; 1099 } 1100 } 1101