blob: 407d86d27921daab78dd2707427e726d84b8af2d [file] [log] [blame]
#ifndef _GLUVARTYPE_HPP
#define _GLUVARTYPE_HPP
/*-------------------------------------------------------------------------
* drawElements Quality Program OpenGL ES Utilities
* ------------------------------------------------
*
* 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 Shader variable type.
*//*--------------------------------------------------------------------*/
#include "tcuDefs.hpp"
#include "gluShaderUtil.hpp"
#include <vector>
#include <string>
#include <ostream>
namespace glu
{
class StructType;
/*--------------------------------------------------------------------*//*!
* \brief Shader variable type.
*
* Variable type represents data type. No storage qualifiers are supported
* since they are associated to a declaration, not to the variable type.
*
* \note Structs are handled using struct pointers since it is often desirable
* to maintain unique list of struct declarations.
*//*--------------------------------------------------------------------*/
class VarType
{
public:
VarType(void);
VarType(const VarType &other);
VarType(DataType basicType, Precision precision); //!< Basic type constructor.
VarType(const VarType &elementType, int arraySize); //!< Array type constructor.
explicit VarType(const StructType *structPtr); //!< Struct type constructor.
~VarType(void);
bool isBasicType(void) const
{
return m_type == VARTYPE_BASIC;
}
bool isArrayType(void) const
{
return m_type == VARTYPE_ARRAY;
}
bool isStructType(void) const
{
return m_type == VARTYPE_STRUCT;
}
DataType getBasicType(void) const
{
DE_ASSERT(isBasicType());
return m_data.basic.type;
}
Precision getPrecision(void) const
{
DE_ASSERT(isBasicType());
return m_data.basic.precision;
}
const VarType &getElementType(void) const
{
DE_ASSERT(isArrayType());
return *m_data.array.elementType;
}
int getArraySize(void) const
{
DE_ASSERT(isArrayType());
return m_data.array.size;
}
const StructType *getStructPtr(void) const
{
DE_ASSERT(isStructType());
return m_data.structPtr;
}
int getScalarSize(void) const;
VarType &operator=(const VarType &other);
bool operator==(const VarType &other) const;
bool operator!=(const VarType &other) const;
enum
{
UNSIZED_ARRAY = -1 //!< Array length for unsized arrays.
};
private:
enum Type
{
VARTYPE_BASIC,
VARTYPE_ARRAY,
VARTYPE_STRUCT,
VARTYPE_LAST
};
Type m_type;
union Data
{
// TYPE_BASIC
struct
{
DataType type;
Precision precision;
} basic;
// TYPE_ARRAY
struct
{
VarType *elementType;
int size;
} array;
// TYPE_STRUCT
const StructType *structPtr;
Data(void)
{
array.elementType = DE_NULL;
array.size = 0;
}
} m_data;
} DE_WARN_UNUSED_TYPE;
template <typename T>
inline VarType varTypeOf(Precision prec = PRECISION_LAST)
{
return VarType(dataTypeOf<T>(), prec);
}
class StructMember
{
public:
StructMember(const char *name, const VarType &type) : m_name(name), m_type(type)
{
}
StructMember(void)
{
}
const char *getName(void) const
{
return m_name.c_str();
}
const VarType &getType(void) const
{
return m_type;
}
bool operator==(const StructMember &other) const;
bool operator!=(const StructMember &other) const;
private:
std::string m_name;
VarType m_type;
} DE_WARN_UNUSED_TYPE;
class StructType
{
public:
typedef std::vector<StructMember>::iterator Iterator;
typedef std::vector<StructMember>::const_iterator ConstIterator;
StructType(const char *typeName) : m_typeName(typeName)
{
}
~StructType(void)
{
}
bool hasTypeName(void) const
{
return !m_typeName.empty();
}
const char *getTypeName(void) const
{
return hasTypeName() ? m_typeName.c_str() : DE_NULL;
}
void addMember(const char *name, const VarType &type);
int getNumMembers(void) const
{
return (int)m_members.size();
}
const StructMember &getMember(int ndx) const
{
return m_members[ndx];
}
inline Iterator begin(void)
{
return m_members.begin();
}
inline ConstIterator begin(void) const
{
return m_members.begin();
}
inline Iterator end(void)
{
return m_members.end();
}
inline ConstIterator end(void) const
{
return m_members.end();
}
bool operator==(const StructType &other) const;
bool operator!=(const StructType &other) const;
private:
std::string m_typeName;
std::vector<StructMember> m_members;
} DE_WARN_UNUSED_TYPE;
enum Storage
{
STORAGE_IN = 0,
STORAGE_OUT,
STORAGE_CONST,
STORAGE_UNIFORM,
STORAGE_BUFFER,
STORAGE_PATCH_IN,
STORAGE_PATCH_OUT,
STORAGE_LAST
};
const char *getStorageName(Storage storage);
enum Interpolation
{
INTERPOLATION_SMOOTH = 0,
INTERPOLATION_FLAT,
INTERPOLATION_CENTROID,
INTERPOLATION_LAST
};
const char *getInterpolationName(Interpolation interpolation);
enum FormatLayout
{
FORMATLAYOUT_RGBA32F = 0,
FORMATLAYOUT_RGBA16F,
FORMATLAYOUT_R32F,
FORMATLAYOUT_RGBA8,
FORMATLAYOUT_RGBA8_SNORM,
FORMATLAYOUT_RGBA32I,
FORMATLAYOUT_RGBA16I,
FORMATLAYOUT_RGBA8I,
FORMATLAYOUT_R32I,
FORMATLAYOUT_RGBA32UI,
FORMATLAYOUT_RGBA16UI,
FORMATLAYOUT_RGBA8UI,
FORMATLAYOUT_R32UI,
FORMATLAYOUT_LAST
};
const char *getFormatLayoutName(FormatLayout layout);
enum MemoryAccessQualifier
{
MEMORYACCESSQUALIFIER_COHERENT_BIT = 0x01,
MEMORYACCESSQUALIFIER_VOLATILE_BIT = 0x02,
MEMORYACCESSQUALIFIER_RESTRICT_BIT = 0x04,
MEMORYACCESSQUALIFIER_READONLY_BIT = 0x08,
MEMORYACCESSQUALIFIER_WRITEONLY_BIT = 0x10,
MEMORYACCESSQUALIFIER_MASK = (MEMORYACCESSQUALIFIER_WRITEONLY_BIT << 1) - 1
};
const char *getMemoryAccessQualifierName(MemoryAccessQualifier qualifier);
enum MatrixOrder
{
MATRIXORDER_COLUMN_MAJOR = 0,
MATRIXORDER_ROW_MAJOR,
MATRIXORDER_LAST
};
const char *getMatrixOrderName(MatrixOrder qualifier);
// Declaration utilities.
struct Layout
{
Layout(int location_ = -1, int binding_ = -1, int offset_ = -1, FormatLayout format_ = FORMATLAYOUT_LAST,
MatrixOrder matrixOrder_ = MATRIXORDER_LAST);
bool operator==(const Layout &other) const;
bool operator!=(const Layout &other) const;
int location;
int binding;
int offset;
FormatLayout format;
MatrixOrder matrixOrder;
} DE_WARN_UNUSED_TYPE;
struct VariableDeclaration
{
VariableDeclaration(const VarType &varType_, const std::string &name_, Storage storage_ = STORAGE_LAST,
Interpolation interpolation_ = INTERPOLATION_LAST, const Layout &layout_ = Layout(),
uint32_t memoryAccessQualifierBits_ = 0);
bool operator==(const VariableDeclaration &other) const;
bool operator!=(const VariableDeclaration &other) const;
Layout layout;
Interpolation interpolation;
Storage storage;
VarType varType;
uint32_t memoryAccessQualifierBits;
std::string name;
} DE_WARN_UNUSED_TYPE;
struct InterfaceBlock
{
InterfaceBlock(void);
glu::Layout layout;
Storage storage;
int memoryAccessQualifierFlags;
std::string interfaceName;
std::string instanceName;
std::vector<glu::VariableDeclaration> variables;
std::vector<int> dimensions;
} DE_WARN_UNUSED_TYPE;
//! Internals for declare() utilities.
namespace decl
{
struct Indent
{
int level;
Indent(int level_) : level(level_)
{
}
};
struct DeclareStructTypePtr
{
DeclareStructTypePtr(const StructType *structPtr_, int indentLevel_)
: structPtr(structPtr_)
, indentLevel(indentLevel_)
{
}
const StructType *structPtr;
int indentLevel;
};
struct DeclareStructType
{
DeclareStructType(const StructType &structType_, int indentLevel_)
: structType(structType_)
, indentLevel(indentLevel_)
{
}
StructType structType;
int indentLevel;
};
struct DeclareVariable
{
DeclareVariable(const VarType &varType_, const std::string &name_, int indentLevel_)
: varType(varType_)
, name(name_)
, indentLevel(indentLevel_)
{
}
VarType varType;
std::string name;
int indentLevel;
};
std::ostream &operator<<(std::ostream &str, const Indent &indent);
std::ostream &operator<<(std::ostream &str, const DeclareStructTypePtr &decl);
std::ostream &operator<<(std::ostream &str, const DeclareStructType &decl);
std::ostream &operator<<(std::ostream &str, const DeclareVariable &decl);
} // namespace decl
inline decl::Indent indent(int indentLevel)
{
return decl::Indent(indentLevel);
}
inline decl::DeclareStructTypePtr declare(const StructType *structPtr, int indentLevel = 0)
{
return decl::DeclareStructTypePtr(structPtr, indentLevel);
}
inline decl::DeclareStructType declare(const StructType &structType, int indentLevel = 0)
{
return decl::DeclareStructType(structType, indentLevel);
}
inline decl::DeclareVariable declare(const VarType &varType, const std::string &name, int indentLevel = 0)
{
return decl::DeclareVariable(varType, name, indentLevel);
}
std::ostream &operator<<(std::ostream &str, const Layout &decl);
std::ostream &operator<<(std::ostream &str, const VariableDeclaration &decl);
} // namespace glu
#endif // _GLUVARTYPE_HPP