OSDN Git Service

5535369d82712aa65ae41166e34dcff0a2b477a1
[android-x86/external-swiftshader.git] / src / OpenGL / libGLESv2 / Shader.cpp
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 // Shader.cpp: Implements the Shader class and its  derived classes
16 // VertexShader and FragmentShader. Implements GL shader objects and related
17 // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
18
19 #include "Shader.h"
20
21 #include "main.h"
22 #include "utilities.h"
23
24 #include <string>
25 #include <algorithm>
26
27 namespace es2
28 {
29 bool Shader::compilerInitialized = false;
30
31 Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
32 {
33         mSource = nullptr;
34
35         clear();
36
37         mRefCount = 0;
38         mDeleteStatus = false;
39 }
40
41 Shader::~Shader()
42 {
43         delete[] mSource;
44 }
45
46 GLuint Shader::getName() const
47 {
48         return mHandle;
49 }
50
51 void Shader::setSource(GLsizei count, const char *const *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
91 size_t Shader::getInfoLogLength() const
92 {
93         if(infoLog.empty())
94         {
95                 return 0;
96         }
97         else
98         {
99            return infoLog.size() + 1;
100         }
101 }
102
103 void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLogOut)
104 {
105         int index = 0;
106
107         if(bufSize > 0)
108         {
109                 if(!infoLog.empty())
110                 {
111                         index = std::min(bufSize - 1, (GLsizei)infoLog.size());
112                         memcpy(infoLogOut, infoLog.c_str(), index);
113                 }
114
115                 infoLogOut[index] = '\0';
116         }
117
118         if(length)
119         {
120                 *length = index;
121         }
122 }
123
124 size_t Shader::getSourceLength() const
125 {
126         if(!mSource)
127         {
128                 return 0;
129         }
130         else
131         {
132            return strlen(mSource) + 1;
133         }
134 }
135
136 void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
137 {
138         int index = 0;
139
140         if(bufSize > 0)
141         {
142                 if(mSource)
143                 {
144                         index = std::min(bufSize - 1, (int)strlen(mSource));
145                         memcpy(source, mSource, index);
146                 }
147
148                 source[index] = '\0';
149         }
150
151         if(length)
152         {
153                 *length = index;
154         }
155 }
156
157 TranslatorASM *Shader::createCompiler(GLenum shaderType)
158 {
159         if(!compilerInitialized)
160         {
161                 InitCompilerGlobals();
162                 compilerInitialized = true;
163         }
164
165         TranslatorASM *assembler = new TranslatorASM(this, shaderType);
166
167         ShBuiltInResources resources;
168         resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
169         resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
170         resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
171         resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
172         resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
173         resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
174         resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
175         resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
176         resources.MaxVertexOutputVectors = MAX_VERTEX_OUTPUT_VECTORS;
177         resources.MaxFragmentInputVectors = MAX_FRAGMENT_INPUT_VECTORS;
178         resources.MinProgramTexelOffset = MIN_PROGRAM_TEXEL_OFFSET;
179         resources.MaxProgramTexelOffset = MAX_PROGRAM_TEXEL_OFFSET;
180         resources.OES_standard_derivatives = 1;
181         resources.OES_fragment_precision_high = 1;
182         resources.OES_EGL_image_external = 1;
183         resources.EXT_draw_buffers = 1;
184         resources.MaxCallStackDepth = 16;
185         assembler->Init(resources);
186
187         return assembler;
188 }
189
190 void Shader::clear()
191 {
192         infoLog.clear();
193
194         varyings.clear();
195         activeUniforms.clear();
196         activeAttributes.clear();
197 }
198
199 void Shader::compile()
200 {
201         clear();
202
203         createShader();
204         TranslatorASM *compiler = createCompiler(getType());
205
206         // Ensure we don't pass a nullptr source to the compiler
207         const char *source = "\0";
208         if(mSource)
209         {
210                 source = mSource;
211         }
212
213         bool success = compiler->compile(&source, 1, SH_OBJECT_CODE);
214
215         if(false)
216         {
217                 static int serial = 1;
218
219                 if(false)
220                 {
221                         char buffer[256];
222                         sprintf(buffer, "shader-input-%d-%d.txt", getName(), serial);
223                         FILE *file = fopen(buffer, "wt");
224                         fprintf(file, "%s", mSource);
225                         fclose(file);
226                 }
227
228                 getShader()->print("shader-output-%d-%d.txt", getName(), serial);
229
230                 serial++;
231         }
232
233         int shaderVersion = compiler->getShaderVersion();
234         int clientVersion = es2::getContext()->getClientVersion();
235
236         if(shaderVersion >= 300 && clientVersion < 3)
237         {
238                 infoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
239                 success = false;
240         }
241
242         if(!success)
243         {
244                 deleteShader();
245
246                 infoLog += compiler->getInfoSink().info.c_str();
247                 TRACE("\n%s", infoLog.c_str());
248         }
249
250         delete compiler;
251 }
252
253 bool Shader::isCompiled()
254 {
255         return getShader() != 0;
256 }
257
258 void Shader::addRef()
259 {
260         mRefCount++;
261 }
262
263 void Shader::release()
264 {
265         mRefCount--;
266
267         if(mRefCount == 0 && mDeleteStatus)
268         {
269                 mResourceManager->deleteShader(mHandle);
270         }
271 }
272
273 unsigned int Shader::getRefCount() const
274 {
275         return mRefCount;
276 }
277
278 bool Shader::isFlaggedForDeletion() const
279 {
280         return mDeleteStatus;
281 }
282
283 void Shader::flagForDeletion()
284 {
285         mDeleteStatus = true;
286 }
287
288 void Shader::releaseCompiler()
289 {
290         FreeCompilerGlobals();
291         compilerInitialized = false;
292 }
293
294 // true if varying x has a higher priority in packing than y
295 bool Shader::compareVarying(const glsl::Varying &x, const glsl::Varying &y)
296 {
297         if(x.type == y.type)
298         {
299                 return x.size() > y.size();
300         }
301
302         switch(x.type)
303         {
304         case GL_FLOAT_MAT4: return true;
305         case GL_FLOAT_MAT2:
306                 switch(y.type)
307                 {
308                 case GL_FLOAT_MAT4: return false;
309                 case GL_FLOAT_MAT2: return true;
310                 case GL_FLOAT_VEC4: return true;
311                 case GL_FLOAT_MAT3: return true;
312                 case GL_FLOAT_VEC3: return true;
313                 case GL_FLOAT_VEC2: return true;
314                 case GL_FLOAT:      return true;
315                 default: UNREACHABLE(y.type);
316                 }
317                 break;
318         case GL_FLOAT_VEC4:
319                 switch(y.type)
320                 {
321                 case GL_FLOAT_MAT4: return false;
322                 case GL_FLOAT_MAT2: return false;
323                 case GL_FLOAT_VEC4: return true;
324                 case GL_FLOAT_MAT3: return true;
325                 case GL_FLOAT_VEC3: return true;
326                 case GL_FLOAT_VEC2: return true;
327                 case GL_FLOAT:      return true;
328                 default: UNREACHABLE(y.type);
329                 }
330                 break;
331         case GL_FLOAT_MAT3:
332                 switch(y.type)
333                 {
334                 case GL_FLOAT_MAT4: return false;
335                 case GL_FLOAT_MAT2: return false;
336                 case GL_FLOAT_VEC4: return false;
337                 case GL_FLOAT_MAT3: return true;
338                 case GL_FLOAT_VEC3: return true;
339                 case GL_FLOAT_VEC2: return true;
340                 case GL_FLOAT:      return true;
341                 default: UNREACHABLE(y.type);
342                 }
343                 break;
344         case GL_FLOAT_VEC3:
345                 switch(y.type)
346                 {
347                 case GL_FLOAT_MAT4: return false;
348                 case GL_FLOAT_MAT2: return false;
349                 case GL_FLOAT_VEC4: return false;
350                 case GL_FLOAT_MAT3: return false;
351                 case GL_FLOAT_VEC3: return true;
352                 case GL_FLOAT_VEC2: return true;
353                 case GL_FLOAT:      return true;
354                 default: UNREACHABLE(y.type);
355                 }
356                 break;
357         case GL_FLOAT_VEC2:
358                 switch(y.type)
359                 {
360                 case GL_FLOAT_MAT4: return false;
361                 case GL_FLOAT_MAT2: return false;
362                 case GL_FLOAT_VEC4: return false;
363                 case GL_FLOAT_MAT3: return false;
364                 case GL_FLOAT_VEC3: return false;
365                 case GL_FLOAT_VEC2: return true;
366                 case GL_FLOAT:      return true;
367                 default: UNREACHABLE(y.type);
368                 }
369                 break;
370         case GL_FLOAT: return false;
371         default: UNREACHABLE(x.type);
372         }
373
374         return false;
375 }
376
377 VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
378 {
379         vertexShader = 0;
380 }
381
382 VertexShader::~VertexShader()
383 {
384         delete vertexShader;
385 }
386
387 GLenum VertexShader::getType() const
388 {
389         return GL_VERTEX_SHADER;
390 }
391
392 int VertexShader::getSemanticIndex(const std::string &attributeName)
393 {
394         if(!attributeName.empty())
395         {
396                 for(glsl::ActiveAttributes::iterator attribute = activeAttributes.begin(); attribute != activeAttributes.end(); attribute++)
397                 {
398                         if(attribute->name == attributeName)
399                         {
400                                 return attribute->registerIndex;
401                         }
402                 }
403         }
404
405         return -1;
406 }
407
408 sw::Shader *VertexShader::getShader() const
409 {
410         return vertexShader;
411 }
412
413 sw::VertexShader *VertexShader::getVertexShader() const
414 {
415         return vertexShader;
416 }
417
418 void VertexShader::createShader()
419 {
420         delete vertexShader;
421         vertexShader = new sw::VertexShader();
422 }
423
424 void VertexShader::deleteShader()
425 {
426         delete vertexShader;
427         vertexShader = nullptr;
428 }
429
430 FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
431 {
432         pixelShader = 0;
433 }
434
435 FragmentShader::~FragmentShader()
436 {
437         delete pixelShader;
438 }
439
440 GLenum FragmentShader::getType() const
441 {
442         return GL_FRAGMENT_SHADER;
443 }
444
445 sw::Shader *FragmentShader::getShader() const
446 {
447         return pixelShader;
448 }
449
450 sw::PixelShader *FragmentShader::getPixelShader() const
451 {
452         return pixelShader;
453 }
454
455 void FragmentShader::createShader()
456 {
457         delete pixelShader;
458         pixelShader = new sw::PixelShader();
459 }
460
461 void FragmentShader::deleteShader()
462 {
463         delete pixelShader;
464         pixelShader = nullptr;
465 }
466
467 }