blob: 9f8dacbe03953ac8a1bcde4db980ca8bb9be0775 [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002//
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +00003// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// Shader.cpp: Implements the gl::Shader class and its derived classes
9// VertexShader and FragmentShader. Implements GL shader objects and related
10// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
11
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000012#include "libGLESv2/Shader.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000013
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000014#include "GLSLANG/ShaderLang.h"
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +000015#include "libGLESv2/utilities.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000016#include "libGLESv2/renderer/Renderer.h"
17#include "libGLESv2/Constants.h"
18#include "libGLESv2/ResourceManager.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000019
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000020namespace gl
21{
22void *Shader::mFragmentCompiler = NULL;
23void *Shader::mVertexCompiler = NULL;
24
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +000025Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
26 : mHandle(handle), mRenderer(renderer), mResourceManager(manager)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027{
28 mSource = NULL;
29 mHlsl = NULL;
daniel@transgaming.comcba50572010-03-28 19:36:09 +000030 mInfoLog = NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000031
daniel@transgaming.com938009c2012-02-17 18:02:15 +000032 uncompile();
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +000033 initializeCompiler();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000035 mRefCount = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000036 mDeleteStatus = false;
37}
38
39Shader::~Shader()
40{
41 delete[] mSource;
42 delete[] mHlsl;
daniel@transgaming.comcba50572010-03-28 19:36:09 +000043 delete[] mInfoLog;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000044}
45
daniel@transgaming.com6c785212010-03-30 03:36:17 +000046GLuint Shader::getHandle() const
47{
48 return mHandle;
49}
50
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000051void Shader::setSource(GLsizei count, const char **string, const GLint *length)
52{
53 delete[] mSource;
54 int totalLength = 0;
55
56 for (int i = 0; i < count; i++)
57 {
58 if (length && length[i] >= 0)
59 {
60 totalLength += length[i];
61 }
62 else
63 {
64 totalLength += (int)strlen(string[i]);
65 }
66 }
67
68 mSource = new char[totalLength + 1];
69 char *code = mSource;
70
71 for (int i = 0; i < count; i++)
72 {
73 int stringLength;
74
75 if (length && length[i] >= 0)
76 {
77 stringLength = length[i];
78 }
79 else
80 {
81 stringLength = (int)strlen(string[i]);
82 }
83
84 strncpy(code, string[i], stringLength);
85 code += stringLength;
86 }
87
88 mSource[totalLength] = '\0';
89}
90
daniel@transgaming.comcba50572010-03-28 19:36:09 +000091int Shader::getInfoLogLength() const
92{
93 if (!mInfoLog)
94 {
95 return 0;
96 }
97 else
98 {
99 return strlen(mInfoLog) + 1;
100 }
101}
102
103void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
104{
105 int index = 0;
106
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000107 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000108 {
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000109 if (mInfoLog)
110 {
111 index = std::min(bufSize - 1, (int)strlen(mInfoLog));
112 memcpy(infoLog, mInfoLog, index);
113 }
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000114
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000115 infoLog[index] = '\0';
116 }
117
118 if (length)
119 {
120 *length = index;
121 }
122}
123
124int Shader::getSourceLength() const
125{
126 if (!mSource)
127 {
128 return 0;
129 }
130 else
131 {
132 return strlen(mSource) + 1;
133 }
134}
135
zmo@google.coma574f782011-10-03 21:45:23 +0000136int Shader::getTranslatedSourceLength() const
137{
138 if (!mHlsl)
139 {
140 return 0;
141 }
142 else
143 {
144 return strlen(mHlsl) + 1;
145 }
146}
147
148void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000149{
150 int index = 0;
151
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000152 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000153 {
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000154 if (source)
155 {
156 index = std::min(bufSize - 1, (int)strlen(source));
157 memcpy(buffer, source, index);
158 }
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000159
zmo@google.coma574f782011-10-03 21:45:23 +0000160 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000161 }
162
163 if (length)
164 {
165 *length = index;
166 }
167}
168
zmo@google.coma574f782011-10-03 21:45:23 +0000169void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer)
170{
171 getSourceImpl(mSource, bufSize, length, buffer);
172}
173
174void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
175{
176 getSourceImpl(mHlsl, bufSize, length, buffer);
177}
178
daniel@transgaming.comc5c9e3c2012-12-20 21:12:32 +0000179const sh::ActiveUniforms &Shader::getUniforms()
180{
181 return mActiveUniforms;
182}
183
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000184bool Shader::isCompiled()
185{
186 return mHlsl != NULL;
187}
188
daniel@transgaming.com0e3358a2010-04-05 20:32:42 +0000189const char *Shader::getHLSL()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000190{
191 return mHlsl;
192}
193
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000194void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000195{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000196 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000197}
198
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000199void Shader::release()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000200{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000201 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000202
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000203 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000204 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000205 mResourceManager->deleteShader(mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000206 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000207}
208
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000209unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000210{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000211 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000212}
213
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000214bool Shader::isFlaggedForDeletion() const
215{
216 return mDeleteStatus;
217}
218
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000219void Shader::flagForDeletion()
220{
221 mDeleteStatus = true;
222}
223
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000224// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
225void Shader::initializeCompiler()
226{
227 if (!mFragmentCompiler)
228 {
229 int result = ShInitialize();
230
231 if (result)
232 {
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +0000233 ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
234
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000235 ShBuiltInResources resources;
236 ShInitBuiltInResources(&resources);
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000237
238 resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
shannon.woods@transgaming.com4e482042013-01-25 21:54:18 +0000239 resources.MaxVertexUniformVectors = mRenderer->getMaxVertexUniformVectors();
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +0000240 resources.MaxVaryingVectors = mRenderer->getMaxVaryingVectors();
shannon.woods@transgaming.com233fe952013-01-25 21:51:57 +0000241 resources.MaxVertexTextureImageUnits = mRenderer->getMaxVertexTextureImageUnits();
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +0000242 resources.MaxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000243 resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
shannon.woods@transgaming.com254317d2013-01-25 21:54:09 +0000244 resources.MaxFragmentUniformVectors = mRenderer->getMaxFragmentUniformVectors();
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000245 resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +0000246 resources.OES_standard_derivatives = mRenderer->getDerivativeInstructionSupport();
247 // 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 +0000248
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +0000249 mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
250 mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000251 }
252 }
253}
254
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000255void Shader::releaseCompiler()
256{
257 ShDestruct(mFragmentCompiler);
258 ShDestruct(mVertexCompiler);
259
260 mFragmentCompiler = NULL;
261 mVertexCompiler = NULL;
alokp@chromium.org90033b92010-05-24 15:02:43 +0000262
263 ShFinalize();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264}
265
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000266void Shader::parseVaryings()
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000267{
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000268 if (mHlsl)
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000269 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000270 const char *input = strstr(mHlsl, "// Varyings") + 12;
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000271
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000272 while(true)
273 {
274 char varyingType[256];
275 char varyingName[256];
276
daniel@transgaming.com7ea933f2010-12-12 08:52:42 +0000277 int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000278
279 if (matches != 2)
280 {
281 break;
282 }
283
284 char *array = strstr(varyingName, "[");
285 int size = 1;
286
287 if (array)
288 {
289 size = atoi(array + 1);
290 *array = '\0';
291 }
292
daniel@transgaming.comcde6a612012-02-17 18:01:10 +0000293 mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000294
295 input = strstr(input, ";") + 2;
296 }
297
298 mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
299 mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
daniel@transgaming.combe5a0862010-07-28 19:20:37 +0000300 mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
301 mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000302 }
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000303}
304
shannon.woods@transgaming.com5bcf7df2013-01-25 21:55:33 +0000305void Shader::resetVaryingsRegisterAssignment()
306{
307 for (VaryingList::iterator var = mVaryings.begin(); var != mVaryings.end(); var++)
308 {
309 var->reg = -1;
310 var->col = -1;
311 }
312}
313
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000314// initialize/clean up previous state
315void Shader::uncompile()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000316{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000317 // set by compileToHLSL
318 delete[] mHlsl;
319 mHlsl = NULL;
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000320 delete[] mInfoLog;
321 mInfoLog = NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000322
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000323 // set by parseVaryings
324 mVaryings.clear();
325
326 mUsesFragCoord = false;
327 mUsesFrontFacing = false;
328 mUsesPointSize = false;
329 mUsesPointCoord = false;
daniel@transgaming.comc5c9e3c2012-12-20 21:12:32 +0000330
331 mActiveUniforms.clear();
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000332}
333
334void Shader::compileToHLSL(void *compiler)
335{
336 // ensure we don't pass a NULL source to the compiler
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000337 const char *source = "\0";
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000338 if (mSource)
339 {
340 source = mSource;
341 }
342
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000343 // ensure the compiler is loaded
344 initializeCompiler();
345
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000346 int compileOptions = SH_OBJECT_CODE;
347 std::string sourcePath;
348 if (perfActive())
349 {
350 sourcePath = getTempPath();
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000351 writeFile(sourcePath.c_str(), source, strlen(source));
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000352 compileOptions |= SH_LINE_DIRECTIVES;
353 }
354
355 int result;
356 if (sourcePath.empty())
357 {
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000358 result = ShCompile(compiler, &source, 1, compileOptions);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000359 }
360 else
361 {
362 const char* sourceStrings[2] =
363 {
364 sourcePath.c_str(),
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000365 source
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000366 };
367
368 result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH);
369 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000370
371 if (result)
372 {
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000373 size_t objCodeLen = 0;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000374 ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
375 mHlsl = new char[objCodeLen];
376 ShGetObjectCode(compiler, mHlsl);
daniel@transgaming.comc5c9e3c2012-12-20 21:12:32 +0000377
378 void *activeUniforms;
379 ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
380 mActiveUniforms = *(sh::ActiveUniforms*)activeUniforms;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000381 }
382 else
383 {
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000384 size_t infoLogLen = 0;
alokp@chromium.org7beea402010-09-15 21:18:34 +0000385 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
386 mInfoLog = new char[infoLogLen];
387 ShGetInfoLog(compiler, mInfoLog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000388
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000389 TRACE("\n%s", mInfoLog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000390 }
391}
392
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000393GLenum Shader::parseType(const std::string &type)
394{
395 if (type == "float")
396 {
397 return GL_FLOAT;
398 }
399 else if (type == "float2")
400 {
401 return GL_FLOAT_VEC2;
402 }
403 else if (type == "float3")
404 {
405 return GL_FLOAT_VEC3;
406 }
407 else if (type == "float4")
408 {
409 return GL_FLOAT_VEC4;
410 }
411 else if (type == "float2x2")
412 {
413 return GL_FLOAT_MAT2;
414 }
415 else if (type == "float3x3")
416 {
417 return GL_FLOAT_MAT3;
418 }
419 else if (type == "float4x4")
420 {
421 return GL_FLOAT_MAT4;
422 }
423 else UNREACHABLE();
424
425 return GL_NONE;
426}
427
428// true if varying x has a higher priority in packing than y
429bool Shader::compareVarying(const Varying &x, const Varying &y)
430{
431 if(x.type == y.type)
432 {
433 return x.size > y.size;
434 }
435
436 switch (x.type)
437 {
438 case GL_FLOAT_MAT4: return true;
439 case GL_FLOAT_MAT2:
440 switch(y.type)
441 {
442 case GL_FLOAT_MAT4: return false;
443 case GL_FLOAT_MAT2: return true;
444 case GL_FLOAT_VEC4: return true;
445 case GL_FLOAT_MAT3: return true;
446 case GL_FLOAT_VEC3: return true;
447 case GL_FLOAT_VEC2: return true;
448 case GL_FLOAT: return true;
449 default: UNREACHABLE();
450 }
451 break;
452 case GL_FLOAT_VEC4:
453 switch(y.type)
454 {
455 case GL_FLOAT_MAT4: return false;
456 case GL_FLOAT_MAT2: return false;
457 case GL_FLOAT_VEC4: return true;
458 case GL_FLOAT_MAT3: return true;
459 case GL_FLOAT_VEC3: return true;
460 case GL_FLOAT_VEC2: return true;
461 case GL_FLOAT: return true;
462 default: UNREACHABLE();
463 }
464 break;
465 case GL_FLOAT_MAT3:
466 switch(y.type)
467 {
468 case GL_FLOAT_MAT4: return false;
469 case GL_FLOAT_MAT2: return false;
470 case GL_FLOAT_VEC4: return false;
471 case GL_FLOAT_MAT3: return true;
472 case GL_FLOAT_VEC3: return true;
473 case GL_FLOAT_VEC2: return true;
474 case GL_FLOAT: return true;
475 default: UNREACHABLE();
476 }
477 break;
478 case GL_FLOAT_VEC3:
479 switch(y.type)
480 {
481 case GL_FLOAT_MAT4: return false;
482 case GL_FLOAT_MAT2: return false;
483 case GL_FLOAT_VEC4: return false;
484 case GL_FLOAT_MAT3: return false;
485 case GL_FLOAT_VEC3: return true;
486 case GL_FLOAT_VEC2: return true;
487 case GL_FLOAT: return true;
488 default: UNREACHABLE();
489 }
490 break;
491 case GL_FLOAT_VEC2:
492 switch(y.type)
493 {
494 case GL_FLOAT_MAT4: return false;
495 case GL_FLOAT_MAT2: return false;
496 case GL_FLOAT_VEC4: return false;
497 case GL_FLOAT_MAT3: return false;
498 case GL_FLOAT_VEC3: return false;
499 case GL_FLOAT_VEC2: return true;
500 case GL_FLOAT: return true;
501 default: UNREACHABLE();
502 }
503 break;
504 case GL_FLOAT: return false;
505 default: UNREACHABLE();
506 }
507
508 return false;
509}
510
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +0000511VertexShader::VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
512 : Shader(manager, renderer, handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000513{
514}
515
516VertexShader::~VertexShader()
517{
518}
519
520GLenum VertexShader::getType()
521{
522 return GL_VERTEX_SHADER;
523}
524
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000525void VertexShader::uncompile()
526{
527 Shader::uncompile();
528
529 // set by ParseAttributes
530 mAttributes.clear();
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000531}
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000532
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000533void VertexShader::compile()
534{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000535 uncompile();
536
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000537 compileToHLSL(mVertexCompiler);
538 parseAttributes();
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000539 parseVaryings();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000540}
541
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000542int VertexShader::getSemanticIndex(const std::string &attributeName)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000543{
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000544 if (!attributeName.empty())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000545 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000546 int semanticIndex = 0;
547 for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000548 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000549 if (attribute->name == attributeName)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000550 {
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000551 return semanticIndex;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000552 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000553
554 semanticIndex += VariableRowCount(attribute->type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000555 }
556 }
557
558 return -1;
559}
560
561void VertexShader::parseAttributes()
562{
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +0000563 const char *hlsl = getHLSL();
564 if (hlsl)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565 {
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +0000566 const char *input = strstr(hlsl, "// Attributes") + 14;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000567
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000568 while(true)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000569 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000570 char attributeType[256];
571 char attributeName[256];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000572
daniel@transgaming.com7ea933f2010-12-12 08:52:42 +0000573 int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000574
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000575 if (matches != 2)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000576 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000577 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000578 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000579
580 mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
581
582 input = strstr(input, ";") + 2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000583 }
584 }
585}
586
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +0000587FragmentShader::FragmentShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
588 : Shader(manager, renderer, handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000589{
590}
591
592FragmentShader::~FragmentShader()
593{
594}
595
596GLenum FragmentShader::getType()
597{
598 return GL_FRAGMENT_SHADER;
599}
600
601void FragmentShader::compile()
602{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000603 uncompile();
604
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000605 compileToHLSL(mFragmentCompiler);
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000606 parseVaryings();
daniel@transgaming.comcde6a612012-02-17 18:01:10 +0000607 mVaryings.sort(compareVarying);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000608}
609}