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 
     27 namespace glu
     28 {
     29 
     30 VarType::VarType (void)
     31 	: m_type(TYPE_LAST)
     32 {
     33 }
     34 
     35 VarType::VarType (const VarType& other)
     36 	: m_type(TYPE_LAST)
     37 {
     38 	*this = other;
     39 }
     40 
     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 
     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 
     56 VarType::VarType (const StructType* structPtr)
     57 	: m_type(TYPE_STRUCT)
     58 {
     59 	m_data.structPtr = structPtr;
     60 }
     61 
     62 VarType::~VarType (void)
     63 {
     64 	if (m_type == TYPE_ARRAY)
     65 		delete m_data.array.elementType;
     66 }
     67 
     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 
     90 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 
    111 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 
    135 bool VarType::operator!= (const VarType& other) const
    136 {
    137 	return !(*this == other);
    138 }
    139 
    140 // StructMember implementation
    141 
    142 bool StructMember::operator== (const StructMember& other) const
    143 {
    144 	return (m_name == other.m_name) && (m_type == other.m_type);
    145 }
    146 
    147 bool StructMember::operator!= (const StructMember& other) const
    148 {
    149 	return !(*this == other);
    150 }
    151 
    152 // StructType implementation.
    153 
    154 void StructType::addMember (const char* name, const VarType& type)
    155 {
    156 	m_members.push_back(StructMember(name, type));
    157 }
    158 
    159 bool StructType::operator== (const StructType& other) const
    160 {
    161 	return (m_typeName == other.m_typeName) && (m_members == other.m_members);
    162 }
    163 
    164 bool StructType::operator!= (const StructType& other) const
    165 {
    166 	return !(*this == other);
    167 }
    168 
    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 
    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 
    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 
    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 
    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 
    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 
    242 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 
    251 bool Layout::operator!= (const Layout& other) const
    252 {
    253 	return !(*this == other);
    254 }
    255 
    256 // VariableDeclaration Implementation
    257 
    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 
    268 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 
    278 bool VariableDeclaration::operator!= (const VariableDeclaration& other) const
    279 {
    280 	return !(*this == other);
    281 }
    282 
    283 // InterfaceBlock Implementation
    284 
    285 InterfaceBlock::InterfaceBlock (void)
    286 	: layout						(Layout())
    287 	, storage						(glu::STORAGE_LAST)
    288 	, memoryAccessQualifierFlags	(0)
    289 {
    290 }
    291 
    292 // Declaration utilties.
    293 
    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 
    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 
    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 
    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 
    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 
    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