• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES Utilities
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 Shader variable type.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "gluVarType.hpp"
25 #include "deStringUtil.hpp"
26 
27 namespace glu
28 {
29 
VarType(void)30 VarType::VarType (void)
31 	: m_type(TYPE_LAST)
32 {
33 }
34 
VarType(const VarType & other)35 VarType::VarType (const VarType& other)
36 	: m_type(TYPE_LAST)
37 {
38 	*this = other;
39 }
40 
VarType(DataType basicType,Precision precision)41 VarType::VarType (DataType basicType, Precision precision)
42 	: m_type(TYPE_BASIC)
43 {
44 	m_data.basic.type		= basicType;
45 	m_data.basic.precision	= precision;
46 }
47 
VarType(const VarType & elementType,int arraySize)48 VarType::VarType (const VarType& elementType, int arraySize)
49 	: m_type(TYPE_ARRAY)
50 {
51 	DE_ASSERT(arraySize >= 0 || arraySize == UNSIZED_ARRAY);
52 	m_data.array.size			= arraySize;
53 	m_data.array.elementType	= new VarType(elementType);
54 }
55 
VarType(const StructType * structPtr)56 VarType::VarType (const StructType* structPtr)
57 	: m_type(TYPE_STRUCT)
58 {
59 	m_data.structPtr = structPtr;
60 }
61 
~VarType(void)62 VarType::~VarType (void)
63 {
64 	if (m_type == TYPE_ARRAY)
65 		delete m_data.array.elementType;
66 }
67 
operator =(const VarType & other)68 VarType& VarType::operator= (const VarType& other)
69 {
70 	if (this == &other)
71 		return *this; // Self-assignment.
72 
73 	if (m_type == TYPE_ARRAY)
74 		delete m_data.array.elementType;
75 
76 	m_type	= other.m_type;
77 	m_data	= Data();
78 
79 	if (m_type == TYPE_ARRAY)
80 	{
81 		m_data.array.elementType	= new VarType(*other.m_data.array.elementType);
82 		m_data.array.size			= other.m_data.array.size;
83 	}
84 	else
85 		m_data = other.m_data;
86 
87 	return *this;
88 }
89 
getScalarSize(void) const90 int VarType::getScalarSize (void) const
91 {
92 	switch (m_type)
93 	{
94 		case TYPE_BASIC:	return glu::getDataTypeScalarSize(m_data.basic.type);
95 		case TYPE_ARRAY:	return m_data.array.elementType->getScalarSize()*m_data.array.size;
96 
97 		case TYPE_STRUCT:
98 		{
99 			int size = 0;
100 			for (StructType::ConstIterator iter = m_data.structPtr->begin(); iter != m_data.structPtr->end(); iter++)
101 				size += iter->getType().getScalarSize();
102 			return size;
103 		}
104 
105 		default:
106 			DE_ASSERT(false);
107 			return 0;
108 	}
109 }
110 
operator ==(const VarType & other) const111 bool VarType::operator== (const VarType& other) const
112 {
113 	if (m_type != other.m_type)
114 		return false;
115 
116 	switch (m_type)
117 	{
118 		case TYPE_BASIC:
119 			return	m_data.basic.type == other.m_data.basic.type &&
120 					m_data.basic.precision == other.m_data.basic.precision;
121 
122 		case TYPE_ARRAY:
123 			return	*m_data.array.elementType == *other.m_data.array.elementType &&
124 					m_data.array.size == other.m_data.array.size;
125 
126 		case TYPE_STRUCT:
127 			return m_data.structPtr == other.m_data.structPtr;
128 
129 		default:
130 			DE_ASSERT(false);
131 			return 0;
132 	}
133 }
134 
operator !=(const VarType & other) const135 bool VarType::operator!= (const VarType& other) const
136 {
137 	return !(*this == other);
138 }
139 
140 // StructMember implementation
141 
operator ==(const StructMember & other) const142 bool StructMember::operator== (const StructMember& other) const
143 {
144 	return (m_name == other.m_name) && (m_type == other.m_type);
145 }
146 
operator !=(const StructMember & other) const147 bool StructMember::operator!= (const StructMember& other) const
148 {
149 	return !(*this == other);
150 }
151 
152 // StructType implementation.
153 
addMember(const char * name,const VarType & type)154 void StructType::addMember (const char* name, const VarType& type)
155 {
156 	m_members.push_back(StructMember(name, type));
157 }
158 
operator ==(const StructType & other) const159 bool StructType::operator== (const StructType& other) const
160 {
161 	return (m_typeName == other.m_typeName) && (m_members == other.m_members);
162 }
163 
operator !=(const StructType & other) const164 bool StructType::operator!= (const StructType& other) const
165 {
166 	return !(*this == other);
167 }
168 
getStorageName(Storage storage)169 const char* getStorageName (Storage storage)
170 {
171 	static const char* const s_names[] = { "in", "out", "const", "uniform", "buffer" };
172 
173 	return de::getSizedArrayElement<STORAGE_LAST>(s_names, storage);
174 }
175 
getInterpolationName(Interpolation interpolation)176 const char* getInterpolationName (Interpolation interpolation)
177 {
178 	static const char* const s_names[] = { "smooth", "flat", "centroid" };
179 
180 	return de::getSizedArrayElement<INTERPOLATION_LAST>(s_names, interpolation);
181 }
182 
getFormatLayoutName(FormatLayout layout)183 const char* getFormatLayoutName (FormatLayout layout)
184 {
185 	static const char* s_names[] =
186 	{
187 		"rgba32f",			// FORMATLAYOUT_RGBA32F
188 		"rgba16f",			// FORMATLAYOUT_RGBA16F
189 		"r32f",				// FORMATLAYOUT_R32F
190 		"rgba8",			// FORMATLAYOUT_RGBA8
191 		"rgba8_snorm",		// FORMATLAYOUT_RGBA8_SNORM
192 		"rgba32i",			// FORMATLAYOUT_RGBA32I
193 		"rgba16i",			// FORMATLAYOUT_RGBA16I
194 		"rgba8i",			// FORMATLAYOUT_RGBA8I
195 		"r32i",				// FORMATLAYOUT_R32I
196 		"rgba32ui",			// FORMATLAYOUT_RGBA32UI
197 		"rgba16ui",			// FORMATLAYOUT_RGBA16UI
198 		"rgba8ui",			// FORMATLAYOUT_RGBA8UI
199 		"r32ui",			// FORMATLAYOUT_R32UI
200 	};
201 
202 	return de::getSizedArrayElement<FORMATLAYOUT_LAST>(s_names, layout);
203 }
204 
getMemoryAccessQualifierName(MemoryAccessQualifier qualifier)205 const char* getMemoryAccessQualifierName (MemoryAccessQualifier qualifier)
206 {
207 	switch (qualifier)
208 	{
209 		case MEMORYACCESSQUALIFIER_COHERENT_BIT:	return "coherent";
210 		case MEMORYACCESSQUALIFIER_VOLATILE_BIT:	return "volatile";
211 		case MEMORYACCESSQUALIFIER_RESTRICT_BIT:	return "restrict";
212 		case MEMORYACCESSQUALIFIER_READONLY_BIT:	return "readonly";
213 		case MEMORYACCESSQUALIFIER_WRITEONLY_BIT:	return "writeonly";
214 		default:
215 			DE_ASSERT(false);
216 			return DE_NULL;
217 	}
218 }
219 
getMatrixOrderName(MatrixOrder qualifier)220 const char* getMatrixOrderName (MatrixOrder qualifier)
221 {
222 	static const char* s_names[] =
223 	{
224 		"column_major",	// MATRIXORDER_COLUMN_MAJOR
225 		"row_major",	// MATRIXORDER_ROW_MAJOR
226 	};
227 
228 	return de::getSizedArrayElement<MATRIXORDER_LAST>(s_names, qualifier);
229 }
230 
231 // Layout Implementation
232 
Layout(int location_,int binding_,int offset_,FormatLayout format_,MatrixOrder matrixOrder_)233 Layout::Layout (int location_, int binding_, int offset_, FormatLayout format_, MatrixOrder matrixOrder_)
234 	: location			(location_)
235 	, binding			(binding_)
236 	, offset			(offset_)
237 	, format			(format_)
238 	, matrixOrder		(matrixOrder_)
239 {
240 }
241 
operator ==(const Layout & other) const242 bool Layout::operator== (const Layout& other) const
243 {
244 	return	location == other.location &&
245 			binding == other.binding &&
246 			offset == other.offset &&
247 			format == other.format &&
248 			matrixOrder == other.matrixOrder;
249 }
250 
operator !=(const Layout & other) const251 bool Layout::operator!= (const Layout& other) const
252 {
253 	return !(*this == other);
254 }
255 
256 // VariableDeclaration Implementation
257 
VariableDeclaration(const VarType & varType_,const std::string & name_,Storage storage_,Interpolation interpolation_,const Layout & layout_,deUint32 memoryAccessQualifierBits_)258 VariableDeclaration::VariableDeclaration (const VarType& varType_, const std::string& name_, Storage storage_, Interpolation interpolation_, const Layout& layout_, deUint32 memoryAccessQualifierBits_)
259 	: layout						(layout_)
260 	, interpolation					(interpolation_)
261 	, storage						(storage_)
262 	, varType						(varType_)
263 	, memoryAccessQualifierBits		(memoryAccessQualifierBits_)
264 	, name							(name_)
265 {
266 }
267 
operator ==(const VariableDeclaration & other) const268 bool VariableDeclaration::operator== (const VariableDeclaration& other) const
269 {
270 	return	layout == other.layout &&
271 			interpolation == other.interpolation &&
272 			storage == other.storage &&
273 			varType == other.varType &&
274 			memoryAccessQualifierBits == other.memoryAccessQualifierBits &&
275 			name == other.name;
276 }
277 
operator !=(const VariableDeclaration & other) const278 bool VariableDeclaration::operator!= (const VariableDeclaration& other) const
279 {
280 	return !(*this == other);
281 }
282 
283 // InterfaceBlock Implementation
284 
InterfaceBlock(void)285 InterfaceBlock::InterfaceBlock (void)
286 	: layout						(Layout())
287 	, storage						(glu::STORAGE_LAST)
288 	, memoryAccessQualifierFlags	(0)
289 {
290 }
291 
292 // Declaration utilties.
293 
operator <<(std::ostream & str,const Layout & layout)294 std::ostream& operator<< (std::ostream& str, const Layout& layout)
295 {
296 	std::vector<std::string> layoutDeclarationList;
297 
298 	if (layout.location != -1)
299 		layoutDeclarationList.push_back("location=" + de::toString(layout.location));
300 
301 	if (layout.binding != -1)
302 		layoutDeclarationList.push_back("binding=" + de::toString(layout.binding));
303 
304 	if (layout.offset != -1)
305 		layoutDeclarationList.push_back("offset=" + de::toString(layout.offset));
306 
307 	if (layout.format != FORMATLAYOUT_LAST)
308 		layoutDeclarationList.push_back(getFormatLayoutName(layout.format));
309 
310 	if (layout.matrixOrder != MATRIXORDER_LAST)
311 		layoutDeclarationList.push_back(getMatrixOrderName(layout.matrixOrder));
312 
313 	if (!layoutDeclarationList.empty())
314 	{
315 		str << "layout(" << layoutDeclarationList[0];
316 
317 		for (int layoutNdx = 1; layoutNdx < (int)layoutDeclarationList.size(); ++layoutNdx)
318 			str << ", " << layoutDeclarationList[layoutNdx];
319 
320 		str << ")";
321 	}
322 
323 	return str;
324 }
325 
operator <<(std::ostream & str,const VariableDeclaration & decl)326 std::ostream& operator<< (std::ostream& str, const VariableDeclaration& decl)
327 {
328 	if (decl.layout != Layout())
329 		str << decl.layout << " ";
330 
331 	for (int bitNdx = 0; (1 << bitNdx) & MEMORYACCESSQUALIFIER_MASK; ++bitNdx)
332 		if (decl.memoryAccessQualifierBits & (1 << bitNdx))
333 			str << getMemoryAccessQualifierName((glu::MemoryAccessQualifier)(1 << bitNdx)) << " ";
334 
335 	if (decl.interpolation != INTERPOLATION_LAST)
336 		str << getInterpolationName(decl.interpolation) << " ";
337 
338 	if (decl.storage != STORAGE_LAST)
339 		str << getStorageName(decl.storage) << " ";
340 
341 	str << declare(decl.varType, decl.name);
342 
343 	return str;
344 }
345 
346 namespace decl
347 {
348 
operator <<(std::ostream & str,const Indent & indent)349 std::ostream& operator<< (std::ostream& str, const Indent& indent)
350 {
351 	for (int i = 0; i < indent.level; i++)
352 		str << "\t";
353 	return str;
354 }
355 
operator <<(std::ostream & str,const DeclareVariable & decl)356 std::ostream& operator<< (std::ostream& str, const DeclareVariable& decl)
357 {
358 	const VarType&		type	= decl.varType;
359 	const VarType*		curType	= &type;
360 	std::vector<int>	arraySizes;
361 
362 	// Handle arrays.
363 	while (curType->isArrayType())
364 	{
365 		arraySizes.push_back(curType->getArraySize());
366 		curType = &curType->getElementType();
367 	}
368 
369 	if (curType->isBasicType())
370 	{
371 		if (curType->getPrecision() != PRECISION_LAST)
372 			str << glu::getPrecisionName(curType->getPrecision()) << " ";
373 		str << glu::getDataTypeName(curType->getBasicType());
374 	}
375 	else if (curType->isStructType())
376 	{
377 		const StructType* structPtr = curType->getStructPtr();
378 
379 		if (structPtr->hasTypeName())
380 			str << structPtr->getTypeName();
381 		else
382 			str << declare(structPtr, decl.indentLevel); // Generate inline declaration.
383 	}
384 	else
385 		DE_ASSERT(false);
386 
387 	str << " " << decl.name;
388 
389 	// Print array sizes.
390 	for (std::vector<int>::const_iterator sizeIter = arraySizes.begin(); sizeIter != arraySizes.end(); sizeIter++)
391 	{
392 		const int arrSize = *sizeIter;
393 		if (arrSize == VarType::UNSIZED_ARRAY)
394 			str << "[]";
395 		else
396 			str << "[" << arrSize << "]";
397 	}
398 
399 	return str;
400 }
401 
operator <<(std::ostream & str,const DeclareStructTypePtr & decl)402 std::ostream& operator<< (std::ostream& str, const DeclareStructTypePtr& decl)
403 {
404 	str << "struct";
405 
406 	// Type name is optional.
407 	if (decl.structPtr->hasTypeName())
408 		str << " " << decl.structPtr->getTypeName();
409 
410 	str << "\n" << indent(decl.indentLevel) << "{\n";
411 
412 	for (StructType::ConstIterator memberIter = decl.structPtr->begin(); memberIter != decl.structPtr->end(); memberIter++)
413 	{
414 		str << indent(decl.indentLevel+1);
415 		str << declare(memberIter->getType(), memberIter->getName(), decl.indentLevel+1) << ";\n";
416 	}
417 
418 	str << indent(decl.indentLevel) << "}";
419 
420 	return str;
421 }
422 
operator <<(std::ostream & str,const DeclareStructType & decl)423 std::ostream& operator<< (std::ostream& str, const DeclareStructType& decl)
424 {
425 	return str << declare(&decl.structType, decl.indentLevel);
426 }
427 
428 } // decl
429 } // glu
430