Home | History | Annotate | Download | only in libGLESv2
      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 		char buffer[256];
    219 		sprintf(buffer, "shader-input-%d-%d.txt", getName(), serial);
    220 		FILE *file = fopen(buffer, "wt");
    221 		fprintf(file, "%s", mSource);
    222 		fclose(file);
    223 		getShader()->print("shader-output-%d-%d.txt", getName(), serial);
    224 		serial++;
    225 	}
    226 
    227 	int shaderVersion = compiler->getShaderVersion();
    228 	int clientVersion = es2::getContext()->getClientVersion();
    229 
    230 	if(shaderVersion >= 300 && clientVersion < 3)
    231 	{
    232 		infoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
    233 		success = false;
    234 	}
    235 
    236 	if(!success)
    237 	{
    238 		deleteShader();
    239 
    240 		infoLog += compiler->getInfoSink().info.c_str();
    241 		TRACE("\n%s", infoLog.c_str());
    242 	}
    243 
    244 	delete compiler;
    245 }
    246 
    247 bool Shader::isCompiled()
    248 {
    249 	return getShader() != 0;
    250 }
    251 
    252 void Shader::addRef()
    253 {
    254 	mRefCount++;
    255 }
    256 
    257 void Shader::release()
    258 {
    259 	mRefCount--;
    260 
    261 	if(mRefCount == 0 && mDeleteStatus)
    262 	{
    263 		mResourceManager->deleteShader(mHandle);
    264 	}
    265 }
    266 
    267 unsigned int Shader::getRefCount() const
    268 {
    269 	return mRefCount;
    270 }
    271 
    272 bool Shader::isFlaggedForDeletion() const
    273 {
    274 	return mDeleteStatus;
    275 }
    276 
    277 void Shader::flagForDeletion()
    278 {
    279 	mDeleteStatus = true;
    280 }
    281 
    282 void Shader::releaseCompiler()
    283 {
    284 	FreeCompilerGlobals();
    285 	compilerInitialized = false;
    286 }
    287 
    288 // true if varying x has a higher priority in packing than y
    289 bool Shader::compareVarying(const glsl::Varying &x, const glsl::Varying &y)
    290 {
    291 	if(x.type == y.type)
    292 	{
    293 		return x.size() > y.size();
    294 	}
    295 
    296 	switch(x.type)
    297 	{
    298 	case GL_FLOAT_MAT4: return true;
    299 	case GL_FLOAT_MAT2:
    300 		switch(y.type)
    301 		{
    302 		case GL_FLOAT_MAT4: return false;
    303 		case GL_FLOAT_MAT2: return true;
    304 		case GL_FLOAT_VEC4: return true;
    305 		case GL_FLOAT_MAT3: return true;
    306 		case GL_FLOAT_VEC3: return true;
    307 		case GL_FLOAT_VEC2: return true;
    308 		case GL_FLOAT:      return true;
    309 		default: UNREACHABLE(y.type);
    310 		}
    311 		break;
    312 	case GL_FLOAT_VEC4:
    313 		switch(y.type)
    314 		{
    315 		case GL_FLOAT_MAT4: return false;
    316 		case GL_FLOAT_MAT2: return false;
    317 		case GL_FLOAT_VEC4: return true;
    318 		case GL_FLOAT_MAT3: return true;
    319 		case GL_FLOAT_VEC3: return true;
    320 		case GL_FLOAT_VEC2: return true;
    321 		case GL_FLOAT:      return true;
    322 		default: UNREACHABLE(y.type);
    323 		}
    324 		break;
    325 	case GL_FLOAT_MAT3:
    326 		switch(y.type)
    327 		{
    328 		case GL_FLOAT_MAT4: return false;
    329 		case GL_FLOAT_MAT2: return false;
    330 		case GL_FLOAT_VEC4: return false;
    331 		case GL_FLOAT_MAT3: return true;
    332 		case GL_FLOAT_VEC3: return true;
    333 		case GL_FLOAT_VEC2: return true;
    334 		case GL_FLOAT:      return true;
    335 		default: UNREACHABLE(y.type);
    336 		}
    337 		break;
    338 	case GL_FLOAT_VEC3:
    339 		switch(y.type)
    340 		{
    341 		case GL_FLOAT_MAT4: return false;
    342 		case GL_FLOAT_MAT2: return false;
    343 		case GL_FLOAT_VEC4: return false;
    344 		case GL_FLOAT_MAT3: return false;
    345 		case GL_FLOAT_VEC3: return true;
    346 		case GL_FLOAT_VEC2: return true;
    347 		case GL_FLOAT:      return true;
    348 		default: UNREACHABLE(y.type);
    349 		}
    350 		break;
    351 	case GL_FLOAT_VEC2:
    352 		switch(y.type)
    353 		{
    354 		case GL_FLOAT_MAT4: return false;
    355 		case GL_FLOAT_MAT2: return false;
    356 		case GL_FLOAT_VEC4: return false;
    357 		case GL_FLOAT_MAT3: return false;
    358 		case GL_FLOAT_VEC3: return false;
    359 		case GL_FLOAT_VEC2: return true;
    360 		case GL_FLOAT:      return true;
    361 		default: UNREACHABLE(y.type);
    362 		}
    363 		break;
    364 	case GL_FLOAT: return false;
    365 	default: UNREACHABLE(x.type);
    366 	}
    367 
    368 	return false;
    369 }
    370 
    371 VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
    372 {
    373 	vertexShader = 0;
    374 }
    375 
    376 VertexShader::~VertexShader()
    377 {
    378 	delete vertexShader;
    379 }
    380 
    381 GLenum VertexShader::getType() const
    382 {
    383 	return GL_VERTEX_SHADER;
    384 }
    385 
    386 int VertexShader::getSemanticIndex(const std::string &attributeName)
    387 {
    388 	if(!attributeName.empty())
    389 	{
    390 		for(glsl::ActiveAttributes::iterator attribute = activeAttributes.begin(); attribute != activeAttributes.end(); attribute++)
    391 		{
    392 			if(attribute->name == attributeName)
    393 			{
    394 				return attribute->registerIndex;
    395 			}
    396 		}
    397 	}
    398 
    399 	return -1;
    400 }
    401 
    402 sw::Shader *VertexShader::getShader() const
    403 {
    404 	return vertexShader;
    405 }
    406 
    407 sw::VertexShader *VertexShader::getVertexShader() const
    408 {
    409 	return vertexShader;
    410 }
    411 
    412 void VertexShader::createShader()
    413 {
    414 	delete vertexShader;
    415 	vertexShader = new sw::VertexShader();
    416 }
    417 
    418 void VertexShader::deleteShader()
    419 {
    420 	delete vertexShader;
    421 	vertexShader = nullptr;
    422 }
    423 
    424 FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
    425 {
    426 	pixelShader = 0;
    427 }
    428 
    429 FragmentShader::~FragmentShader()
    430 {
    431 	delete pixelShader;
    432 }
    433 
    434 GLenum FragmentShader::getType() const
    435 {
    436 	return GL_FRAGMENT_SHADER;
    437 }
    438 
    439 sw::Shader *FragmentShader::getShader() const
    440 {
    441 	return pixelShader;
    442 }
    443 
    444 sw::PixelShader *FragmentShader::getPixelShader() const
    445 {
    446 	return pixelShader;
    447 }
    448 
    449 void FragmentShader::createShader()
    450 {
    451 	delete pixelShader;
    452 	pixelShader = new sw::PixelShader();
    453 }
    454 
    455 void FragmentShader::deleteShader()
    456 {
    457 	delete pixelShader;
    458 	pixelShader = nullptr;
    459 }
    460 
    461 }
    462