gfx/angle/src/libGLESv2/Shader.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 #include "precompiled.h"
michael@0 2 //
michael@0 3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
michael@0 4 // Use of this source code is governed by a BSD-style license that can be
michael@0 5 // found in the LICENSE file.
michael@0 6 //
michael@0 7
michael@0 8 // Shader.cpp: Implements the gl::Shader class and its derived classes
michael@0 9 // VertexShader and FragmentShader. Implements GL shader objects and related
michael@0 10 // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
michael@0 11
michael@0 12 #include "libGLESv2/Shader.h"
michael@0 13
michael@0 14 #include <algorithm>
michael@0 15
michael@0 16 #include "GLSLANG/ShaderLang.h"
michael@0 17 #include "libGLESv2/utilities.h"
michael@0 18 #include "libGLESv2/renderer/Renderer.h"
michael@0 19 #include "libGLESv2/Constants.h"
michael@0 20 #include "libGLESv2/ResourceManager.h"
michael@0 21
michael@0 22 namespace gl
michael@0 23 {
michael@0 24 void *Shader::mFragmentCompiler = NULL;
michael@0 25 void *Shader::mVertexCompiler = NULL;
michael@0 26
michael@0 27 Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
michael@0 28 : mHandle(handle), mRenderer(renderer), mResourceManager(manager)
michael@0 29 {
michael@0 30 mSource = NULL;
michael@0 31 mHlsl = NULL;
michael@0 32 mInfoLog = NULL;
michael@0 33
michael@0 34 uncompile();
michael@0 35 initializeCompiler();
michael@0 36
michael@0 37 mRefCount = 0;
michael@0 38 mDeleteStatus = false;
michael@0 39 }
michael@0 40
michael@0 41 Shader::~Shader()
michael@0 42 {
michael@0 43 delete[] mSource;
michael@0 44 delete[] mHlsl;
michael@0 45 delete[] mInfoLog;
michael@0 46 }
michael@0 47
michael@0 48 GLuint Shader::getHandle() const
michael@0 49 {
michael@0 50 return mHandle;
michael@0 51 }
michael@0 52
michael@0 53 void Shader::setSource(GLsizei count, const char **string, const GLint *length)
michael@0 54 {
michael@0 55 delete[] mSource;
michael@0 56 int totalLength = 0;
michael@0 57
michael@0 58 for (int i = 0; i < count; i++)
michael@0 59 {
michael@0 60 if (length && length[i] >= 0)
michael@0 61 {
michael@0 62 totalLength += length[i];
michael@0 63 }
michael@0 64 else
michael@0 65 {
michael@0 66 totalLength += (int)strlen(string[i]);
michael@0 67 }
michael@0 68 }
michael@0 69
michael@0 70 mSource = new char[totalLength + 1];
michael@0 71 char *code = mSource;
michael@0 72
michael@0 73 for (int i = 0; i < count; i++)
michael@0 74 {
michael@0 75 int stringLength;
michael@0 76
michael@0 77 if (length && length[i] >= 0)
michael@0 78 {
michael@0 79 stringLength = length[i];
michael@0 80 }
michael@0 81 else
michael@0 82 {
michael@0 83 stringLength = (int)strlen(string[i]);
michael@0 84 }
michael@0 85
michael@0 86 strncpy(code, string[i], stringLength);
michael@0 87 code += stringLength;
michael@0 88 }
michael@0 89
michael@0 90 mSource[totalLength] = '\0';
michael@0 91 }
michael@0 92
michael@0 93 int Shader::getInfoLogLength() const
michael@0 94 {
michael@0 95 if (!mInfoLog)
michael@0 96 {
michael@0 97 return 0;
michael@0 98 }
michael@0 99 else
michael@0 100 {
michael@0 101 return strlen(mInfoLog) + 1;
michael@0 102 }
michael@0 103 }
michael@0 104
michael@0 105 void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
michael@0 106 {
michael@0 107 int index = 0;
michael@0 108
michael@0 109 if (bufSize > 0)
michael@0 110 {
michael@0 111 if (mInfoLog)
michael@0 112 {
michael@0 113 index = std::min(bufSize - 1, (int)strlen(mInfoLog));
michael@0 114 memcpy(infoLog, mInfoLog, index);
michael@0 115 }
michael@0 116
michael@0 117 infoLog[index] = '\0';
michael@0 118 }
michael@0 119
michael@0 120 if (length)
michael@0 121 {
michael@0 122 *length = index;
michael@0 123 }
michael@0 124 }
michael@0 125
michael@0 126 int Shader::getSourceLength() const
michael@0 127 {
michael@0 128 if (!mSource)
michael@0 129 {
michael@0 130 return 0;
michael@0 131 }
michael@0 132 else
michael@0 133 {
michael@0 134 return strlen(mSource) + 1;
michael@0 135 }
michael@0 136 }
michael@0 137
michael@0 138 int Shader::getTranslatedSourceLength() const
michael@0 139 {
michael@0 140 if (!mHlsl)
michael@0 141 {
michael@0 142 return 0;
michael@0 143 }
michael@0 144 else
michael@0 145 {
michael@0 146 return strlen(mHlsl) + 1;
michael@0 147 }
michael@0 148 }
michael@0 149
michael@0 150 void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer)
michael@0 151 {
michael@0 152 int index = 0;
michael@0 153
michael@0 154 if (bufSize > 0)
michael@0 155 {
michael@0 156 if (source)
michael@0 157 {
michael@0 158 index = std::min(bufSize - 1, (int)strlen(source));
michael@0 159 memcpy(buffer, source, index);
michael@0 160 }
michael@0 161
michael@0 162 buffer[index] = '\0';
michael@0 163 }
michael@0 164
michael@0 165 if (length)
michael@0 166 {
michael@0 167 *length = index;
michael@0 168 }
michael@0 169 }
michael@0 170
michael@0 171 void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer)
michael@0 172 {
michael@0 173 getSourceImpl(mSource, bufSize, length, buffer);
michael@0 174 }
michael@0 175
michael@0 176 void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
michael@0 177 {
michael@0 178 getSourceImpl(mHlsl, bufSize, length, buffer);
michael@0 179 }
michael@0 180
michael@0 181 const sh::ActiveUniforms &Shader::getUniforms()
michael@0 182 {
michael@0 183 return mActiveUniforms;
michael@0 184 }
michael@0 185
michael@0 186 bool Shader::isCompiled()
michael@0 187 {
michael@0 188 return mHlsl != NULL;
michael@0 189 }
michael@0 190
michael@0 191 const char *Shader::getHLSL()
michael@0 192 {
michael@0 193 return mHlsl;
michael@0 194 }
michael@0 195
michael@0 196 void Shader::addRef()
michael@0 197 {
michael@0 198 mRefCount++;
michael@0 199 }
michael@0 200
michael@0 201 void Shader::release()
michael@0 202 {
michael@0 203 mRefCount--;
michael@0 204
michael@0 205 if (mRefCount == 0 && mDeleteStatus)
michael@0 206 {
michael@0 207 mResourceManager->deleteShader(mHandle);
michael@0 208 }
michael@0 209 }
michael@0 210
michael@0 211 unsigned int Shader::getRefCount() const
michael@0 212 {
michael@0 213 return mRefCount;
michael@0 214 }
michael@0 215
michael@0 216 bool Shader::isFlaggedForDeletion() const
michael@0 217 {
michael@0 218 return mDeleteStatus;
michael@0 219 }
michael@0 220
michael@0 221 void Shader::flagForDeletion()
michael@0 222 {
michael@0 223 mDeleteStatus = true;
michael@0 224 }
michael@0 225
michael@0 226 // Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
michael@0 227 void Shader::initializeCompiler()
michael@0 228 {
michael@0 229 if (!mFragmentCompiler)
michael@0 230 {
michael@0 231 int result = ShInitialize();
michael@0 232
michael@0 233 if (result)
michael@0 234 {
michael@0 235 ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
michael@0 236
michael@0 237 ShBuiltInResources resources;
michael@0 238 ShInitBuiltInResources(&resources);
michael@0 239
michael@0 240 resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
michael@0 241 resources.MaxVertexUniformVectors = mRenderer->getMaxVertexUniformVectors();
michael@0 242 resources.MaxVaryingVectors = mRenderer->getMaxVaryingVectors();
michael@0 243 resources.MaxVertexTextureImageUnits = mRenderer->getMaxVertexTextureImageUnits();
michael@0 244 resources.MaxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
michael@0 245 resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
michael@0 246 resources.MaxFragmentUniformVectors = mRenderer->getMaxFragmentUniformVectors();
michael@0 247 resources.MaxDrawBuffers = mRenderer->getMaxRenderTargets();
michael@0 248 resources.OES_standard_derivatives = mRenderer->getDerivativeInstructionSupport();
michael@0 249 resources.EXT_draw_buffers = mRenderer->getMaxRenderTargets() > 1;
michael@0 250 // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
michael@0 251 resources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
michael@0 252 resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
michael@0 253
michael@0 254 mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
michael@0 255 mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
michael@0 256 }
michael@0 257 }
michael@0 258 }
michael@0 259
michael@0 260 void Shader::releaseCompiler()
michael@0 261 {
michael@0 262 ShDestruct(mFragmentCompiler);
michael@0 263 ShDestruct(mVertexCompiler);
michael@0 264
michael@0 265 mFragmentCompiler = NULL;
michael@0 266 mVertexCompiler = NULL;
michael@0 267
michael@0 268 ShFinalize();
michael@0 269 }
michael@0 270
michael@0 271 void Shader::parseVaryings()
michael@0 272 {
michael@0 273 if (mHlsl)
michael@0 274 {
michael@0 275 const char *input = strstr(mHlsl, "// Varyings") + 12;
michael@0 276
michael@0 277 while(true)
michael@0 278 {
michael@0 279 char varyingType[256];
michael@0 280 char varyingName[256];
michael@0 281
michael@0 282 int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
michael@0 283
michael@0 284 if (matches != 2)
michael@0 285 {
michael@0 286 break;
michael@0 287 }
michael@0 288
michael@0 289 char *array = strstr(varyingName, "[");
michael@0 290 int size = 1;
michael@0 291
michael@0 292 if (array)
michael@0 293 {
michael@0 294 size = atoi(array + 1);
michael@0 295 *array = '\0';
michael@0 296 }
michael@0 297
michael@0 298 mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
michael@0 299
michael@0 300 input = strstr(input, ";") + 2;
michael@0 301 }
michael@0 302
michael@0 303 mUsesMultipleRenderTargets = strstr(mHlsl, "GL_USES_MRT") != NULL;
michael@0 304 mUsesFragColor = strstr(mHlsl, "GL_USES_FRAG_COLOR") != NULL;
michael@0 305 mUsesFragData = strstr(mHlsl, "GL_USES_FRAG_DATA") != NULL;
michael@0 306 mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
michael@0 307 mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
michael@0 308 mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
michael@0 309 mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
michael@0 310 mUsesDepthRange = strstr(mHlsl, "GL_USES_DEPTH_RANGE") != NULL;
michael@0 311 mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL;
michael@0 312 }
michael@0 313 }
michael@0 314
michael@0 315 void Shader::resetVaryingsRegisterAssignment()
michael@0 316 {
michael@0 317 for (VaryingList::iterator var = mVaryings.begin(); var != mVaryings.end(); var++)
michael@0 318 {
michael@0 319 var->reg = -1;
michael@0 320 var->col = -1;
michael@0 321 }
michael@0 322 }
michael@0 323
michael@0 324 // initialize/clean up previous state
michael@0 325 void Shader::uncompile()
michael@0 326 {
michael@0 327 // set by compileToHLSL
michael@0 328 delete[] mHlsl;
michael@0 329 mHlsl = NULL;
michael@0 330 delete[] mInfoLog;
michael@0 331 mInfoLog = NULL;
michael@0 332
michael@0 333 // set by parseVaryings
michael@0 334 mVaryings.clear();
michael@0 335
michael@0 336 mUsesMultipleRenderTargets = false;
michael@0 337 mUsesFragColor = false;
michael@0 338 mUsesFragData = false;
michael@0 339 mUsesFragCoord = false;
michael@0 340 mUsesFrontFacing = false;
michael@0 341 mUsesPointSize = false;
michael@0 342 mUsesPointCoord = false;
michael@0 343 mUsesDepthRange = false;
michael@0 344 mUsesFragDepth = false;
michael@0 345
michael@0 346 mActiveUniforms.clear();
michael@0 347 }
michael@0 348
michael@0 349 void Shader::compileToHLSL(void *compiler)
michael@0 350 {
michael@0 351 // ensure we don't pass a NULL source to the compiler
michael@0 352 const char *source = "\0";
michael@0 353 if (mSource)
michael@0 354 {
michael@0 355 source = mSource;
michael@0 356 }
michael@0 357
michael@0 358 // ensure the compiler is loaded
michael@0 359 initializeCompiler();
michael@0 360
michael@0 361 int compileOptions = SH_OBJECT_CODE;
michael@0 362 std::string sourcePath;
michael@0 363 if (perfActive())
michael@0 364 {
michael@0 365 sourcePath = getTempPath();
michael@0 366 writeFile(sourcePath.c_str(), source, strlen(source));
michael@0 367 compileOptions |= SH_LINE_DIRECTIVES;
michael@0 368 }
michael@0 369
michael@0 370 int result;
michael@0 371 if (sourcePath.empty())
michael@0 372 {
michael@0 373 result = ShCompile(compiler, &source, 1, compileOptions);
michael@0 374 }
michael@0 375 else
michael@0 376 {
michael@0 377 const char* sourceStrings[2] =
michael@0 378 {
michael@0 379 sourcePath.c_str(),
michael@0 380 source
michael@0 381 };
michael@0 382
michael@0 383 result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH);
michael@0 384 }
michael@0 385
michael@0 386 if (result)
michael@0 387 {
michael@0 388 size_t objCodeLen = 0;
michael@0 389 ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
michael@0 390 mHlsl = new char[objCodeLen];
michael@0 391 ShGetObjectCode(compiler, mHlsl);
michael@0 392
michael@0 393 void *activeUniforms;
michael@0 394 ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
michael@0 395 mActiveUniforms = *(sh::ActiveUniforms*)activeUniforms;
michael@0 396 }
michael@0 397 else
michael@0 398 {
michael@0 399 size_t infoLogLen = 0;
michael@0 400 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
michael@0 401 mInfoLog = new char[infoLogLen];
michael@0 402 ShGetInfoLog(compiler, mInfoLog);
michael@0 403
michael@0 404 TRACE("\n%s", mInfoLog);
michael@0 405 }
michael@0 406 }
michael@0 407
michael@0 408 GLenum Shader::parseType(const std::string &type)
michael@0 409 {
michael@0 410 if (type == "float")
michael@0 411 {
michael@0 412 return GL_FLOAT;
michael@0 413 }
michael@0 414 else if (type == "float2")
michael@0 415 {
michael@0 416 return GL_FLOAT_VEC2;
michael@0 417 }
michael@0 418 else if (type == "float3")
michael@0 419 {
michael@0 420 return GL_FLOAT_VEC3;
michael@0 421 }
michael@0 422 else if (type == "float4")
michael@0 423 {
michael@0 424 return GL_FLOAT_VEC4;
michael@0 425 }
michael@0 426 else if (type == "float2x2")
michael@0 427 {
michael@0 428 return GL_FLOAT_MAT2;
michael@0 429 }
michael@0 430 else if (type == "float3x3")
michael@0 431 {
michael@0 432 return GL_FLOAT_MAT3;
michael@0 433 }
michael@0 434 else if (type == "float4x4")
michael@0 435 {
michael@0 436 return GL_FLOAT_MAT4;
michael@0 437 }
michael@0 438 else UNREACHABLE();
michael@0 439
michael@0 440 return GL_NONE;
michael@0 441 }
michael@0 442
michael@0 443 // true if varying x has a higher priority in packing than y
michael@0 444 bool Shader::compareVarying(const Varying &x, const Varying &y)
michael@0 445 {
michael@0 446 if(x.type == y.type)
michael@0 447 {
michael@0 448 return x.size > y.size;
michael@0 449 }
michael@0 450
michael@0 451 switch (x.type)
michael@0 452 {
michael@0 453 case GL_FLOAT_MAT4: return true;
michael@0 454 case GL_FLOAT_MAT2:
michael@0 455 switch(y.type)
michael@0 456 {
michael@0 457 case GL_FLOAT_MAT4: return false;
michael@0 458 case GL_FLOAT_MAT2: return true;
michael@0 459 case GL_FLOAT_VEC4: return true;
michael@0 460 case GL_FLOAT_MAT3: return true;
michael@0 461 case GL_FLOAT_VEC3: return true;
michael@0 462 case GL_FLOAT_VEC2: return true;
michael@0 463 case GL_FLOAT: return true;
michael@0 464 default: UNREACHABLE();
michael@0 465 }
michael@0 466 break;
michael@0 467 case GL_FLOAT_VEC4:
michael@0 468 switch(y.type)
michael@0 469 {
michael@0 470 case GL_FLOAT_MAT4: return false;
michael@0 471 case GL_FLOAT_MAT2: return false;
michael@0 472 case GL_FLOAT_VEC4: return true;
michael@0 473 case GL_FLOAT_MAT3: return true;
michael@0 474 case GL_FLOAT_VEC3: return true;
michael@0 475 case GL_FLOAT_VEC2: return true;
michael@0 476 case GL_FLOAT: return true;
michael@0 477 default: UNREACHABLE();
michael@0 478 }
michael@0 479 break;
michael@0 480 case GL_FLOAT_MAT3:
michael@0 481 switch(y.type)
michael@0 482 {
michael@0 483 case GL_FLOAT_MAT4: return false;
michael@0 484 case GL_FLOAT_MAT2: return false;
michael@0 485 case GL_FLOAT_VEC4: return false;
michael@0 486 case GL_FLOAT_MAT3: return true;
michael@0 487 case GL_FLOAT_VEC3: return true;
michael@0 488 case GL_FLOAT_VEC2: return true;
michael@0 489 case GL_FLOAT: return true;
michael@0 490 default: UNREACHABLE();
michael@0 491 }
michael@0 492 break;
michael@0 493 case GL_FLOAT_VEC3:
michael@0 494 switch(y.type)
michael@0 495 {
michael@0 496 case GL_FLOAT_MAT4: return false;
michael@0 497 case GL_FLOAT_MAT2: return false;
michael@0 498 case GL_FLOAT_VEC4: return false;
michael@0 499 case GL_FLOAT_MAT3: return false;
michael@0 500 case GL_FLOAT_VEC3: return true;
michael@0 501 case GL_FLOAT_VEC2: return true;
michael@0 502 case GL_FLOAT: return true;
michael@0 503 default: UNREACHABLE();
michael@0 504 }
michael@0 505 break;
michael@0 506 case GL_FLOAT_VEC2:
michael@0 507 switch(y.type)
michael@0 508 {
michael@0 509 case GL_FLOAT_MAT4: return false;
michael@0 510 case GL_FLOAT_MAT2: return false;
michael@0 511 case GL_FLOAT_VEC4: return false;
michael@0 512 case GL_FLOAT_MAT3: return false;
michael@0 513 case GL_FLOAT_VEC3: return false;
michael@0 514 case GL_FLOAT_VEC2: return true;
michael@0 515 case GL_FLOAT: return true;
michael@0 516 default: UNREACHABLE();
michael@0 517 }
michael@0 518 break;
michael@0 519 case GL_FLOAT: return false;
michael@0 520 default: UNREACHABLE();
michael@0 521 }
michael@0 522
michael@0 523 return false;
michael@0 524 }
michael@0 525
michael@0 526 VertexShader::VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
michael@0 527 : Shader(manager, renderer, handle)
michael@0 528 {
michael@0 529 }
michael@0 530
michael@0 531 VertexShader::~VertexShader()
michael@0 532 {
michael@0 533 }
michael@0 534
michael@0 535 GLenum VertexShader::getType()
michael@0 536 {
michael@0 537 return GL_VERTEX_SHADER;
michael@0 538 }
michael@0 539
michael@0 540 void VertexShader::uncompile()
michael@0 541 {
michael@0 542 Shader::uncompile();
michael@0 543
michael@0 544 // set by ParseAttributes
michael@0 545 mAttributes.clear();
michael@0 546 }
michael@0 547
michael@0 548 void VertexShader::compile()
michael@0 549 {
michael@0 550 uncompile();
michael@0 551
michael@0 552 compileToHLSL(mVertexCompiler);
michael@0 553 parseAttributes();
michael@0 554 parseVaryings();
michael@0 555 }
michael@0 556
michael@0 557 int VertexShader::getSemanticIndex(const std::string &attributeName)
michael@0 558 {
michael@0 559 if (!attributeName.empty())
michael@0 560 {
michael@0 561 int semanticIndex = 0;
michael@0 562 for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++)
michael@0 563 {
michael@0 564 if (attribute->name == attributeName)
michael@0 565 {
michael@0 566 return semanticIndex;
michael@0 567 }
michael@0 568
michael@0 569 semanticIndex += VariableRowCount(attribute->type);
michael@0 570 }
michael@0 571 }
michael@0 572
michael@0 573 return -1;
michael@0 574 }
michael@0 575
michael@0 576 void VertexShader::parseAttributes()
michael@0 577 {
michael@0 578 const char *hlsl = getHLSL();
michael@0 579 if (hlsl)
michael@0 580 {
michael@0 581 const char *input = strstr(hlsl, "// Attributes") + 14;
michael@0 582
michael@0 583 while(true)
michael@0 584 {
michael@0 585 char attributeType[256];
michael@0 586 char attributeName[256];
michael@0 587
michael@0 588 int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
michael@0 589
michael@0 590 if (matches != 2)
michael@0 591 {
michael@0 592 break;
michael@0 593 }
michael@0 594
michael@0 595 mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
michael@0 596
michael@0 597 input = strstr(input, ";") + 2;
michael@0 598 }
michael@0 599 }
michael@0 600 }
michael@0 601
michael@0 602 FragmentShader::FragmentShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
michael@0 603 : Shader(manager, renderer, handle)
michael@0 604 {
michael@0 605 }
michael@0 606
michael@0 607 FragmentShader::~FragmentShader()
michael@0 608 {
michael@0 609 }
michael@0 610
michael@0 611 GLenum FragmentShader::getType()
michael@0 612 {
michael@0 613 return GL_FRAGMENT_SHADER;
michael@0 614 }
michael@0 615
michael@0 616 void FragmentShader::compile()
michael@0 617 {
michael@0 618 uncompile();
michael@0 619
michael@0 620 compileToHLSL(mFragmentCompiler);
michael@0 621 parseVaryings();
michael@0 622 mVaryings.sort(compareVarying);
michael@0 623 }
michael@0 624 }

mercurial