| /*------------------------------------------------------------------------- |
| * 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 |