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