blob: 992e937a933a5d4df7497980c0e12406f67dcf37 [file] [log] [blame]
/*-------------------------------------------------------------------------
* drawElements Quality Program Random Shader Generator
* ----------------------------------------------------
*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Variable Type class.
*//*--------------------------------------------------------------------*/
#include "rsgVariableType.hpp"
#include "rsgToken.hpp"
using std::vector;
namespace rsg
{
VariableType& VariableType::operator= (const VariableType& other)
{
if (this == &other)
return *this;
delete m_elementType;
m_elementType = DE_NULL;
m_baseType = other.m_baseType;
m_precision = other.m_precision;
m_typeName = other.m_typeName;
m_numElements = other.m_numElements;
m_members = other.m_members;
m_elementType = DE_NULL;
if (other.m_elementType)
m_elementType = new VariableType(*other.m_elementType);
return *this;
}
VariableType::VariableType (const VariableType& other)
: m_elementType(DE_NULL)
{
*this = other;
}
bool VariableType::operator!= (const VariableType& other) const
{
if (m_baseType != other.m_baseType)
return true;
if (m_precision != other.m_precision)
return true;
if (m_numElements != other.m_numElements)
return true;
if (!!m_elementType != !!other.m_elementType)
return true;
if (m_elementType && *m_elementType != *other.m_elementType)
return true;
if (m_members != other.m_members)
return true;
return false;
}
bool VariableType::operator== (const VariableType& other) const
{
return !(*this != other);
}
int VariableType::getScalarSize (void) const
{
switch (m_baseType)
{
case TYPE_VOID:
case TYPE_FLOAT:
case TYPE_INT:
case TYPE_BOOL:
case TYPE_SAMPLER_2D:
case TYPE_SAMPLER_CUBE:
return m_numElements;
case TYPE_STRUCT:
{
int sum = 0;
for (vector<Member>::const_iterator i = m_members.begin(); i != m_members.end(); i++)
sum += i->getType().getScalarSize();
return sum;
}
case TYPE_ARRAY:
{
DE_ASSERT(m_elementType);
return m_elementType->getScalarSize() * m_numElements;
}
default:
DE_ASSERT(false);
return 0;
}
}
int VariableType::getMemberScalarOffset (int memberNdx) const
{
DE_ASSERT(isStruct());
int curOffset = 0;
for (vector<Member>::const_iterator i = m_members.begin(); i != m_members.begin() + memberNdx; i++)
curOffset += i->getType().getScalarSize();
return curOffset;
}
int VariableType::getElementScalarOffset (int elementNdx) const
{
DE_ASSERT(isArray());
return elementNdx * getElementType().getScalarSize();
}
const VariableType& VariableType::getScalarType (Type baseType)
{
switch (baseType)
{
case TYPE_FLOAT:
{
static const VariableType s_floatTypes[] =
{
VariableType(TYPE_FLOAT, 1)
// \todo [pyry] Extend with different precision variants?
};
return s_floatTypes[0];
}
case TYPE_INT:
{
static const VariableType s_intTypes[] =
{
VariableType(TYPE_INT, 1)
};
return s_intTypes[0];
}
case TYPE_BOOL:
{
static const VariableType s_boolTypes[] =
{
VariableType(TYPE_BOOL, 1)
};
return s_boolTypes[0];
}
case TYPE_SAMPLER_2D:
{
static const VariableType sampler2DType = VariableType(TYPE_SAMPLER_2D, 1);
return sampler2DType;
}
case TYPE_SAMPLER_CUBE:
{
static const VariableType samplerCubeType = VariableType(TYPE_SAMPLER_CUBE, 1);
return samplerCubeType;
}
default:
DE_ASSERT(DE_FALSE);
throw Exception("VariableType::getScalarType(): unsupported type");
}
}
const VariableType& VariableType::getElementType (void) const
{
DE_ASSERT(m_precision == PRECISION_NONE); // \todo [pyry] Precision
switch (m_baseType)
{
case TYPE_FLOAT:
case TYPE_INT:
case TYPE_BOOL:
case TYPE_SAMPLER_2D:
case TYPE_SAMPLER_CUBE:
return getScalarType(m_baseType);
case TYPE_ARRAY:
{
DE_ASSERT(m_elementType);
return *m_elementType;
}
default:
DE_ASSERT(DE_FALSE);
throw Exception("VariableType::getElementType(): unsupported type");
}
}
void VariableType::tokenizeShortType (TokenStream& str) const
{
switch (m_precision)
{
case PRECISION_LOW: str << Token::LOW_PRECISION; break;
case PRECISION_MEDIUM: str << Token::MEDIUM_PRECISION; break;
case PRECISION_HIGH: str << Token::HIGH_PRECISION; break;
default: /* nothing */ break;
}
switch (m_baseType)
{
case TYPE_VOID:
str << Token::VOID;
break;
case TYPE_FLOAT:
switch (m_numElements)
{
case 1: str << Token::FLOAT; break;
case 2: str << Token::VEC2; break;
case 3: str << Token::VEC3; break;
case 4: str << Token::VEC4; break;
default: DE_ASSERT(DE_FALSE); break;
}
break;
case TYPE_INT:
switch (m_numElements)
{
case 1: str << Token::INT; break;
case 2: str << Token::IVEC2; break;
case 3: str << Token::IVEC3; break;
case 4: str << Token::IVEC4; break;
default: DE_ASSERT(DE_FALSE); break;
}
break;
case TYPE_BOOL:
switch (m_numElements)
{
case 1: str << Token::BOOL; break;
case 2: str << Token::BVEC2; break;
case 3: str << Token::BVEC3; break;
case 4: str << Token::BVEC4; break;
default: DE_ASSERT(DE_FALSE); break;
}
break;
case TYPE_SAMPLER_2D: str << Token::SAMPLER2D; break;
case TYPE_SAMPLER_CUBE: str << Token::SAMPLERCUBE; break;
case TYPE_STRUCT:
DE_ASSERT(m_typeName != "");
str << Token(m_typeName.c_str());
break;
case TYPE_ARRAY:
DE_ASSERT(m_elementType);
m_elementType->tokenizeShortType(str);
str << Token::LEFT_BRACKET << Token(m_numElements) << Token::RIGHT_BRACKET;
break;
default:
DE_ASSERT(DE_FALSE);
break;
}
}
} // rsg