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