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