blob: d3ff6e17ab16fb780b577a2d67585128b4da5f95 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +00002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Shader.cpp: Implements the gl::Shader class and its derived classes
8// VertexShader and FragmentShader. Implements GL shader objects and related
9// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
10
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000011#include "libGLESv2/Shader.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000012
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000013#include "GLSLANG/ShaderLang.h"
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +000014#include "libGLESv2/utilities.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000015#include "libGLESv2/renderer/Renderer.h"
16#include "libGLESv2/Constants.h"
17#include "libGLESv2/ResourceManager.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000018
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000019namespace gl
20{
21void *Shader::mFragmentCompiler = NULL;
22void *Shader::mVertexCompiler = NULL;
23
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +000024Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
25 : mHandle(handle), mRenderer(renderer), mResourceManager(manager)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000026{
27 mSource = NULL;
28 mHlsl = NULL;
daniel@transgaming.comcba50572010-03-28 19:36:09 +000029 mInfoLog = NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030
daniel@transgaming.com938009c2012-02-17 18:02:15 +000031 uncompile();
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +000032 initializeCompiler();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000033
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000034 mRefCount = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035 mDeleteStatus = false;
36}
37
38Shader::~Shader()
39{
40 delete[] mSource;
41 delete[] mHlsl;
daniel@transgaming.comcba50572010-03-28 19:36:09 +000042 delete[] mInfoLog;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000043}
44
daniel@transgaming.com6c785212010-03-30 03:36:17 +000045GLuint Shader::getHandle() const
46{
47 return mHandle;
48}
49
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000050void Shader::setSource(GLsizei count, const char **string, const GLint *length)
51{
52 delete[] mSource;
53 int totalLength = 0;
54
55 for (int i = 0; i < count; i++)
56 {
57 if (length && length[i] >= 0)
58 {
59 totalLength += length[i];
60 }
61 else
62 {
63 totalLength += (int)strlen(string[i]);
64 }
65 }
66
67 mSource = new char[totalLength + 1];
68 char *code = mSource;
69
70 for (int i = 0; i < count; i++)
71 {
72 int stringLength;
73
74 if (length && length[i] >= 0)
75 {
76 stringLength = length[i];
77 }
78 else
79 {
80 stringLength = (int)strlen(string[i]);
81 }
82
83 strncpy(code, string[i], stringLength);
84 code += stringLength;
85 }
86
87 mSource[totalLength] = '\0';
88}
89
daniel@transgaming.comcba50572010-03-28 19:36:09 +000090int Shader::getInfoLogLength() const
91{
92 if (!mInfoLog)
93 {
94 return 0;
95 }
96 else
97 {
98 return strlen(mInfoLog) + 1;
99 }
100}
101
102void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
103{
104 int index = 0;
105
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000106 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000107 {
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000108 if (mInfoLog)
109 {
110 index = std::min(bufSize - 1, (int)strlen(mInfoLog));
111 memcpy(infoLog, mInfoLog, index);
112 }
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000113
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000114 infoLog[index] = '\0';
115 }
116
117 if (length)
118 {
119 *length = index;
120 }
121}
122
123int Shader::getSourceLength() const
124{
125 if (!mSource)
126 {
127 return 0;
128 }
129 else
130 {
131 return strlen(mSource) + 1;
132 }
133}
134
zmo@google.coma574f782011-10-03 21:45:23 +0000135int Shader::getTranslatedSourceLength() const
136{
137 if (!mHlsl)
138 {
139 return 0;
140 }
141 else
142 {
143 return strlen(mHlsl) + 1;
144 }
145}
146
147void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000148{
149 int index = 0;
150
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000151 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000152 {
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000153 if (source)
154 {
155 index = std::min(bufSize - 1, (int)strlen(source));
156 memcpy(buffer, source, index);
157 }
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000158
zmo@google.coma574f782011-10-03 21:45:23 +0000159 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000160 }
161
162 if (length)
163 {
164 *length = index;
165 }
166}
167
zmo@google.coma574f782011-10-03 21:45:23 +0000168void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer)
169{
170 getSourceImpl(mSource, bufSize, length, buffer);
171}
172
173void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
174{
175 getSourceImpl(mHlsl, bufSize, length, buffer);
176}
177
daniel@transgaming.comc5c9e3c2012-12-20 21:12:32 +0000178const sh::ActiveUniforms &Shader::getUniforms()
179{
180 return mActiveUniforms;
181}
182
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000183bool Shader::isCompiled()
184{
185 return mHlsl != NULL;
186}
187
daniel@transgaming.com0e3358a2010-04-05 20:32:42 +0000188const char *Shader::getHLSL()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000189{
190 return mHlsl;
191}
192
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000193void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000194{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000195 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000196}
197
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000198void Shader::release()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000199{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000200 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000201
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000202 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000203 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000204 mResourceManager->deleteShader(mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000205 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000206}
207
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000208unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000210 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211}
212
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000213bool Shader::isFlaggedForDeletion() const
214{
215 return mDeleteStatus;
216}
217
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000218void Shader::flagForDeletion()
219{
220 mDeleteStatus = true;
221}
222
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000223// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
224void Shader::initializeCompiler()
225{
226 if (!mFragmentCompiler)
227 {
228 int result = ShInitialize();
229
230 if (result)
231 {
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +0000232 ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
233
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000234 ShBuiltInResources resources;
235 ShInitBuiltInResources(&resources);
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000236
237 resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
shannon.woods@transgaming.com4e482042013-01-25 21:54:18 +0000238 resources.MaxVertexUniformVectors = mRenderer->getMaxVertexUniformVectors();
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +0000239 resources.MaxVaryingVectors = mRenderer->getMaxVaryingVectors();
shannon.woods@transgaming.com233fe952013-01-25 21:51:57 +0000240 resources.MaxVertexTextureImageUnits = mRenderer->getMaxVertexTextureImageUnits();
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +0000241 resources.MaxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000242 resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
shannon.woods@transgaming.com254317d2013-01-25 21:54:09 +0000243 resources.MaxFragmentUniformVectors = mRenderer->getMaxFragmentUniformVectors();
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000244 resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +0000245 resources.OES_standard_derivatives = mRenderer->getDerivativeInstructionSupport();
246 // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000247
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +0000248 mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
249 mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000250 }
251 }
252}
253
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000254void Shader::releaseCompiler()
255{
256 ShDestruct(mFragmentCompiler);
257 ShDestruct(mVertexCompiler);
258
259 mFragmentCompiler = NULL;
260 mVertexCompiler = NULL;
alokp@chromium.org90033b92010-05-24 15:02:43 +0000261
262 ShFinalize();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000263}
264
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000265void Shader::parseVaryings()
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000266{
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000267 if (mHlsl)
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000268 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000269 const char *input = strstr(mHlsl, "// Varyings") + 12;
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000270
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000271 while(true)
272 {
273 char varyingType[256];
274 char varyingName[256];
275
daniel@transgaming.com7ea933f2010-12-12 08:52:42 +0000276 int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000277
278 if (matches != 2)
279 {
280 break;
281 }
282
283 char *array = strstr(varyingName, "[");
284 int size = 1;
285
286 if (array)
287 {
288 size = atoi(array + 1);
289 *array = '\0';
290 }
291
daniel@transgaming.comcde6a612012-02-17 18:01:10 +0000292 mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000293
294 input = strstr(input, ";") + 2;
295 }
296
297 mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
298 mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
daniel@transgaming.combe5a0862010-07-28 19:20:37 +0000299 mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
300 mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000301 }
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000302}
303
shannon.woods@transgaming.com5bcf7df2013-01-25 21:55:33 +0000304void Shader::resetVaryingsRegisterAssignment()
305{
306 for (VaryingList::iterator var = mVaryings.begin(); var != mVaryings.end(); var++)
307 {
308 var->reg = -1;
309 var->col = -1;
310 }
311}
312
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000313// initialize/clean up previous state
314void Shader::uncompile()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000315{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000316 // set by compileToHLSL
317 delete[] mHlsl;
318 mHlsl = NULL;
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000319 delete[] mInfoLog;
320 mInfoLog = NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000321
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000322 // set by parseVaryings
323 mVaryings.clear();
324
325 mUsesFragCoord = false;
326 mUsesFrontFacing = false;
327 mUsesPointSize = false;
328 mUsesPointCoord = false;
daniel@transgaming.comc5c9e3c2012-12-20 21:12:32 +0000329
330 mActiveUniforms.clear();
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000331}
332
333void Shader::compileToHLSL(void *compiler)
334{
335 // ensure we don't pass a NULL source to the compiler
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000336 const char *source = "\0";
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000337 if (mSource)
338 {
339 source = mSource;
340 }
341
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000342 // ensure the compiler is loaded
343 initializeCompiler();
344
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000345 int compileOptions = SH_OBJECT_CODE;
346 std::string sourcePath;
347 if (perfActive())
348 {
349 sourcePath = getTempPath();
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000350 writeFile(sourcePath.c_str(), source, strlen(source));
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000351 compileOptions |= SH_LINE_DIRECTIVES;
352 }
353
354 int result;
355 if (sourcePath.empty())
356 {
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000357 result = ShCompile(compiler, &source, 1, compileOptions);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000358 }
359 else
360 {
361 const char* sourceStrings[2] =
362 {
363 sourcePath.c_str(),
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000364 source
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000365 };
366
367 result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH);
368 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000369
370 if (result)
371 {
alokp@chromium.org7beea402010-09-15 21:18:34 +0000372 int objCodeLen = 0;
373 ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
374 mHlsl = new char[objCodeLen];
375 ShGetObjectCode(compiler, mHlsl);
daniel@transgaming.comc5c9e3c2012-12-20 21:12:32 +0000376
377 void *activeUniforms;
378 ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
379 mActiveUniforms = *(sh::ActiveUniforms*)activeUniforms;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000380 }
381 else
382 {
alokp@chromium.org7beea402010-09-15 21:18:34 +0000383 int infoLogLen = 0;
384 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
385 mInfoLog = new char[infoLogLen];
386 ShGetInfoLog(compiler, mInfoLog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000387
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000388 TRACE("\n%s", mInfoLog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000389 }
390}
391
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000392GLenum Shader::parseType(const std::string &type)
393{
394 if (type == "float")
395 {
396 return GL_FLOAT;
397 }
398 else if (type == "float2")
399 {
400 return GL_FLOAT_VEC2;
401 }
402 else if (type == "float3")
403 {
404 return GL_FLOAT_VEC3;
405 }
406 else if (type == "float4")
407 {
408 return GL_FLOAT_VEC4;
409 }
410 else if (type == "float2x2")
411 {
412 return GL_FLOAT_MAT2;
413 }
414 else if (type == "float3x3")
415 {
416 return GL_FLOAT_MAT3;
417 }
418 else if (type == "float4x4")
419 {
420 return GL_FLOAT_MAT4;
421 }
422 else UNREACHABLE();
423
424 return GL_NONE;
425}
426
427// true if varying x has a higher priority in packing than y
428bool Shader::compareVarying(const Varying &x, const Varying &y)
429{
430 if(x.type == y.type)
431 {
432 return x.size > y.size;
433 }
434
435 switch (x.type)
436 {
437 case GL_FLOAT_MAT4: return true;
438 case GL_FLOAT_MAT2:
439 switch(y.type)
440 {
441 case GL_FLOAT_MAT4: return false;
442 case GL_FLOAT_MAT2: return true;
443 case GL_FLOAT_VEC4: return true;
444 case GL_FLOAT_MAT3: return true;
445 case GL_FLOAT_VEC3: return true;
446 case GL_FLOAT_VEC2: return true;
447 case GL_FLOAT: return true;
448 default: UNREACHABLE();
449 }
450 break;
451 case GL_FLOAT_VEC4:
452 switch(y.type)
453 {
454 case GL_FLOAT_MAT4: return false;
455 case GL_FLOAT_MAT2: return false;
456 case GL_FLOAT_VEC4: return true;
457 case GL_FLOAT_MAT3: return true;
458 case GL_FLOAT_VEC3: return true;
459 case GL_FLOAT_VEC2: return true;
460 case GL_FLOAT: return true;
461 default: UNREACHABLE();
462 }
463 break;
464 case GL_FLOAT_MAT3:
465 switch(y.type)
466 {
467 case GL_FLOAT_MAT4: return false;
468 case GL_FLOAT_MAT2: return false;
469 case GL_FLOAT_VEC4: return false;
470 case GL_FLOAT_MAT3: return true;
471 case GL_FLOAT_VEC3: return true;
472 case GL_FLOAT_VEC2: return true;
473 case GL_FLOAT: return true;
474 default: UNREACHABLE();
475 }
476 break;
477 case GL_FLOAT_VEC3:
478 switch(y.type)
479 {
480 case GL_FLOAT_MAT4: return false;
481 case GL_FLOAT_MAT2: return false;
482 case GL_FLOAT_VEC4: return false;
483 case GL_FLOAT_MAT3: return false;
484 case GL_FLOAT_VEC3: return true;
485 case GL_FLOAT_VEC2: return true;
486 case GL_FLOAT: return true;
487 default: UNREACHABLE();
488 }
489 break;
490 case GL_FLOAT_VEC2:
491 switch(y.type)
492 {
493 case GL_FLOAT_MAT4: return false;
494 case GL_FLOAT_MAT2: return false;
495 case GL_FLOAT_VEC4: return false;
496 case GL_FLOAT_MAT3: return false;
497 case GL_FLOAT_VEC3: return false;
498 case GL_FLOAT_VEC2: return true;
499 case GL_FLOAT: return true;
500 default: UNREACHABLE();
501 }
502 break;
503 case GL_FLOAT: return false;
504 default: UNREACHABLE();
505 }
506
507 return false;
508}
509
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +0000510VertexShader::VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
511 : Shader(manager, renderer, handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512{
513}
514
515VertexShader::~VertexShader()
516{
517}
518
519GLenum VertexShader::getType()
520{
521 return GL_VERTEX_SHADER;
522}
523
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000524void VertexShader::uncompile()
525{
526 Shader::uncompile();
527
528 // set by ParseAttributes
529 mAttributes.clear();
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000530}
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000531
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000532void VertexShader::compile()
533{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000534 uncompile();
535
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000536 compileToHLSL(mVertexCompiler);
537 parseAttributes();
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000538 parseVaryings();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000539}
540
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000541int VertexShader::getSemanticIndex(const std::string &attributeName)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000542{
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000543 if (!attributeName.empty())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000544 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000545 int semanticIndex = 0;
546 for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000547 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000548 if (attribute->name == attributeName)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000549 {
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000550 return semanticIndex;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000551 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000552
553 semanticIndex += VariableRowCount(attribute->type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000554 }
555 }
556
557 return -1;
558}
559
560void VertexShader::parseAttributes()
561{
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +0000562 const char *hlsl = getHLSL();
563 if (hlsl)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000564 {
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +0000565 const char *input = strstr(hlsl, "// Attributes") + 14;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000566
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000567 while(true)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000568 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000569 char attributeType[256];
570 char attributeName[256];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000571
daniel@transgaming.com7ea933f2010-12-12 08:52:42 +0000572 int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000573
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000574 if (matches != 2)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000575 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000576 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000577 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000578
579 mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
580
581 input = strstr(input, ";") + 2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000582 }
583 }
584}
585
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +0000586FragmentShader::FragmentShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
587 : Shader(manager, renderer, handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000588{
589}
590
591FragmentShader::~FragmentShader()
592{
593}
594
595GLenum FragmentShader::getType()
596{
597 return GL_FRAGMENT_SHADER;
598}
599
600void FragmentShader::compile()
601{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000602 uncompile();
603
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000604 compileToHLSL(mFragmentCompiler);
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000605 parseVaryings();
daniel@transgaming.comcde6a612012-02-17 18:01:10 +0000606 mVaryings.sort(compareVarying);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000607}
608}