blob: 405f119c5198cdc352441a2561ecfb50b2fd9dd5 [file] [log] [blame]
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// utilities.cpp: Conversion functions and other utility routines.
#include "common/utilities.h"
#include "common/mathutil.h"
#include "common/platform.h"
#include <set>
namespace gl
{
int VariableComponentCount(GLenum type)
{
return VariableRowCount(type) * VariableColumnCount(type);
}
GLenum VariableComponentType(GLenum type)
{
switch(type)
{
case GL_BOOL:
case GL_BOOL_VEC2:
case GL_BOOL_VEC3:
case GL_BOOL_VEC4:
return GL_BOOL;
case GL_FLOAT:
case GL_FLOAT_VEC2:
case GL_FLOAT_VEC3:
case GL_FLOAT_VEC4:
case GL_FLOAT_MAT2:
case GL_FLOAT_MAT3:
case GL_FLOAT_MAT4:
case GL_FLOAT_MAT2x3:
case GL_FLOAT_MAT3x2:
case GL_FLOAT_MAT2x4:
case GL_FLOAT_MAT4x2:
case GL_FLOAT_MAT3x4:
case GL_FLOAT_MAT4x3:
return GL_FLOAT;
case GL_INT:
case GL_SAMPLER_2D:
case GL_SAMPLER_3D:
case GL_SAMPLER_CUBE:
case GL_SAMPLER_2D_ARRAY:
case GL_INT_SAMPLER_2D:
case GL_INT_SAMPLER_3D:
case GL_INT_SAMPLER_CUBE:
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D:
case GL_UNSIGNED_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_CUBE:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
case GL_SAMPLER_2D_SHADOW:
case GL_SAMPLER_CUBE_SHADOW:
case GL_SAMPLER_2D_ARRAY_SHADOW:
case GL_INT_VEC2:
case GL_INT_VEC3:
case GL_INT_VEC4:
return GL_INT;
case GL_UNSIGNED_INT:
case GL_UNSIGNED_INT_VEC2:
case GL_UNSIGNED_INT_VEC3:
case GL_UNSIGNED_INT_VEC4:
return GL_UNSIGNED_INT;
default:
UNREACHABLE();
}
return GL_NONE;
}
size_t VariableComponentSize(GLenum type)
{
switch(type)
{
case GL_BOOL: return sizeof(GLint);
case GL_FLOAT: return sizeof(GLfloat);
case GL_INT: return sizeof(GLint);
case GL_UNSIGNED_INT: return sizeof(GLuint);
default: UNREACHABLE();
}
return 0;
}
size_t VariableInternalSize(GLenum type)
{
// Expanded to 4-element vectors
return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
}
size_t VariableExternalSize(GLenum type)
{
return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
}
GLenum VariableBoolVectorType(GLenum type)
{
switch (type)
{
case GL_FLOAT:
case GL_INT:
case GL_UNSIGNED_INT:
return GL_BOOL;
case GL_FLOAT_VEC2:
case GL_INT_VEC2:
case GL_UNSIGNED_INT_VEC2:
return GL_BOOL_VEC2;
case GL_FLOAT_VEC3:
case GL_INT_VEC3:
case GL_UNSIGNED_INT_VEC3:
return GL_BOOL_VEC3;
case GL_FLOAT_VEC4:
case GL_INT_VEC4:
case GL_UNSIGNED_INT_VEC4:
return GL_BOOL_VEC4;
default:
UNREACHABLE();
return GL_NONE;
}
}
int VariableRowCount(GLenum type)
{
switch (type)
{
case GL_NONE:
case GL_STRUCT_ANGLEX:
return 0;
case GL_BOOL:
case GL_FLOAT:
case GL_INT:
case GL_UNSIGNED_INT:
case GL_BOOL_VEC2:
case GL_FLOAT_VEC2:
case GL_INT_VEC2:
case GL_UNSIGNED_INT_VEC2:
case GL_BOOL_VEC3:
case GL_FLOAT_VEC3:
case GL_INT_VEC3:
case GL_UNSIGNED_INT_VEC3:
case GL_BOOL_VEC4:
case GL_FLOAT_VEC4:
case GL_INT_VEC4:
case GL_UNSIGNED_INT_VEC4:
case GL_SAMPLER_2D:
case GL_SAMPLER_3D:
case GL_SAMPLER_CUBE:
case GL_SAMPLER_2D_ARRAY:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_2D_RECT_ARB:
case GL_INT_SAMPLER_2D:
case GL_INT_SAMPLER_3D:
case GL_INT_SAMPLER_CUBE:
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D:
case GL_UNSIGNED_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_CUBE:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
case GL_SAMPLER_2D_SHADOW:
case GL_SAMPLER_CUBE_SHADOW:
case GL_SAMPLER_2D_ARRAY_SHADOW:
return 1;
case GL_FLOAT_MAT2:
case GL_FLOAT_MAT3x2:
case GL_FLOAT_MAT4x2:
return 2;
case GL_FLOAT_MAT3:
case GL_FLOAT_MAT2x3:
case GL_FLOAT_MAT4x3:
return 3;
case GL_FLOAT_MAT4:
case GL_FLOAT_MAT2x4:
case GL_FLOAT_MAT3x4:
return 4;
default:
UNREACHABLE();
}
return 0;
}
int VariableColumnCount(GLenum type)
{
switch (type)
{
case GL_NONE:
case GL_STRUCT_ANGLEX:
return 0;
case GL_BOOL:
case GL_FLOAT:
case GL_INT:
case GL_UNSIGNED_INT:
case GL_SAMPLER_2D:
case GL_SAMPLER_3D:
case GL_SAMPLER_CUBE:
case GL_SAMPLER_2D_ARRAY:
case GL_INT_SAMPLER_2D:
case GL_INT_SAMPLER_3D:
case GL_INT_SAMPLER_CUBE:
case GL_INT_SAMPLER_2D_ARRAY:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_2D_RECT_ARB:
case GL_UNSIGNED_INT_SAMPLER_2D:
case GL_UNSIGNED_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_CUBE:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
case GL_SAMPLER_2D_SHADOW:
case GL_SAMPLER_CUBE_SHADOW:
case GL_SAMPLER_2D_ARRAY_SHADOW:
return 1;
case GL_BOOL_VEC2:
case GL_FLOAT_VEC2:
case GL_INT_VEC2:
case GL_UNSIGNED_INT_VEC2:
case GL_FLOAT_MAT2:
case GL_FLOAT_MAT2x3:
case GL_FLOAT_MAT2x4:
return 2;
case GL_BOOL_VEC3:
case GL_FLOAT_VEC3:
case GL_INT_VEC3:
case GL_UNSIGNED_INT_VEC3:
case GL_FLOAT_MAT3:
case GL_FLOAT_MAT3x2:
case GL_FLOAT_MAT3x4:
return 3;
case GL_BOOL_VEC4:
case GL_FLOAT_VEC4:
case GL_INT_VEC4:
case GL_UNSIGNED_INT_VEC4:
case GL_FLOAT_MAT4:
case GL_FLOAT_MAT4x2:
case GL_FLOAT_MAT4x3:
return 4;
default:
UNREACHABLE();
}
return 0;
}
bool IsSampler(GLenum type)
{
switch (type)
{
case GL_SAMPLER_2D:
case GL_SAMPLER_3D:
case GL_SAMPLER_CUBE:
case GL_SAMPLER_2D_ARRAY:
case GL_INT_SAMPLER_2D:
case GL_INT_SAMPLER_3D:
case GL_INT_SAMPLER_CUBE:
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D:
case GL_UNSIGNED_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_CUBE:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
case GL_SAMPLER_2D_SHADOW:
case GL_SAMPLER_CUBE_SHADOW:
case GL_SAMPLER_2D_ARRAY_SHADOW:
return true;
}
return false;
}
bool IsMatrixType(GLenum type)
{
return VariableRowCount(type) > 1;
}
GLenum TransposeMatrixType(GLenum type)
{
if (!IsMatrixType(type))
{
return type;
}
switch (type)
{
case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
default: UNREACHABLE(); return GL_NONE;
}
}
int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
{
ASSERT(IsMatrixType(type));
return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
}
int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
{
ASSERT(IsMatrixType(type));
return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
}
int VariableRegisterCount(GLenum type)
{
return IsMatrixType(type) ? VariableColumnCount(type) : 1;
}
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
{
ASSERT(allocationSize <= bitsSize);
unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
{
if ((*bits & mask) == 0)
{
*bits |= mask;
return i;
}
mask <<= 1;
}
return -1;
}
bool IsCubemapTextureTarget(GLenum target)
{
return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
}
bool IsTriangleMode(GLenum drawMode)
{
switch (drawMode)
{
case GL_TRIANGLES:
case GL_TRIANGLE_FAN:
case GL_TRIANGLE_STRIP:
return true;
case GL_POINTS:
case GL_LINES:
case GL_LINE_LOOP:
case GL_LINE_STRIP:
return false;
default: UNREACHABLE();
}
return false;
}
// [OpenGL ES SL 3.00.4] Section 11 p. 120
// Vertex Outs/Fragment Ins packing priorities
int VariableSortOrder(GLenum type)
{
switch (type)
{
// 1. Arrays of mat4 and mat4
// Non-square matrices of type matCxR consume the same space as a square
// matrix of type matN where N is the greater of C and R
case GL_FLOAT_MAT4:
case GL_FLOAT_MAT2x4:
case GL_FLOAT_MAT3x4:
case GL_FLOAT_MAT4x2:
case GL_FLOAT_MAT4x3:
return 0;
// 2. Arrays of mat2 and mat2 (since they occupy full rows)
case GL_FLOAT_MAT2:
return 1;
// 3. Arrays of vec4 and vec4
case GL_FLOAT_VEC4:
case GL_INT_VEC4:
case GL_BOOL_VEC4:
case GL_UNSIGNED_INT_VEC4:
return 2;
// 4. Arrays of mat3 and mat3
case GL_FLOAT_MAT3:
case GL_FLOAT_MAT2x3:
case GL_FLOAT_MAT3x2:
return 3;
// 5. Arrays of vec3 and vec3
case GL_FLOAT_VEC3:
case GL_INT_VEC3:
case GL_BOOL_VEC3:
case GL_UNSIGNED_INT_VEC3:
return 4;
// 6. Arrays of vec2 and vec2
case GL_FLOAT_VEC2:
case GL_INT_VEC2:
case GL_BOOL_VEC2:
case GL_UNSIGNED_INT_VEC2:
return 5;
// 7. Single component types
case GL_FLOAT:
case GL_INT:
case GL_BOOL:
case GL_UNSIGNED_INT:
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_2D_ARRAY:
case GL_SAMPLER_3D:
case GL_INT_SAMPLER_2D:
case GL_INT_SAMPLER_3D:
case GL_INT_SAMPLER_CUBE:
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D:
case GL_UNSIGNED_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_CUBE:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
case GL_SAMPLER_2D_SHADOW:
case GL_SAMPLER_2D_ARRAY_SHADOW:
case GL_SAMPLER_CUBE_SHADOW:
return 6;
default:
UNREACHABLE();
return 0;
}
}
}
std::string getTempPath()
{
#ifdef ANGLE_PLATFORM_WINDOWS
char path[MAX_PATH];
DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
if (pathLen == 0)
{
UNREACHABLE();
return std::string();
}
UINT unique = GetTempFileNameA(path, "sh", 0, path);
if (unique == 0)
{
UNREACHABLE();
return std::string();
}
return path;
#else
UNIMPLEMENTED();
return "";
#endif
}
void writeFile(const char* path, const void* content, size_t size)
{
FILE* file = fopen(path, "w");
if (!file)
{
UNREACHABLE();
return;
}
fwrite(content, sizeof(char), size, file);
fclose(file);
}