1/*-------------------------------------------------------------------------
2 * drawElements Quality Program Random Shader Generator
3 * ----------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Variable class.
22 *//*--------------------------------------------------------------------*/
23
24#include "rsgVariable.hpp"
25#include "rsgGeneratorState.hpp"
26#include "rsgShader.hpp"
27
28namespace rsg
29{
30
31Variable::Variable (const VariableType& type, Storage storage, const char* name)
32	: m_type			(type)
33	, m_storage			(storage)
34	, m_name			(name)
35	, m_layoutLocation	(-1)
36{
37}
38
39Variable::~Variable (void)
40{
41}
42
43void Variable::tokenizeDeclaration (GeneratorState& state, TokenStream& str) const
44{
45	Version targetVersion = state.getProgramParameters().version;
46
47	// \todo [2011-03-10 pyry] Remove precision hacks once precision handling is implemented
48	switch (m_storage)
49	{
50		case STORAGE_CONST:				str << Token::CONST;		break;
51		case STORAGE_PARAMETER_IN:		str << Token::IN;			break;
52		case STORAGE_PARAMETER_OUT:		str << Token::OUT;			break;
53		case STORAGE_PARAMETER_INOUT:	str << Token::INOUT;		break;
54
55		case STORAGE_UNIFORM:
56		{
57			str << Token::UNIFORM;
58			if (m_type.isFloatOrVec() || m_type.isIntOrVec())
59				str << Token::MEDIUM_PRECISION;
60			break;
61		}
62
63		case STORAGE_SHADER_IN:
64		{
65			if (targetVersion >= VERSION_300)
66			{
67				if (hasLayoutLocation())
68					str << Token::LAYOUT << Token::LEFT_PAREN << Token::LOCATION << Token::EQUAL << m_layoutLocation << Token::RIGHT_PAREN;
69
70				str << Token::IN;
71
72				if (state.getShader().getType() == Shader::TYPE_FRAGMENT)
73					str << Token::MEDIUM_PRECISION;
74			}
75			else
76			{
77				DE_ASSERT(!hasLayoutLocation());
78
79				switch (state.getShader().getType())
80				{
81					case Shader::TYPE_VERTEX:	str << Token::ATTRIBUTE;								break;
82					case Shader::TYPE_FRAGMENT:	str << Token::VARYING << Token::MEDIUM_PRECISION;		break;
83					default:					DE_ASSERT(DE_FALSE);									break;
84				}
85			}
86			break;
87		}
88
89		case STORAGE_SHADER_OUT:
90		{
91			if (targetVersion >= VERSION_300)
92			{
93				if (hasLayoutLocation())
94					str << Token::LAYOUT << Token::LEFT_PAREN << Token::LOCATION << Token::EQUAL << m_layoutLocation << Token::RIGHT_PAREN;
95
96				str << Token::OUT << Token::MEDIUM_PRECISION;
97			}
98			else
99			{
100				DE_ASSERT(!hasLayoutLocation());
101
102				if (state.getShader().getType() == Shader::TYPE_VERTEX)
103					str << Token::VARYING << Token::MEDIUM_PRECISION;
104				else
105					DE_ASSERT(DE_FALSE);
106			}
107			break;
108		}
109
110		case STORAGE_LOCAL:
111		default:
112			/* nothing */
113			break;
114	}
115
116	m_type.tokenizeShortType(str);
117
118	DE_ASSERT(m_name != "");
119	str << Token(m_name.c_str());
120}
121
122} // rsg
123