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