ANGLE: Upgrade to 2.1~abce76206141

Upgrade to address issues discovered since the last upgrade.

Patch notes:
0000-General-fixes-for-ANGLE-2.1.patch
  added removal of the unused third-party tracing functions

0003-Fix-compilation-with-MinGW-gcc-64-bit.patch
  removed as it is no longer needed

0011-ANGLE-Fix-compilation-error-on-MinGW-caused-by-trace.patch
  removed as it is no longer needed

0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch
  now supports MinGW 64-bit

[ChangeLog][Third-party libraries] ANGLE updated to 2.1~f8602ad91e4f

Task-number: QTBUG-40649
Task-number: QTBUG-40658
Task-number: QTBUG-41031
Task-number: QTBUG-41081
Task-number: QTBUG-41308
Task-number: QTBUG-41563
Change-Id: I9f776c8d5cb94ddb12d608a8d5630bfc54437bea
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
bb10
Andrew Knight 2014-09-25 13:22:55 +03:00
parent 04d3a89e20
commit 311157c3c6
279 changed files with 18452 additions and 17067 deletions

View File

@ -20,6 +20,7 @@ Intel Corporation
Mozilla Corporation
Turbulenz
Klarälvdalens Datakonsult AB
Microsoft Open Technologies, Inc.
Jacek Caban
Mark Callow

View File

@ -59,6 +59,7 @@ Intel Corporation
Jin Yang
Andy Chen
Josh Triplett
Sudarsana Nagineni
Klarälvdalens Datakonsult AB
Milian Wolff
@ -78,3 +79,6 @@ Ulrik Persson (ddefrostt)
Mark Banner (standard8mbp)
David Kilzer
Microsoft Open Technologies, Inc.
Cooper Partin
Austin Kinross

View File

@ -23,9 +23,10 @@
#define COMPILER_EXPORT
#endif
#include "KHR/khrplatform.h"
#include <stddef.h>
#include "KHR/khrplatform.h"
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
@ -37,13 +38,17 @@ namespace sh
typedef unsigned int GLenum;
}
// Must be included after GLenum proxy typedef
// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
#include "ShaderVars.h"
#ifdef __cplusplus
extern "C" {
#endif
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 128
#define ANGLE_SH_VERSION 130
typedef enum {
SH_GLES2_SPEC = 0x8B40,
@ -100,14 +105,9 @@ typedef enum {
SH_NAME_MAX_LENGTH = 0x6001,
SH_HASHED_NAME_MAX_LENGTH = 0x6002,
SH_HASHED_NAMES_COUNT = 0x6003,
SH_ACTIVE_UNIFORMS_ARRAY = 0x6004,
SH_SHADER_VERSION = 0x6005,
SH_ACTIVE_INTERFACE_BLOCKS_ARRAY = 0x6006,
SH_ACTIVE_OUTPUT_VARIABLES_ARRAY = 0x6007,
SH_ACTIVE_ATTRIBUTES_ARRAY = 0x6008,
SH_ACTIVE_VARYINGS_ARRAY = 0x6009,
SH_RESOURCES_STRING_LENGTH = 0x600A,
SH_OUTPUT_TYPE = 0x600B
SH_SHADER_VERSION = 0x6004,
SH_RESOURCES_STRING_LENGTH = 0x6005,
SH_OUTPUT_TYPE = 0x6006
} ShShaderInfo;
// Compile options.
@ -189,6 +189,11 @@ typedef enum {
// This flag scalarizes vec/ivec/bvec/mat constructor args.
// It is intended as a workaround for Linux/Mac driver bugs.
SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = 0x40000,
// This flag overwrites a struct name with a unique prefix.
// It is intended as a workaround for drivers that do not handle
// struct scopes correctly, including all Mac drivers and Linux AMD.
SH_REGENERATE_STRUCT_NAMES = 0x80000,
} ShCompileOptions;
// Defines alternate strategies for implementing array index clamping.
@ -453,17 +458,17 @@ COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle,
char* name,
char* hashedName);
// Returns a parameter from a compiled shader.
// Shader variable inspection.
// Returns a pointer to a list of variables of the designated type.
// (See ShaderVars.h for type definitions, included above)
// Returns NULL on failure.
// Parameters:
// handle: Specifies the compiler
// pname: Specifies the parameter to query.
// The following parameters are defined:
// SH_ACTIVE_UNIFORMS_ARRAY: an STL vector of active uniforms. Valid only for
// HLSL output.
// params: Requested parameter
COMPILER_EXPORT void ShGetInfoPointer(const ShHandle handle,
ShShaderInfo pname,
void** params);
COMPILER_EXPORT const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle);
COMPILER_EXPORT const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle);
COMPILER_EXPORT const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle);
COMPILER_EXPORT const std::vector<sh::Attribute> *ShGetOutputVariables(const ShHandle handle);
COMPILER_EXPORT const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle);
typedef struct
{

View File

@ -0,0 +1,123 @@
//
// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ShaderVars.h:
// Types to represent GL variables (varyings, uniforms, etc)
//
#ifndef _COMPILER_INTERFACE_VARIABLES_
#define _COMPILER_INTERFACE_VARIABLES_
#include <string>
#include <vector>
#include <algorithm>
// Assume ShaderLang.h is included before ShaderVars.h, for sh::GLenum
// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
namespace sh
{
// Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec
enum InterpolationType
{
INTERPOLATION_SMOOTH,
INTERPOLATION_CENTROID,
INTERPOLATION_FLAT
};
// Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
enum BlockLayoutType
{
BLOCKLAYOUT_STANDARD,
BLOCKLAYOUT_PACKED,
BLOCKLAYOUT_SHARED
};
// Base class for all variables defined in shaders, including Varyings, Uniforms, etc
// Note: we must override the copy constructor and assignment operator so we can
// work around excessive GCC binary bloating:
// See https://code.google.com/p/angleproject/issues/detail?id=697
struct COMPILER_EXPORT ShaderVariable
{
ShaderVariable();
ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
~ShaderVariable();
ShaderVariable(const ShaderVariable &other);
ShaderVariable &operator=(const ShaderVariable &other);
bool isArray() const { return arraySize > 0; }
unsigned int elementCount() const { return std::max(1u, arraySize); }
bool isStruct() const { return !fields.empty(); }
GLenum type;
GLenum precision;
std::string name;
std::string mappedName;
unsigned int arraySize;
bool staticUse;
std::vector<ShaderVariable> fields;
std::string structName;
};
struct COMPILER_EXPORT Uniform : public ShaderVariable
{
Uniform();
~Uniform();
Uniform(const Uniform &other);
Uniform &operator=(const Uniform &other);
};
struct COMPILER_EXPORT Attribute : public ShaderVariable
{
Attribute();
~Attribute();
Attribute(const Attribute &other);
Attribute &operator=(const Attribute &other);
int location;
};
struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
{
InterfaceBlockField();
~InterfaceBlockField();
InterfaceBlockField(const InterfaceBlockField &other);
InterfaceBlockField &operator=(const InterfaceBlockField &other);
bool isRowMajorLayout;
};
struct COMPILER_EXPORT Varying : public ShaderVariable
{
Varying();
~Varying();
Varying(const Varying &other);
Varying &operator=(const Varying &other);
InterpolationType interpolation;
bool isInvariant;
};
struct COMPILER_EXPORT InterfaceBlock
{
InterfaceBlock();
~InterfaceBlock();
InterfaceBlock(const InterfaceBlock &other);
InterfaceBlock &operator=(const InterfaceBlock &other);
std::string name;
std::string mappedName;
std::string instanceName;
unsigned int arraySize;
BlockLayoutType layout;
bool isRowMajorLayout;
bool staticUse;
std::vector<InterfaceBlockField> fields;
};
}
#endif // _COMPILER_INTERFACE_VARIABLES_

View File

@ -10,9 +10,6 @@
#ifndef ANGLE_GL_H_
#define ANGLE_GL_H_
#define GL_GLEXT_PROTOTYPES
#define GL_APICALL
#include "GLES2/gl2.h"
#include "GLES2/gl2ext.h"
#include "GLES3/gl3.h"

View File

@ -7,6 +7,6 @@
// This is a default commit hash header, when git is not available.
//
#define ANGLE_COMMIT_HASH "07d49ef5350a"
#define ANGLE_COMMIT_HASH "abce76206141"
#define ANGLE_COMMIT_HASH_SIZE 12
#define ANGLE_COMMIT_DATE "2014-07-25 16:01:42 +0000"
#define ANGLE_COMMIT_DATE "2014-09-23 19:37:05 +0000"

View File

@ -12,11 +12,11 @@
#ifndef COMMON_REFCOUNTOBJECT_H_
#define COMMON_REFCOUNTOBJECT_H_
#include <cstddef>
#include "common/debug.h"
#include "angle_gl.h"
#include "common/debug.h"
#include <cstddef>
class RefCountObject
{

View File

@ -0,0 +1,37 @@
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "common/angleutils.h"
#include <vector>
std::string FormatString(const char *fmt, va_list vararg)
{
static std::vector<char> buffer(512);
// Attempt to just print to the current buffer
int len = vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
if (len < 0 || static_cast<size_t>(len) >= buffer.size())
{
// Buffer was not large enough, calculate the required size and resize the buffer
len = vsnprintf(NULL, 0, fmt, vararg);
buffer.resize(len + 1);
// Print again
vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
}
return std::string(buffer.data(), len);
}
std::string FormatString(const char *fmt, ...)
{
va_list vararg;
va_start(vararg, fmt);
std::string result = FormatString(fmt, vararg);
va_end(vararg);
return result;
}

View File

@ -16,6 +16,7 @@
#include <string>
#include <set>
#include <sstream>
#include <cstdarg>
// A macro to disallow the copy constructor and operator= functions
// This must be used in the private: declarations for a class
@ -23,8 +24,8 @@
TypeName(const TypeName&); \
void operator=(const TypeName&)
template <typename T, unsigned int N>
inline unsigned int ArraySize(T(&)[N])
template <typename T, size_t N>
inline size_t ArraySize(T(&)[N])
{
return N;
}
@ -131,6 +132,9 @@ inline std::string Str(int i)
return strstr.str();
}
std::string FormatString(const char *fmt, va_list vararg);
std::string FormatString(const char *fmt, ...);
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif

View File

@ -8,7 +8,6 @@
//
#include "common/blocklayout.h"
#include "common/shadervars.h"
#include "common/mathutil.h"
#include "common/utilities.h"
@ -20,46 +19,7 @@ BlockLayoutEncoder::BlockLayoutEncoder()
{
}
void BlockLayoutEncoder::encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields)
{
for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
const InterfaceBlockField &variable = fields[fieldIndex];
if (variable.fields.size() > 0)
{
const unsigned int elementCount = std::max(1u, variable.arraySize);
for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
{
enterAggregateType();
encodeInterfaceBlockFields(variable.fields);
exitAggregateType();
}
}
else
{
encodeInterfaceBlockField(variable);
}
}
}
BlockMemberInfo BlockLayoutEncoder::encodeInterfaceBlockField(const InterfaceBlockField &field)
{
int arrayStride;
int matrixStride;
ASSERT(field.fields.empty());
getBlockLayoutInfo(field.type, field.arraySize, field.isRowMajorMatrix, &arrayStride, &matrixStride);
const BlockMemberInfo memberInfo(mCurrentOffset * BytesPerComponent, arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, field.isRowMajorMatrix);
advanceOffset(field.type, field.arraySize, field.isRowMajorMatrix, arrayStride, matrixStride);
return memberInfo;
}
void BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
{
int arrayStride;
int matrixStride;
@ -69,6 +29,8 @@ void BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool is
const BlockMemberInfo memberInfo(mCurrentOffset * BytesPerComponent, arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, isRowMajorMatrix);
advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride);
return memberInfo;
}
void BlockLayoutEncoder::nextRegister()

View File

@ -10,10 +10,11 @@
#ifndef COMMON_BLOCKLAYOUT_H_
#define COMMON_BLOCKLAYOUT_H_
#include <cstddef>
#include <vector>
#include "angle_gl.h"
#include <GLSLANG/ShaderLang.h>
#include <cstddef>
namespace sh
{
@ -48,9 +49,7 @@ class BlockLayoutEncoder
public:
BlockLayoutEncoder();
void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields);
BlockMemberInfo encodeInterfaceBlockField(const InterfaceBlockField &field);
void encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
BlockMemberInfo encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
size_t getCurrentRegister() const { return mCurrentOffset / ComponentsPerRegister; }

View File

@ -8,6 +8,7 @@
#include "common/debug.h"
#include "common/platform.h"
#include "common/angleutils.h"
#include <stdarg.h>
#include <vector>
@ -25,22 +26,7 @@ typedef void (*PerfOutputFunction)(unsigned int, const wchar_t*);
static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
{
#if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE)
static std::vector<char> asciiMessageBuffer(512);
// Attempt to just print to the current buffer
int len = vsnprintf(&asciiMessageBuffer[0], asciiMessageBuffer.size(), format, vararg);
if (len < 0 || static_cast<size_t>(len) >= asciiMessageBuffer.size())
{
// Buffer was not large enough, calculate the required size and resize the buffer
len = vsnprintf(NULL, 0, format, vararg);
asciiMessageBuffer.resize(len + 1);
// Print again
vsnprintf(&asciiMessageBuffer[0], asciiMessageBuffer.size(), format, vararg);
}
// NULL terminate the buffer to be safe
asciiMessageBuffer[len] = '\0';
std::string formattedMessage = FormatString(format, vararg);
#endif
#if defined(ANGLE_ENABLE_PERF)
@ -48,12 +34,12 @@ static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const c
{
// The perf function only accepts wide strings, widen the ascii message
static std::wstring wideMessage;
if (wideMessage.capacity() < asciiMessageBuffer.size())
if (wideMessage.capacity() < formattedMessage.length())
{
wideMessage.reserve(asciiMessageBuffer.size());
wideMessage.reserve(formattedMessage.size());
}
wideMessage.assign(asciiMessageBuffer.begin(), asciiMessageBuffer.begin() + len);
wideMessage.assign(formattedMessage.begin(), formattedMessage.end());
perfFunc(0, wideMessage.c_str());
}
@ -70,7 +56,7 @@ static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const c
static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
if (file)
{
file.write(&asciiMessageBuffer[0], len);
file.write(formattedMessage.c_str(), formattedMessage.length());
file.flush();
}

View File

@ -91,6 +91,10 @@ namespace gl
// A macro to indicate unimplemented functionality
#if defined (ANGLE_TEST_CONFIG)
#define NOASSERT_UNIMPLEMENTED 1
#endif
// Define NOASSERT_UNIMPLEMENTED to non zero to skip the assert fail in the unimplemented checks
// This will allow us to test with some automated test suites (eg dEQP) without crashing
#ifndef NOASSERT_UNIMPLEMENTED

View File

@ -1,49 +0,0 @@
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "common/event_tracer.h"
namespace gl
{
GetCategoryEnabledFlagFunc g_getCategoryEnabledFlag;
AddTraceEventFunc g_addTraceEvent;
} // namespace gl
extern "C" {
void TRACE_ENTRY SetTraceFunctionPointers(GetCategoryEnabledFlagFunc getCategoryEnabledFlag,
AddTraceEventFunc addTraceEvent)
{
gl::g_getCategoryEnabledFlag = getCategoryEnabledFlag;
gl::g_addTraceEvent = addTraceEvent;
}
} // extern "C"
namespace gl
{
const unsigned char* TraceGetTraceCategoryEnabledFlag(const char* name)
{
if (g_getCategoryEnabledFlag)
{
return g_getCategoryEnabledFlag(name);
}
static unsigned char disabled = 0;
return &disabled;
}
void TraceAddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, unsigned long long id,
int numArgs, const char** argNames, const unsigned char* argTypes,
const unsigned long long* argValues, unsigned char flags)
{
if (g_addTraceEvent)
{
g_addTraceEvent(phase, categoryGroupEnabled, name, id, numArgs, argNames, argTypes, argValues, flags);
}
}
} // namespace gl

View File

@ -1,43 +0,0 @@
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMMON_EVENT_TRACER_H_
#define COMMON_EVENT_TRACER_H_
#include "common/platform.h"
#if !defined(TRACE_ENTRY)
# ifdef ANGLE_PLATFORM_WINDOWS
# define TRACE_ENTRY __stdcall
# else
# define TRACE_ENTRY
# endif // ANGLE_PLATFORM_WINDOWS
#endif //TRACE_ENTRY
extern "C" {
typedef const unsigned char* (*GetCategoryEnabledFlagFunc)(const char* name);
typedef void (*AddTraceEventFunc)(char phase, const unsigned char* categoryGroupEnabled, const char* name,
unsigned long long id, int numArgs, const char** argNames,
const unsigned char* argTypes, const unsigned long long* argValues,
unsigned char flags);
// extern "C" so that it has a reasonable name for GetProcAddress.
void TRACE_ENTRY SetTraceFunctionPointers(GetCategoryEnabledFlagFunc get_category_enabled_flag,
AddTraceEventFunc add_trace_event_func);
}
namespace gl
{
const unsigned char* TraceGetTraceCategoryEnabledFlag(const char* name);
void TraceAddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, unsigned long long id,
int numArgs, const char** argNames, const unsigned char* argTypes,
const unsigned long long* argValues, unsigned char flags);
}
#endif // COMMON_EVENT_TRACER_H_

View File

@ -7,6 +7,7 @@
// mathutil.cpp: Math and bit manipulation functions.
#include "common/mathutil.h"
#include <algorithm>
#include <math.h>

View File

@ -505,21 +505,33 @@ inline unsigned int averageFloat10(unsigned int a, unsigned int b)
namespace rx
{
template <typename T>
struct Range
{
Range() {}
Range(int lo, int hi) : start(lo), end(hi) { ASSERT(lo <= hi); }
Range(T lo, T hi) : start(lo), end(hi) { ASSERT(lo <= hi); }
int start;
int end;
T start;
T end;
T length() const { return end - start; }
};
typedef Range<int> RangeI;
typedef Range<unsigned int> RangeUI;
template <typename T>
T roundUp(const T value, const T alignment)
{
return value + alignment - 1 - (value - 1) % alignment;
}
inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
{
unsigned int divided = value / divisor;
return (divided + ((value % divisor == 0) ? 0 : 1));
}
template <class T>
inline bool IsUnsignedAdditionSafe(T lhs, T rhs)
{

View File

@ -52,6 +52,9 @@
# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF)
# include <d3d9.h>
# if !defined(COMPILER_IMPLEMENTATION)
# include <d3dcompiler.h>
# endif
# endif
# if defined(ANGLE_ENABLE_D3D11)
@ -61,16 +64,25 @@
# include <dxgi.h>
# if _MSC_VER >= 1700
# include <dxgi1_2.h>
# endif
# if !defined(COMPILER_IMPLEMENTATION)
# include <d3dcompiler.h>
# endif
# if defined(__MINGW32__)
typedef enum D3D11_MAP_FLAG
{
D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L
} D3D11_MAP_FLAG;
typedef struct D3D11_QUERY_DATA_SO_STATISTICS
{
UINT64 NumPrimitivesWritten;
UINT64 PrimitivesStorageNeeded;
} D3D11_QUERY_DATA_SO_STATISTICS;
# endif
# endif
# undef near
# undef far
# undef NEAR
# define NEAR
# undef FAR
# define FAR
#endif
#endif // COMMON_PLATFORM_H_

View File

@ -1,157 +0,0 @@
//
// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// shadervars.h:
// Types to represent GL variables (varyings, uniforms, etc)
//
#ifndef COMMON_SHADERVARIABLE_H_
#define COMMON_SHADERVARIABLE_H_
#include <string>
#include <vector>
#include <algorithm>
#include "GLSLANG/ShaderLang.h"
namespace sh
{
// Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec
enum InterpolationType
{
INTERPOLATION_SMOOTH,
INTERPOLATION_CENTROID,
INTERPOLATION_FLAT
};
// Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
enum BlockLayoutType
{
BLOCKLAYOUT_STANDARD,
BLOCKLAYOUT_PACKED,
BLOCKLAYOUT_SHARED
};
// Base class for all variables defined in shaders, including Varyings, Uniforms, etc
struct ShaderVariable
{
ShaderVariable()
: type(0),
precision(0),
arraySize(0),
staticUse(false)
{}
ShaderVariable(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn)
: type(typeIn),
precision(precisionIn),
name(nameIn),
arraySize(arraySizeIn),
staticUse(false)
{}
bool isArray() const { return arraySize > 0; }
unsigned int elementCount() const { return std::max(1u, arraySize); }
GLenum type;
GLenum precision;
std::string name;
std::string mappedName;
unsigned int arraySize;
bool staticUse;
};
struct Uniform : public ShaderVariable
{
Uniform()
{}
Uniform(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn)
: ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn)
{}
bool isStruct() const { return !fields.empty(); }
std::vector<Uniform> fields;
};
struct Attribute : public ShaderVariable
{
Attribute()
: location(-1)
{}
Attribute(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, int locationIn)
: ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
location(locationIn)
{}
int location;
};
struct InterfaceBlockField : public ShaderVariable
{
InterfaceBlockField()
: isRowMajorMatrix(false)
{}
InterfaceBlockField(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, bool isRowMajorMatrix)
: ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
isRowMajorMatrix(isRowMajorMatrix)
{}
bool isStruct() const { return !fields.empty(); }
bool isRowMajorMatrix;
std::vector<InterfaceBlockField> fields;
};
struct Varying : public ShaderVariable
{
Varying()
: interpolation(INTERPOLATION_SMOOTH)
{}
Varying(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, InterpolationType interpolationIn)
: ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
interpolation(interpolationIn)
{}
bool isStruct() const { return !fields.empty(); }
InterpolationType interpolation;
std::vector<Varying> fields;
std::string structName;
};
struct InterfaceBlock
{
InterfaceBlock()
: arraySize(0),
layout(BLOCKLAYOUT_PACKED),
isRowMajorLayout(false),
staticUse(false)
{}
InterfaceBlock(const char *name, unsigned int arraySize)
: name(name),
arraySize(arraySize),
layout(BLOCKLAYOUT_SHARED),
isRowMajorLayout(false),
staticUse(false)
{}
std::string name;
std::string mappedName;
unsigned int arraySize;
BlockLayoutType layout;
bool isRowMajorLayout;
bool staticUse;
std::vector<InterfaceBlockField> fields;
};
}
#endif // COMMON_SHADERVARIABLE_H_

View File

@ -69,40 +69,9 @@ enum TBasicType
EbtStruct,
EbtInterfaceBlock,
EbtAddress, // should be deprecated??
EbtInvariant // used as a type when qualifying a previously declared variable as being invariant
};
inline const char* getBasicString(TBasicType t)
{
switch (t)
{
case EbtVoid: return "void"; break;
case EbtFloat: return "float"; break;
case EbtInt: return "int"; break;
case EbtUInt: return "uint"; break;
case EbtBool: return "bool"; break;
case EbtSampler2D: return "sampler2D"; break;
case EbtSampler3D: return "sampler3D"; break;
case EbtSamplerCube: return "samplerCube"; break;
case EbtSamplerExternalOES: return "samplerExternalOES"; break;
case EbtSampler2DRect: return "sampler2DRect"; break;
case EbtSampler2DArray: return "sampler2DArray"; break;
case EbtISampler2D: return "isampler2D"; break;
case EbtISampler3D: return "isampler3D"; break;
case EbtISamplerCube: return "isamplerCube"; break;
case EbtISampler2DArray: return "isampler2DArray"; break;
case EbtUSampler2D: return "usampler2D"; break;
case EbtUSampler3D: return "usampler3D"; break;
case EbtUSamplerCube: return "usamplerCube"; break;
case EbtUSampler2DArray: return "usampler2DArray"; break;
case EbtSampler2DShadow: return "sampler2DShadow"; break;
case EbtSamplerCubeShadow: return "samplerCubeShadow"; break;
case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break;
case EbtStruct: return "structure"; break;
case EbtInterfaceBlock: return "interface block"; break;
default: return "unknown type";
}
}
const char* getBasicString(TBasicType t);
inline bool IsSampler(TBasicType type)
{

View File

@ -8,7 +8,7 @@
#define COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
//
// This class decides which built-in functions need to be replaced with the

View File

@ -12,6 +12,7 @@
#include "compiler/translator/InitializeParseContext.h"
#include "compiler/translator/InitializeVariables.h"
#include "compiler/translator/ParseContext.h"
#include "compiler/translator/RegenerateStructNames.h"
#include "compiler/translator/RenameFunction.h"
#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
#include "compiler/translator/UnfoldShortCircuitAST.h"
@ -257,10 +258,17 @@ bool TCompiler::compile(const char* const shaderStrings[],
if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS))
{
ScalarizeVecAndMatConstructorArgs scalarizer;
ScalarizeVecAndMatConstructorArgs scalarizer(
shaderType, fragmentPrecisionHigh);
root->traverse(&scalarizer);
}
if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES))
{
RegenerateStructNames gen(symbolTable, shaderVersion);
root->traverse(&gen);
}
if (success && (compileOptions & SH_INTERMEDIATE_TREE))
intermediate.outputTree(root);
@ -494,18 +502,18 @@ bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
void TCompiler::collectVariables(TIntermNode* root)
{
CollectVariables collect(&attributes,
&outputVariables,
&uniforms,
&varyings,
&interfaceBlocks,
hashFunction);
sh::CollectVariables collect(&attributes,
&outputVariables,
&uniforms,
&varyings,
&interfaceBlocks,
hashFunction);
root->traverse(&collect);
// For backwards compatiblity with ShGetVariableInfo, expand struct
// uniforms and varyings into separate variables for each field.
ExpandVariables(uniforms, &expandedUniforms);
ExpandVariables(varyings, &expandedVaryings);
sh::ExpandVariables(uniforms, &expandedUniforms);
sh::ExpandVariables(varyings, &expandedVaryings);
}
bool TCompiler::enforcePackingRestrictions()

View File

@ -71,9 +71,9 @@ class TCompiler : public TShHandleBase
const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
const std::vector<sh::Uniform> &getExpandedUniforms() const { return expandedUniforms; }
const std::vector<sh::ShaderVariable> &getExpandedUniforms() const { return expandedUniforms; }
const std::vector<sh::Varying> &getVaryings() const { return varyings; }
const std::vector<sh::Varying> &getExpandedVaryings() const { return expandedVaryings; }
const std::vector<sh::ShaderVariable> &getExpandedVaryings() const { return expandedVaryings; }
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
ShHashFunction64 getHashFunction() const { return hashFunction; }
@ -83,6 +83,9 @@ class TCompiler : public TShHandleBase
ShShaderOutput getOutputType() const { return outputType; }
std::string getBuiltInResourcesString() const { return builtInResourcesString; }
// Get the resources set by InitBuiltInSymbolTable
const ShBuiltInResources& getResources() const;
protected:
sh::GLenum getShaderType() const { return shaderType; }
// Initialize symbol-table with built-in symbols.
@ -128,8 +131,6 @@ class TCompiler : public TShHandleBase
bool limitExpressionComplexity(TIntermNode* root);
// Get built-in extensions with default behavior.
const TExtensionBehavior& getExtensionBehavior() const;
// Get the resources set by InitBuiltInSymbolTable
const ShBuiltInResources& getResources() const;
const ArrayBoundsClamper& getArrayBoundsClamper() const;
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
@ -138,9 +139,9 @@ class TCompiler : public TShHandleBase
std::vector<sh::Attribute> attributes;
std::vector<sh::Attribute> outputVariables;
std::vector<sh::Uniform> uniforms;
std::vector<sh::Uniform> expandedUniforms;
std::vector<sh::ShaderVariable> expandedUniforms;
std::vector<sh::Varying> varyings;
std::vector<sh::Varying> expandedVaryings;
std::vector<sh::ShaderVariable> expandedVaryings;
std::vector<sh::InterfaceBlock> interfaceBlocks;
private:

View File

@ -8,7 +8,7 @@
#define COMPILER_DETECT_RECURSION_H_
#include <limits.h>
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/VariableInfo.h"
class TInfoSink;

View File

@ -11,7 +11,7 @@
#ifndef COMPILER_DETECTDISCONTINUITY_H_
#define COMPILER_DETECTDISCONTINUITY_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
namespace sh
{

View File

@ -7,7 +7,7 @@
#ifndef COMPILER_FLAGSTD140STRUCTS_H_
#define COMPILER_FLAGSTD140STRUCTS_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
namespace sh
{

View File

@ -9,7 +9,7 @@
#include <map>
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#define HASHED_NAME_PREFIX "webgl_"

View File

@ -12,7 +12,7 @@
#include "compiler/translator/Initialize.h"
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include "angle_gl.h"
void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable)

View File

@ -7,7 +7,7 @@
#ifndef COMPILER_INITIALIZE_VARIABLES_H_
#define COMPILER_INITIALIZE_VARIABLES_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
class InitializeVariables : public TIntermTraverser
{

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,772 @@
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
//
// Definition of the in-memory high-level intermediate representation
// of shaders. This is a tree that parser creates.
//
// Nodes in the tree are defined as a hierarchy of classes derived from
// TIntermNode. Each is a node in a tree. There is no preset branching factor;
// each node can have it's own type of list of children.
//
#ifndef COMPILER_TRANSLATOR_INTERMEDIATE_H_
#define COMPILER_TRANSLATOR_INTERMEDIATE_H_
#include "GLSLANG/ShaderLang.h"
#include <algorithm>
#include <queue>
#include "compiler/translator/Common.h"
#include "compiler/translator/Types.h"
#include "compiler/translator/ConstantUnion.h"
//
// Operators used by the high-level (parse tree) representation.
//
enum TOperator
{
EOpNull, // if in a node, should only mean a node is still being built
EOpSequence, // denotes a list of statements, or parameters, etc.
EOpFunctionCall,
EOpFunction, // For function definition
EOpParameters, // an aggregate listing the parameters to a function
EOpDeclaration,
EOpInvariantDeclaration, // Specialized declarations for attributing invariance
EOpPrototype,
//
// Unary operators
//
EOpNegative,
EOpLogicalNot,
EOpVectorLogicalNot,
EOpPostIncrement,
EOpPostDecrement,
EOpPreIncrement,
EOpPreDecrement,
//
// binary operations
//
EOpAdd,
EOpSub,
EOpMul,
EOpDiv,
EOpEqual,
EOpNotEqual,
EOpVectorEqual,
EOpVectorNotEqual,
EOpLessThan,
EOpGreaterThan,
EOpLessThanEqual,
EOpGreaterThanEqual,
EOpComma,
EOpVectorTimesScalar,
EOpVectorTimesMatrix,
EOpMatrixTimesVector,
EOpMatrixTimesScalar,
EOpLogicalOr,
EOpLogicalXor,
EOpLogicalAnd,
EOpIndexDirect,
EOpIndexIndirect,
EOpIndexDirectStruct,
EOpIndexDirectInterfaceBlock,
EOpVectorSwizzle,
//
// Built-in functions potentially mapped to operators
//
EOpRadians,
EOpDegrees,
EOpSin,
EOpCos,
EOpTan,
EOpAsin,
EOpAcos,
EOpAtan,
EOpPow,
EOpExp,
EOpLog,
EOpExp2,
EOpLog2,
EOpSqrt,
EOpInverseSqrt,
EOpAbs,
EOpSign,
EOpFloor,
EOpCeil,
EOpFract,
EOpMod,
EOpMin,
EOpMax,
EOpClamp,
EOpMix,
EOpStep,
EOpSmoothStep,
EOpLength,
EOpDistance,
EOpDot,
EOpCross,
EOpNormalize,
EOpFaceForward,
EOpReflect,
EOpRefract,
EOpDFdx, // Fragment only, OES_standard_derivatives extension
EOpDFdy, // Fragment only, OES_standard_derivatives extension
EOpFwidth, // Fragment only, OES_standard_derivatives extension
EOpMatrixTimesMatrix,
EOpAny,
EOpAll,
//
// Branch
//
EOpKill, // Fragment only
EOpReturn,
EOpBreak,
EOpContinue,
//
// Constructors
//
EOpConstructInt,
EOpConstructUInt,
EOpConstructBool,
EOpConstructFloat,
EOpConstructVec2,
EOpConstructVec3,
EOpConstructVec4,
EOpConstructBVec2,
EOpConstructBVec3,
EOpConstructBVec4,
EOpConstructIVec2,
EOpConstructIVec3,
EOpConstructIVec4,
EOpConstructUVec2,
EOpConstructUVec3,
EOpConstructUVec4,
EOpConstructMat2,
EOpConstructMat3,
EOpConstructMat4,
EOpConstructStruct,
//
// moves
//
EOpAssign,
EOpInitialize,
EOpAddAssign,
EOpSubAssign,
EOpMulAssign,
EOpVectorTimesMatrixAssign,
EOpVectorTimesScalarAssign,
EOpMatrixTimesScalarAssign,
EOpMatrixTimesMatrixAssign,
EOpDivAssign
};
class TIntermTraverser;
class TIntermAggregate;
class TIntermBinary;
class TIntermUnary;
class TIntermConstantUnion;
class TIntermSelection;
class TIntermTyped;
class TIntermSymbol;
class TIntermLoop;
class TInfoSink;
class TIntermRaw;
//
// Base class for the tree nodes
//
class TIntermNode
{
public:
POOL_ALLOCATOR_NEW_DELETE();
TIntermNode()
{
// TODO: Move this to TSourceLoc constructor
// after getting rid of TPublicType.
mLine.first_file = mLine.last_file = 0;
mLine.first_line = mLine.last_line = 0;
}
virtual ~TIntermNode() { }
const TSourceLoc &getLine() const { return mLine; }
void setLine(const TSourceLoc &l) { mLine = l; }
virtual void traverse(TIntermTraverser *) = 0;
virtual TIntermTyped *getAsTyped() { return 0; }
virtual TIntermConstantUnion *getAsConstantUnion() { return 0; }
virtual TIntermAggregate *getAsAggregate() { return 0; }
virtual TIntermBinary *getAsBinaryNode() { return 0; }
virtual TIntermUnary *getAsUnaryNode() { return 0; }
virtual TIntermSelection *getAsSelectionNode() { return 0; }
virtual TIntermSymbol *getAsSymbolNode() { return 0; }
virtual TIntermLoop *getAsLoopNode() { return 0; }
virtual TIntermRaw *getAsRawNode() { return 0; }
// Replace a child node. Return true if |original| is a child
// node and it is replaced; otherwise, return false.
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement) = 0;
// For traversing a tree in no particular order, but using
// heap memory.
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const = 0;
protected:
TSourceLoc mLine;
};
//
// This is just to help yacc.
//
struct TIntermNodePair
{
TIntermNode *node1;
TIntermNode *node2;
};
//
// Intermediate class for nodes that have a type.
//
class TIntermTyped : public TIntermNode
{
public:
TIntermTyped(const TType &t) : mType(t) { }
virtual TIntermTyped *getAsTyped() { return this; }
virtual bool hasSideEffects() const = 0;
void setType(const TType &t) { mType = t; }
const TType &getType() const { return mType; }
TType *getTypePointer() { return &mType; }
TBasicType getBasicType() const { return mType.getBasicType(); }
TQualifier getQualifier() const { return mType.getQualifier(); }
TPrecision getPrecision() const { return mType.getPrecision(); }
int getCols() const { return mType.getCols(); }
int getRows() const { return mType.getRows(); }
int getNominalSize() const { return mType.getNominalSize(); }
int getSecondarySize() const { return mType.getSecondarySize(); }
bool isInterfaceBlock() const { return mType.isInterfaceBlock(); }
bool isMatrix() const { return mType.isMatrix(); }
bool isArray() const { return mType.isArray(); }
bool isVector() const { return mType.isVector(); }
bool isScalar() const { return mType.isScalar(); }
bool isScalarInt() const { return mType.isScalarInt(); }
const char *getBasicString() const { return mType.getBasicString(); }
const char *getQualifierString() const { return mType.getQualifierString(); }
TString getCompleteString() const { return mType.getCompleteString(); }
int getArraySize() const { return mType.getArraySize(); }
protected:
TType mType;
};
//
// Handle for, do-while, and while loops.
//
enum TLoopType
{
ELoopFor,
ELoopWhile,
ELoopDoWhile
};
class TIntermLoop : public TIntermNode
{
public:
TIntermLoop(TLoopType type,
TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr,
TIntermNode *body)
: mType(type),
mInit(init),
mCond(cond),
mExpr(expr),
mBody(body),
mUnrollFlag(false) { }
virtual TIntermLoop *getAsLoopNode() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
TLoopType getType() const { return mType; }
TIntermNode *getInit() { return mInit; }
TIntermTyped *getCondition() { return mCond; }
TIntermTyped *getExpression() { return mExpr; }
TIntermNode *getBody() { return mBody; }
void setUnrollFlag(bool flag) { mUnrollFlag = flag; }
bool getUnrollFlag() const { return mUnrollFlag; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TLoopType mType;
TIntermNode *mInit; // for-loop initialization
TIntermTyped *mCond; // loop exit condition
TIntermTyped *mExpr; // for-loop expression
TIntermNode *mBody; // loop body
bool mUnrollFlag; // Whether the loop should be unrolled or not.
};
//
// Handle break, continue, return, and kill.
//
class TIntermBranch : public TIntermNode
{
public:
TIntermBranch(TOperator op, TIntermTyped *e)
: mFlowOp(op),
mExpression(e) { }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
TOperator getFlowOp() { return mFlowOp; }
TIntermTyped* getExpression() { return mExpression; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TOperator mFlowOp;
TIntermTyped *mExpression; // non-zero except for "return exp;" statements
};
//
// Nodes that correspond to symbols or constants in the source code.
//
class TIntermSymbol : public TIntermTyped
{
public:
// if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym.
// If sym comes from per process globalpoolallocator, then it causes increased memory usage
// per compile it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(int id, const TString &symbol, const TType &type)
: TIntermTyped(type),
mId(id)
{
mSymbol = symbol;
}
virtual bool hasSideEffects() const { return false; }
int getId() const { return mId; }
const TString &getSymbol() const { return mSymbol; }
void setId(int newId) { mId = newId; }
virtual void traverse(TIntermTraverser *);
virtual TIntermSymbol *getAsSymbolNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
protected:
int mId;
TString mSymbol;
};
// A Raw node stores raw code, that the translator will insert verbatim
// into the output stream. Useful for transformation operations that make
// complex code that might not fit naturally into the GLSL model.
class TIntermRaw : public TIntermTyped
{
public:
TIntermRaw(const TType &type, const TString &rawText)
: TIntermTyped(type),
mRawText(rawText) { }
virtual bool hasSideEffects() const { return false; }
TString getRawText() const { return mRawText; }
virtual void traverse(TIntermTraverser *);
virtual TIntermRaw *getAsRawNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
protected:
TString mRawText;
};
class TIntermConstantUnion : public TIntermTyped
{
public:
TIntermConstantUnion(ConstantUnion *unionPointer, const TType &type)
: TIntermTyped(type),
mUnionArrayPointer(unionPointer) { }
virtual bool hasSideEffects() const { return false; }
ConstantUnion *getUnionArrayPointer() const { return mUnionArrayPointer; }
int getIConst(size_t index) const
{
return mUnionArrayPointer ? mUnionArrayPointer[index].getIConst() : 0;
}
unsigned int getUConst(size_t index) const
{
return mUnionArrayPointer ? mUnionArrayPointer[index].getUConst() : 0;
}
float getFConst(size_t index) const
{
return mUnionArrayPointer ? mUnionArrayPointer[index].getFConst() : 0.0f;
}
bool getBConst(size_t index) const
{
return mUnionArrayPointer ? mUnionArrayPointer[index].getBConst() : false;
}
virtual TIntermConstantUnion *getAsConstantUnion() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
TIntermTyped *fold(TOperator, TIntermTyped *, TInfoSink &);
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
protected:
ConstantUnion *mUnionArrayPointer;
};
//
// Intermediate class for node types that hold operators.
//
class TIntermOperator : public TIntermTyped
{
public:
TOperator getOp() const { return mOp; }
void setOp(TOperator op) { mOp = op; }
bool isAssignment() const;
bool isConstructor() const;
virtual bool hasSideEffects() const { return isAssignment(); }
protected:
TIntermOperator(TOperator op)
: TIntermTyped(TType(EbtFloat, EbpUndefined)),
mOp(op) {}
TIntermOperator(TOperator op, const TType &type)
: TIntermTyped(type),
mOp(op) {}
TOperator mOp;
};
//
// Nodes for all the basic binary math operators.
//
class TIntermBinary : public TIntermOperator
{
public:
TIntermBinary(TOperator op)
: TIntermOperator(op),
mAddIndexClamp(false) {}
virtual TIntermBinary *getAsBinaryNode() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
virtual bool hasSideEffects() const
{
return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
}
void setLeft(TIntermTyped *node) { mLeft = node; }
void setRight(TIntermTyped *node) { mRight = node; }
TIntermTyped *getLeft() const { return mLeft; }
TIntermTyped *getRight() const { return mRight; }
bool promote(TInfoSink &);
void setAddIndexClamp() { mAddIndexClamp = true; }
bool getAddIndexClamp() { return mAddIndexClamp; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TIntermTyped* mLeft;
TIntermTyped* mRight;
// If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
bool mAddIndexClamp;
};
//
// Nodes for unary math operators.
//
class TIntermUnary : public TIntermOperator
{
public:
TIntermUnary(TOperator op, const TType &type)
: TIntermOperator(op, type),
mOperand(NULL),
mUseEmulatedFunction(false) {}
TIntermUnary(TOperator op)
: TIntermOperator(op),
mOperand(NULL),
mUseEmulatedFunction(false) {}
virtual void traverse(TIntermTraverser *);
virtual TIntermUnary *getAsUnaryNode() { return this; }
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
virtual bool hasSideEffects() const
{
return isAssignment() || mOperand->hasSideEffects();
}
void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; }
bool promote(TInfoSink &);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TIntermTyped *mOperand;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
bool mUseEmulatedFunction;
};
typedef TVector<TIntermNode *> TIntermSequence;
typedef TVector<int> TQualifierList;
//
// Nodes that operate on an arbitrary sized set of children.
//
class TIntermAggregate : public TIntermOperator
{
public:
TIntermAggregate()
: TIntermOperator(EOpNull),
mUserDefined(false),
mUseEmulatedFunction(false) { }
TIntermAggregate(TOperator op)
: TIntermOperator(op),
mUseEmulatedFunction(false) { }
~TIntermAggregate() { }
virtual TIntermAggregate *getAsAggregate() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
// Conservatively assume function calls and other aggregate operators have side-effects
virtual bool hasSideEffects() const { return true; }
TIntermSequence *getSequence() { return &mSequence; }
void setName(const TString &name) { mName = name; }
const TString &getName() const { return mName; }
void setUserDefined() { mUserDefined = true; }
bool isUserDefined() const { return mUserDefined; }
void setOptimize(bool optimize) { mOptimize = optimize; }
bool getOptimize() const { return mOptimize; }
void setDebug(bool debug) { mDebug = debug; }
bool getDebug() const { return mDebug; }
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator
TIntermSequence mSequence;
TString mName;
bool mUserDefined; // used for user defined function names
bool mOptimize;
bool mDebug;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
bool mUseEmulatedFunction;
};
//
// For if tests. Simplified since there is no switch statement.
//
class TIntermSelection : public TIntermTyped
{
public:
TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB)
: TIntermTyped(TType(EbtVoid, EbpUndefined)),
mCondition(cond),
mTrueBlock(trueB),
mFalseBlock(falseB) {}
TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB,
const TType &type)
: TIntermTyped(type),
mCondition(cond),
mTrueBlock(trueB),
mFalseBlock(falseB) {}
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
// Conservatively assume selections have side-effects
virtual bool hasSideEffects() const { return true; }
bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
TIntermNode *getCondition() const { return mCondition; }
TIntermNode *getTrueBlock() const { return mTrueBlock; }
TIntermNode *getFalseBlock() const { return mFalseBlock; }
TIntermSelection *getAsSelectionNode() { return this; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TIntermTyped *mCondition;
TIntermNode *mTrueBlock;
TIntermNode *mFalseBlock;
};
enum Visit
{
PreVisit,
InVisit,
PostVisit
};
//
// For traversing the tree. User should derive from this,
// put their traversal specific data in it, and then pass
// it to a Traverse method.
//
// When using this, just fill in the methods for nodes you want visited.
// Return false from a pre-visit to skip visiting that node's subtree.
//
class TIntermTraverser
{
public:
POOL_ALLOCATOR_NEW_DELETE();
// TODO(zmo): remove default values.
TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false,
bool rightToLeft = false)
: preVisit(preVisit),
inVisit(inVisit),
postVisit(postVisit),
rightToLeft(rightToLeft),
mDepth(0),
mMaxDepth(0) {}
virtual ~TIntermTraverser() {}
virtual void visitSymbol(TIntermSymbol *) {}
virtual void visitRaw(TIntermRaw *) {}
virtual void visitConstantUnion(TIntermConstantUnion *) {}
virtual bool visitBinary(Visit, TIntermBinary *) { return true; }
virtual bool visitUnary(Visit, TIntermUnary *) { return true; }
virtual bool visitSelection(Visit, TIntermSelection *) { return true; }
virtual bool visitAggregate(Visit, TIntermAggregate *) { return true; }
virtual bool visitLoop(Visit, TIntermLoop *) { return true; }
virtual bool visitBranch(Visit, TIntermBranch *) { return true; }
int getMaxDepth() const { return mMaxDepth; }
void incrementDepth(TIntermNode *current)
{
mDepth++;
mMaxDepth = std::max(mMaxDepth, mDepth);
mPath.push_back(current);
}
void decrementDepth()
{
mDepth--;
mPath.pop_back();
}
TIntermNode *getParentNode()
{
return mPath.size() == 0 ? NULL : mPath.back();
}
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
static TString hash(const TString& name, ShHashFunction64 hashFunction);
const bool preVisit;
const bool inVisit;
const bool postVisit;
const bool rightToLeft;
protected:
int mDepth;
int mMaxDepth;
// All the nodes from root to the current node's parent during traversing.
TVector<TIntermNode *> mPath;
};
//
// For traversing the tree, and computing max depth.
// Takes a maximum depth limit to prevent stack overflow.
//
class TMaxDepthTraverser : public TIntermTraverser
{
public:
POOL_ALLOCATOR_NEW_DELETE();
TMaxDepthTraverser(int depthLimit)
: TIntermTraverser(true, true, false, false),
mDepthLimit(depthLimit) { }
virtual bool visitBinary(Visit, TIntermBinary *) { return depthCheck(); }
virtual bool visitUnary(Visit, TIntermUnary *) { return depthCheck(); }
virtual bool visitSelection(Visit, TIntermSelection *) { return depthCheck(); }
virtual bool visitAggregate(Visit, TIntermAggregate *) { return depthCheck(); }
virtual bool visitLoop(Visit, TIntermLoop *) { return depthCheck(); }
virtual bool visitBranch(Visit, TIntermBranch *) { return depthCheck(); }
protected:
bool depthCheck() const { return mMaxDepth < mDepthLimit; }
int mDepthLimit;
};
#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_

View File

@ -4,7 +4,7 @@
// found in the LICENSE file.
//
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
//
// Traverse the intermediate representation tree, and

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
#ifndef COMPILER_TRANSLATOR_LOOP_INFO_H_
#define COMPILER_TRANSLATOR_LOOP_INFO_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
class TLoopIndexInfo
{

View File

@ -9,7 +9,7 @@
#ifndef TRANSLATOR_NODESEARCH_H_
#define TRANSLATOR_NODESEARCH_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
namespace sh
{

View File

@ -81,9 +81,10 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
{
TInfoSinkBase &out = objSink();
TQualifier qualifier = type.getQualifier();
// TODO(alokp): Validate qualifier for variable declarations.
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
{
out << type.getQualifierString() << " ";
}
// Declare the struct if we have not done so already.
if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
{
@ -648,6 +649,17 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
mDeclaringVariables = false;
}
break;
case EOpInvariantDeclaration: {
// Invariant declaration.
ASSERT(visit == PreVisit);
const TIntermSequence *sequence = node->getSequence();
ASSERT(sequence && sequence->size() == 1);
const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
ASSERT(symbol);
out << "invariant " << symbol->getSymbol() << ";";
visitChildren = false;
break;
}
case EOpConstructFloat:
writeTriplet(visit, "float(", NULL, ")");
break;

View File

@ -9,7 +9,7 @@
#include <set>
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/LoopInfo.h"
#include "compiler/translator/ParseContext.h"

View File

@ -21,6 +21,7 @@
#include "compiler/translator/util.h"
#include "compiler/translator/UniformHLSL.h"
#include "compiler/translator/StructureHLSL.h"
#include "compiler/translator/TranslatorHLSL.h"
#include <algorithm>
#include <cfloat>
@ -93,8 +94,10 @@ bool OutputHLSL::TextureFunction::operator<(const TextureFunction &rhs) const
return false;
}
OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType)
: TIntermTraverser(true, true, true), mContext(context), mOutputType(outputType)
OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
: TIntermTraverser(true, true, true),
mContext(context),
mOutputType(parentTranslator->getOutputType())
{
mUnfoldShortCircuit = new UnfoldShortCircuit(context, this);
mInsideFunction = false;
@ -126,6 +129,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mUsesDiscardRewriting = false;
mUsesNestedBreak = false;
const ShBuiltInResources &resources = parentTranslator->getResources();
mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
mUniqueIndex = 0;
@ -138,7 +142,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mExcessiveLoopIndex = NULL;
mStructureHLSL = new StructureHLSL;
mUniformHLSL = new UniformHLSL(mStructureHLSL, mOutputType);
mUniformHLSL = new UniformHLSL(mStructureHLSL, parentTranslator);
if (mOutputType == SH_HLSL9_OUTPUT)
{
@ -212,31 +216,6 @@ TInfoSinkBase &OutputHLSL::getBodyStream()
return mBody;
}
const std::vector<sh::Uniform> &OutputHLSL::getUniforms()
{
return mUniformHLSL->getUniforms();
}
const std::vector<sh::InterfaceBlock> &OutputHLSL::getInterfaceBlocks() const
{
return mUniformHLSL->getInterfaceBlocks();
}
const std::vector<sh::Attribute> &OutputHLSL::getOutputVariables() const
{
return mActiveOutputVariables;
}
const std::vector<sh::Attribute> &OutputHLSL::getAttributes() const
{
return mActiveAttributes;
}
const std::vector<sh::Varying> &OutputHLSL::getVaryings() const
{
return mActiveVaryings;
}
const std::map<std::string, unsigned int> &OutputHLSL::getInterfaceBlockRegisterMap() const
{
return mUniformHLSL->getInterfaceBlockRegisterMap();
@ -324,8 +303,6 @@ void OutputHLSL::header()
// Program linking depends on this exact format
varyings += "static " + InterpolationString(type.getQualifier()) + " " + TypeString(type) + " " +
Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n";
declareVaryingToList(type, type.getQualifier(), name, mActiveVaryings);
}
for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++)
@ -334,10 +311,6 @@ void OutputHLSL::header()
const TString &name = attribute->second->getSymbol();
attributes += "static " + TypeString(type) + " " + Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n";
sh::Attribute attributeVar(GLVariableType(type), GLVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), type.getLayoutQualifier().location);
mActiveAttributes.push_back(attributeVar);
}
out << mStructureHLSL->structsHeader();
@ -370,14 +343,9 @@ void OutputHLSL::header()
{
const TString &variableName = outputVariableIt->first;
const TType &variableType = outputVariableIt->second->getType();
const TLayoutQualifier &layoutQualifier = variableType.getLayoutQualifier();
out << "static " + TypeString(variableType) + " out_" + variableName + ArrayString(variableType) +
" = " + initializer(variableType) + ";\n";
sh::Attribute outputVar(GLVariableType(variableType), GLVariablePrecision(variableType), variableName.c_str(),
(unsigned int)variableType.getArraySize(), layoutQualifier.location);
mActiveOutputVariables.push_back(outputVar);
}
}
else
@ -1951,6 +1919,9 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
out << ", ";
}
break;
case EOpInvariantDeclaration:
// Do not do any translation
return false;
case EOpPrototype:
if (visit == PreVisit)
{
@ -2910,29 +2881,4 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
return constUnion;
}
class DeclareVaryingTraverser : public GetVariableTraverser<Varying>
{
public:
DeclareVaryingTraverser(std::vector<Varying> *output,
InterpolationType interpolation)
: GetVariableTraverser(output),
mInterpolation(interpolation)
{}
private:
void visitVariable(Varying *varying)
{
varying->interpolation = mInterpolation;
}
InterpolationType mInterpolation;
};
void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQualifier,
const TString &name, std::vector<Varying> &fieldsOut)
{
DeclareVaryingTraverser traverser(&fieldsOut, GetInterpolationType(baseTypeQualifier));
traverser.traverse(type, name);
}
}

View File

@ -12,9 +12,9 @@
#include <map>
#include "angle_gl.h"
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/ParseContext.h"
#include "common/shadervars.h"
namespace sh
{
@ -27,17 +27,12 @@ typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
class OutputHLSL : public TIntermTraverser
{
public:
OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType);
OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator);
~OutputHLSL();
void output();
TInfoSinkBase &getBodyStream();
const std::vector<sh::Uniform> &getUniforms();
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const;
const std::vector<sh::Attribute> &getOutputVariables() const;
const std::vector<sh::Attribute> &getAttributes() const;
const std::vector<sh::Varying> &getVaryings() const;
const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const;
const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
@ -155,13 +150,8 @@ class OutputHLSL : public TIntermTraverser
TIntermSymbol *mExcessiveLoopIndex;
void declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<sh::Varying>& fieldsOut);
TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName);
std::vector<sh::Attribute> mActiveOutputVariables;
std::vector<sh::Attribute> mActiveAttributes;
std::vector<sh::Varying> mActiveVaryings;
std::map<TIntermTyped*, TString> mFlaggedStructMappedNames;
std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames;

View File

@ -1018,6 +1018,45 @@ void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* nam
//
/////////////////////////////////////////////////////////////////////////////////
const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
const TString *name,
const TSymbol *symbol)
{
const TVariable *variable = NULL;
if (!symbol)
{
error(location, "undeclared identifier", name->c_str());
recover();
}
else if (!symbol->isVariable())
{
error(location, "variable expected", name->c_str());
recover();
}
else
{
variable = static_cast<const TVariable*>(symbol);
if (symbolTable.findBuiltIn(variable->getName(), shaderVersion) &&
!variable->getExtension().empty() &&
extensionErrorCheck(location, variable->getExtension()))
{
recover();
}
}
if (!variable)
{
TType type(EbtFloat, EbpUndefined);
TVariable *fakeVariable = new TVariable(name, type);
symbolTable.declare(fakeVariable);
variable = fakeVariable;
}
return variable;
}
//
// Look up a function name in the symbol table, and make sure it is a function.
//
@ -1050,6 +1089,8 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction*
// Initializers show up in several places in the grammar. Have one set of
// code to handle them here.
//
// Returns true on error, false if no error
//
bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
{
@ -1308,14 +1349,40 @@ TIntermAggregate* TParseContext::parseSingleInitDeclaration(TPublicType &publicT
}
}
TIntermAggregate* TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier)
TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
const TSourceLoc &identifierLoc,
const TString *identifier,
const TSymbol *symbol)
{
if (publicType.type == EbtInvariant && !identifierSymbol)
// invariant declaration
if (globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying"))
{
error(identifierLocation, "undeclared identifier declared as invariant", identifier.c_str());
recover();
}
if (!symbol)
{
error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
recover();
return NULL;
}
else
{
const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
ASSERT(variable);
const TType &type = variable->getType();
TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(),
*identifier, type, identifierLoc);
TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
aggregate->setOp(EOpInvariantDeclaration);
return aggregate;
}
}
TIntermAggregate* TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier)
{
TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
TIntermAggregate* intermAggregate = intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
@ -1548,7 +1615,7 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, const TType
for (size_t i = 0; i < fields.size(); i++)
{
if ((*args)[i]->getAsTyped()->getType() != *fields[i]->type())
if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type())
{
error(line, "Structure constructor arguments do not match structure fields", "Error");
recover();

View File

@ -9,7 +9,7 @@
#include "compiler/translator/Compiler.h"
#include "compiler/translator/Diagnostics.h"
#include "compiler/translator/DirectiveHandler.h"
#include "compiler/translator/localintermediate.h"
#include "compiler/translator/Intermediate.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/preprocessor/Preprocessor.h"
@ -77,6 +77,9 @@ struct TParseContext {
void trace(const char* str);
void recover();
// This method is guaranteed to succeed, even if no variable with 'name' exists.
const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc& line);
bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc& line);
@ -126,6 +129,8 @@ struct TParseContext {
TIntermAggregate* parseSingleDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier);
TIntermAggregate* parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& indexLocation, TIntermTyped *indexExpression);
TIntermAggregate* parseSingleInitDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer);
TIntermAggregate* parseInvariantDeclaration(const TSourceLoc &invariantLoc, const TSourceLoc &identifierLoc, const TString *identifier, const TSymbol *symbol);
TIntermAggregate* parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier);
TIntermAggregate* parseArrayDeclarator(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& arrayLocation, TIntermNode *declaratorList, TIntermTyped *indexExpression);
TIntermAggregate* parseInitDeclarator(TPublicType &publicType, TIntermAggregate *declaratorList, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer);

View File

@ -4,7 +4,7 @@
// found in the LICENSE file.
//
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
class TAliveTraverser : public TIntermTraverser {
public:

View File

@ -0,0 +1,82 @@
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/translator/RegenerateStructNames.h"
#include "compiler/translator/compilerdebug.h"
void RegenerateStructNames::visitSymbol(TIntermSymbol *symbol)
{
ASSERT(symbol);
TType *type = symbol->getTypePointer();
ASSERT(type);
TStructure *userType = type->getStruct();
if (!userType)
return;
if (mSymbolTable.findBuiltIn(userType->name(), mShaderVersion))
{
// Built-in struct, do not touch it.
return;
}
int uniqueId = userType->uniqueId();
ASSERT(mScopeDepth > 0);
if (mScopeDepth == 1)
{
// If a struct is defined at global scope, we don't map its name.
// This is because at global level, the struct might be used to
// declare a uniform, so the same name needs to stay the same for
// vertex/fragment shaders. However, our mapping uses internal ID,
// which will be different for the same struct in vertex/fragment
// shaders.
// This is OK because names for any structs defined in other scopes
// will begin with "_webgl", which is reserved. So there will be
// no conflicts among unmapped struct names from global scope and
// mapped struct names from other scopes.
// However, we need to keep track of these global structs, so if a
// variable is used in a local scope, we don't try to modify the
// struct name through that variable.
mDeclaredGlobalStructs.insert(uniqueId);
return;
}
if (mDeclaredGlobalStructs.count(uniqueId) > 0)
return;
// Map {name} to _webgl_struct_{uniqueId}_{name}.
const char kPrefix[] = "_webgl_struct_";
if (userType->name().find(kPrefix) == 0)
{
// The name has already been regenerated.
return;
}
std::string id = Str(uniqueId);
TString tmp = kPrefix + TString(id.c_str());
tmp += "_" + userType->name();
userType->setName(tmp);
}
bool RegenerateStructNames::visitAggregate(Visit, TIntermAggregate *aggregate)
{
ASSERT(aggregate);
switch (aggregate->getOp())
{
case EOpSequence:
++mScopeDepth;
{
TIntermSequence &sequence = *(aggregate->getSequence());
for (size_t ii = 0; ii < sequence.size(); ++ii)
{
TIntermNode *node = sequence[ii];
ASSERT(node != NULL);
node->traverse(this);
}
}
--mScopeDepth;
return false;
default:
return true;
}
}

View File

@ -0,0 +1,40 @@
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_
#define COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_
#include "compiler/translator/Intermediate.h"
#include "compiler/translator/SymbolTable.h"
#include <set>
class RegenerateStructNames : public TIntermTraverser
{
public:
RegenerateStructNames(const TSymbolTable &symbolTable,
int shaderVersion)
: mSymbolTable(symbolTable),
mShaderVersion(shaderVersion),
mScopeDepth(0) {}
protected:
virtual void visitSymbol(TIntermSymbol *);
virtual bool visitAggregate(Visit, TIntermAggregate *);
private:
const TSymbolTable &mSymbolTable;
int mShaderVersion;
// Indicating the depth of the current scope.
// The global scope is 1.
int mScopeDepth;
// If a struct's declared globally, push its ID in this set.
std::set<int> mDeclaredGlobalStructs;
};
#endif // COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_

View File

@ -4,7 +4,7 @@
// found in the LICENSE file.
//
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/RemoveTree.h"
//

View File

@ -7,7 +7,7 @@
#ifndef COMPILER_RENAME_FUNCTION
#define COMPILER_RENAME_FUNCTION
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
//
// Renames a function, including its declaration and any calls to it.

View File

@ -10,7 +10,7 @@
#ifndef COMPILER_REWRITE_ELSE_BLOCKS_H_
#define COMPILER_REWRITE_ELSE_BLOCKS_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
namespace sh
{

View File

@ -9,6 +9,7 @@
#include <algorithm>
#include "angle_gl.h"
#include "common/angleutils.h"
namespace
@ -249,6 +250,16 @@ TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *orig
TType type = original->getType();
type.setQualifier(EvqTemporary);
if (mShaderType == GL_FRAGMENT_SHADER &&
type.getBasicType() == EbtFloat &&
type.getPrecision() == EbpUndefined)
{
// We use the highest available precision for the temporary variable
// to avoid computing the actual precision using the rules defined
// in GLSL ES 1.0 Section 4.5.2.
type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
}
TIntermBinary *init = new TIntermBinary(EOpInitialize);
TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type);
init->setLeft(symbolNode);

View File

@ -7,13 +7,16 @@
#ifndef COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_
#define COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
class ScalarizeVecAndMatConstructorArgs : public TIntermTraverser
{
public:
ScalarizeVecAndMatConstructorArgs()
: mTempVarCount(0) {}
ScalarizeVecAndMatConstructorArgs(sh::GLenum shaderType,
bool fragmentPrecisionHigh)
: mTempVarCount(0),
mShaderType(shaderType),
mFragmentPrecisionHigh(fragmentPrecisionHigh) {}
protected:
virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
@ -36,6 +39,9 @@ class ScalarizeVecAndMatConstructorArgs : public TIntermTraverser
std::vector<TIntermSequence> mSequenceStack;
int mTempVarCount;
sh::GLenum mShaderType;
bool mFragmentPrecisionHigh;
};
#endif // COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_

View File

@ -9,7 +9,7 @@
#ifndef COMPILER_SEARCHSYMBOL_H_
#define COMPILER_SEARCHSYMBOL_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/ParseContext.h"
namespace sh

View File

@ -18,14 +18,26 @@
#include "compiler/translator/VariablePacker.h"
#include "angle_gl.h"
static bool isInitialized = false;
namespace
{
enum ShaderVariableType
{
SHADERVAR_UNIFORM,
SHADERVAR_VARYING,
SHADERVAR_ATTRIBUTE,
SHADERVAR_OUTPUTVARIABLE,
SHADERVAR_INTERFACEBLOCK
};
bool isInitialized = false;
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
//
static bool checkVariableMaxLengths(const ShHandle handle,
static bool CheckVariableMaxLengths(const ShHandle handle,
size_t expectedValue)
{
size_t activeUniformLimit = 0;
@ -39,7 +51,7 @@ static bool checkVariableMaxLengths(const ShHandle handle,
expectedValue == varyingLimit);
}
static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
bool CheckMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
{
size_t mappedNameMaxLength = 0;
ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
@ -47,7 +59,7 @@ static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue
}
template <typename VarT>
static const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoList, int index)
const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoList, int index)
{
if (index < 0 || static_cast<size_t>(index) >= infoList.size())
{
@ -57,7 +69,7 @@ static const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoLis
return &infoList[index];
}
static const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index)
const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index)
{
switch (varType)
{
@ -73,7 +85,7 @@ static const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShader
}
}
static ShPrecisionType ConvertPrecision(sh::GLenum precision)
ShPrecisionType ConvertPrecision(sh::GLenum precision)
{
switch (precision)
{
@ -91,6 +103,55 @@ static ShPrecisionType ConvertPrecision(sh::GLenum precision)
}
}
template <typename VarT>
const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
template <>
const std::vector<sh::Uniform> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
{
return &compiler->getUniforms();
}
template <>
const std::vector<sh::Varying> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
{
return &compiler->getVaryings();
}
template <>
const std::vector<sh::Attribute> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType)
{
return (variableType == SHADERVAR_ATTRIBUTE ?
&compiler->getAttributes() :
&compiler->getOutputVariables());
}
template <>
const std::vector<sh::InterfaceBlock> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
{
return &compiler->getInterfaceBlocks();
}
template <typename VarT>
const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariableType variableType)
{
if (!handle)
{
return NULL;
}
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
TCompiler* compiler = base->getAsCompiler();
if (!compiler)
{
return NULL;
}
return GetVariableList<VarT>(compiler, variableType);
}
}
//
// Driver must call this first, once, before doing any other compiler operations.
// Subsequent calls to this function are no-op.
@ -372,7 +433,7 @@ void ShGetVariableInfo(const ShHandle handle,
// SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
// in ShGetInfo, below.
size_t variableLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
ASSERT(checkVariableMaxLengths(handle, variableLength));
ASSERT(CheckVariableMaxLengths(handle, variableLength));
strncpy(name, varInfo->name.c_str(), variableLength);
name[variableLength - 1] = 0;
if (mappedName)
@ -380,7 +441,7 @@ void ShGetVariableInfo(const ShHandle handle,
// This size must match that queried by
// SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
size_t maxMappedNameLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
ASSERT(CheckMappedNameMaxLength(handle, maxMappedNameLength));
strncpy(mappedName, varInfo->mappedName.c_str(), maxMappedNameLength);
mappedName[maxMappedNameLength - 1] = 0;
}
@ -429,34 +490,29 @@ void ShGetNameHashingEntry(const ShHandle handle,
hashedName[len - 1] = '\0';
}
void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
{
if (!handle || !params)
return;
return GetShaderVariables<sh::Uniform>(handle, SHADERVAR_UNIFORM);
}
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
TranslatorHLSL* translator = base->getAsTranslatorHLSL();
if (!translator) return;
const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle)
{
return GetShaderVariables<sh::Varying>(handle, SHADERVAR_VARYING);
}
switch(pname)
{
case SH_ACTIVE_UNIFORMS_ARRAY:
*params = (void*)&translator->getUniforms();
break;
case SH_ACTIVE_INTERFACE_BLOCKS_ARRAY:
*params = (void*)&translator->getInterfaceBlocks();
break;
case SH_ACTIVE_OUTPUT_VARIABLES_ARRAY:
*params = (void*)&translator->getOutputVariables();
break;
case SH_ACTIVE_ATTRIBUTES_ARRAY:
*params = (void*)&translator->getAttributes();
break;
case SH_ACTIVE_VARYINGS_ARRAY:
*params = (void*)&translator->getVaryings();
break;
default: UNREACHABLE();
}
const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle)
{
return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_ATTRIBUTE);
}
const std::vector<sh::Attribute> *ShGetOutputVariables(const ShHandle handle)
{
return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_OUTPUTVARIABLE);
}
const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle)
{
return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
}
int ShCheckVariablesWithinPackingLimits(
@ -468,7 +524,7 @@ int ShCheckVariablesWithinPackingLimits(
std::vector<sh::ShaderVariable> variables;
for (size_t ii = 0; ii < varInfoArraySize; ++ii)
{
sh::ShaderVariable var(varInfoArray[ii].type, (sh::GLenum)0, "", varInfoArray[ii].size);
sh::ShaderVariable var(varInfoArray[ii].type, varInfoArray[ii].size);
variables.push_back(var);
}
VariablePacker packer;

View File

@ -0,0 +1,166 @@
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ShaderVars.cpp:
// Methods for GL variable types (varyings, uniforms, etc)
//
#include <GLSLANG/ShaderLang.h>
namespace sh
{
ShaderVariable::ShaderVariable()
: type(0),
precision(0),
arraySize(0),
staticUse(false)
{}
ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn)
: type(typeIn),
precision(0),
arraySize(arraySizeIn),
staticUse(false)
{}
ShaderVariable::~ShaderVariable()
{}
ShaderVariable::ShaderVariable(const ShaderVariable &other)
: type(other.type),
precision(other.precision),
name(other.name),
mappedName(other.mappedName),
arraySize(other.arraySize),
staticUse(other.staticUse),
fields(other.fields),
structName(other.structName)
{}
ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
{
type = other.type;
precision = other.precision;
name = other.name;
mappedName = other.mappedName;
arraySize = other.arraySize;
staticUse = other.staticUse;
fields = other.fields;
structName = other.structName;
return *this;
}
Uniform::Uniform()
{}
Uniform::~Uniform()
{}
Uniform::Uniform(const Uniform &other)
: ShaderVariable(other)
{}
Uniform &Uniform::operator=(const Uniform &other)
{
ShaderVariable::operator=(other);
return *this;
}
Attribute::Attribute()
: location(-1)
{}
Attribute::~Attribute()
{}
Attribute::Attribute(const Attribute &other)
: ShaderVariable(other),
location(other.location)
{}
Attribute &Attribute::operator=(const Attribute &other)
{
ShaderVariable::operator=(other);
location = other.location;
return *this;
}
InterfaceBlockField::InterfaceBlockField()
: isRowMajorLayout(false)
{}
InterfaceBlockField::~InterfaceBlockField()
{}
InterfaceBlockField::InterfaceBlockField(const InterfaceBlockField &other)
: ShaderVariable(other),
isRowMajorLayout(other.isRowMajorLayout)
{}
InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &other)
{
ShaderVariable::operator=(other);
isRowMajorLayout = other.isRowMajorLayout;
return *this;
}
Varying::Varying()
: interpolation(INTERPOLATION_SMOOTH),
isInvariant(false)
{}
Varying::~Varying()
{}
Varying::Varying(const Varying &other)
: ShaderVariable(other),
interpolation(other.interpolation),
isInvariant(other.isInvariant)
{}
Varying &Varying::operator=(const Varying &other)
{
ShaderVariable::operator=(other);
interpolation = other.interpolation;
isInvariant = other.isInvariant;
return *this;
}
InterfaceBlock::InterfaceBlock()
: arraySize(0),
layout(BLOCKLAYOUT_PACKED),
isRowMajorLayout(false),
staticUse(false)
{}
InterfaceBlock::~InterfaceBlock()
{}
InterfaceBlock::InterfaceBlock(const InterfaceBlock &other)
: name(other.name),
mappedName(other.mappedName),
instanceName(other.instanceName),
arraySize(other.arraySize),
layout(other.layout),
isRowMajorLayout(other.isRowMajorLayout),
staticUse(other.staticUse),
fields(other.fields)
{}
InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other)
{
name = other.name;
mappedName = other.mappedName;
instanceName = other.instanceName;
arraySize = other.arraySize;
layout = other.layout;
isRowMajorLayout = other.isRowMajorLayout;
staticUse = other.staticUse;
fields = other.fields;
return *this;
}
}

View File

@ -17,12 +17,19 @@
namespace sh
{
Std140PaddingHelper::Std140PaddingHelper(const std::map<TString, int> &structElementIndexes)
: mPaddingCounter(0),
Std140PaddingHelper::Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
unsigned *uniqueCounter)
: mPaddingCounter(uniqueCounter),
mElementIndex(0),
mStructElementIndexes(structElementIndexes)
{}
TString Std140PaddingHelper::next()
{
unsigned value = (*mPaddingCounter)++;
return str(value);
}
int Std140PaddingHelper::prePadding(const TType &type)
{
if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray())
@ -68,7 +75,7 @@ TString Std140PaddingHelper::prePaddingString(const TType &type)
for (int paddingIndex = 0; paddingIndex < paddingCount; paddingIndex++)
{
padding += " float pad_" + str(mPaddingCounter++) + ";\n";
padding += " float pad_" + next() + ";\n";
}
return padding;
@ -116,19 +123,25 @@ TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRo
TString padding;
for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++)
{
padding += " float pad_" + str(mPaddingCounter++) + ";\n";
padding += " float pad_" + next() + ";\n";
}
return padding;
}
StructureHLSL::StructureHLSL()
: mUniquePaddingCounter(0)
{}
Std140PaddingHelper StructureHLSL::getPaddingHelper()
{
return Std140PaddingHelper(mStd140StructElementIndexes, &mUniquePaddingCounter);
}
TString StructureHLSL::defineQualified(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing)
{
if (useStd140Packing)
{
Std140PaddingHelper padHelper(mStd140StructElementIndexes);
Std140PaddingHelper padHelper = getPaddingHelper();
return define(structure, useHLSLRowMajorPacking, useStd140Packing, &padHelper);
}
else
@ -291,9 +304,9 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const
if (parameter.isScalar())
{
for (int row = 0; row < rows; row++)
for (int col = 0; col < cols; col++)
{
for (int col = 0; col < cols; col++)
for (int row = 0; row < rows; row++)
{
constructor += TString((row == col) ? "x0" : "0.0");
@ -306,13 +319,13 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const
}
else if (parameter.isMatrix())
{
for (int row = 0; row < rows; row++)
for (int col = 0; col < cols; col++)
{
for (int col = 0; col < cols; col++)
for (int row = 0; row < rows; row++)
{
if (row < parameter.getRows() && col < parameter.getCols())
{
constructor += TString("x0") + "[" + str(row) + "][" + str(col) + "]";
constructor += TString("x0") + "[" + str(col) + "][" + str(row) + "]";
}
else
{
@ -461,7 +474,7 @@ std::string StructureHLSL::structsHeader() const
void StructureHLSL::storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking)
{
Std140PaddingHelper padHelper(mStd140StructElementIndexes);
Std140PaddingHelper padHelper = getPaddingHelper();
const TFieldList &fields = structure.fields();
for (unsigned int i = 0; i < fields.size(); i++)

View File

@ -11,7 +11,7 @@
#define TRANSLATOR_STRUCTUREHLSL_H_
#include "compiler/translator/Common.h"
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include <set>
@ -26,7 +26,8 @@ namespace sh
class Std140PaddingHelper
{
public:
explicit Std140PaddingHelper(const std::map<TString, int> &structElementIndexes);
explicit Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
unsigned *uniqueCounter);
int elementIndex() const { return mElementIndex; }
int prePadding(const TType &type);
@ -34,7 +35,9 @@ class Std140PaddingHelper
TString postPaddingString(const TType &type, bool useHLSLRowMajorPacking);
private:
int mPaddingCounter;
TString next();
unsigned *mPaddingCounter;
int mElementIndex;
const std::map<TString, int> &mStructElementIndexes;
};
@ -50,9 +53,11 @@ class StructureHLSL
TString defineQualified(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing);
static TString defineNameless(const TStructure &structure);
Std140PaddingHelper getPaddingHelper() const { return Std140PaddingHelper(mStd140StructElementIndexes); }
Std140PaddingHelper getPaddingHelper();
private:
unsigned mUniquePaddingCounter;
std::map<TString, int> mStd140StructElementIndexes;
typedef std::set<TString> StructNames;

View File

@ -98,7 +98,8 @@ TSymbol::TSymbol(const TSymbol &copyOf)
uniqueId = copyOf.uniqueId;
}
TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope)
TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
bool *builtIn, bool *sameScope) const
{
int level = currentLevel();
TSymbol *symbol;
@ -122,7 +123,8 @@ TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtI
return symbol;
}
TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion)
TSymbol *TSymbolTable::findBuiltIn(
const TString &name, int shaderVersion) const
{
for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
{
@ -210,7 +212,7 @@ void TSymbolTable::insertBuiltIn(
insert(level, function);
}
TPrecision TSymbolTable::getDefaultPrecision(TBasicType type)
TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
{
if (!SupportsPrecision(type))
return EbpUndefined;

View File

@ -34,7 +34,7 @@
#include "common/angleutils.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
// Symbol base class. (Can build functions or variables out of these...)
class TSymbol
@ -323,15 +323,15 @@ class TSymbolTable
// When the symbol table is initialized with the built-ins, there should
// 'push' calls, so that built-ins are at level 0 and the shader
// globals are at level 1.
bool isEmpty()
bool isEmpty() const
{
return table.empty();
}
bool atBuiltInLevel()
bool atBuiltInLevel() const
{
return currentLevel() <= LAST_BUILTIN_LEVEL;
}
bool atGlobalLevel()
bool atGlobalLevel() const
{
return currentLevel() <= GLOBAL_LEVEL;
}
@ -373,8 +373,8 @@ class TSymbolTable
TType *ptype4 = 0, TType *ptype5 = 0);
TSymbol *find(const TString &name, int shaderVersion,
bool *builtIn = NULL, bool *sameScope = NULL);
TSymbol *findBuiltIn(const TString &name, int shaderVersion);
bool *builtIn = NULL, bool *sameScope = NULL) const;
TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
TSymbolTableLevel *getOuterLevel()
{
@ -406,7 +406,7 @@ class TSymbolTable
// Searches down the precisionStack for a precision qualifier
// for the specified TBasicType
TPrecision getDefaultPrecision(TBasicType type);
TPrecision getDefaultPrecision(TBasicType type) const;
static int nextUniqueId()
{

View File

@ -17,16 +17,10 @@ TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutpu
void TranslatorHLSL::translate(TIntermNode *root)
{
TParseContext& parseContext = *GetGlobalParseContext();
sh::OutputHLSL outputHLSL(parseContext, getResources(), getOutputType());
sh::OutputHLSL outputHLSL(parseContext, this);
outputHLSL.output();
attributes = outputHLSL.getAttributes();
outputVariables = outputHLSL.getOutputVariables();
uniforms = outputHLSL.getUniforms();
varyings = outputHLSL.getVaryings();
interfaceBlocks = outputHLSL.getInterfaceBlocks();
mInterfaceBlockRegisterMap = outputHLSL.getInterfaceBlockRegisterMap();
mUniformRegisterMap = outputHLSL.getUniformRegisterMap();
}

View File

@ -8,7 +8,6 @@
#define COMPILER_TRANSLATORHLSL_H_
#include "compiler/translator/Compiler.h"
#include "common/shadervars.h"
class TranslatorHLSL : public TCompiler
{

View File

@ -13,6 +13,38 @@
#include <algorithm>
#include <climits>
const char* getBasicString(TBasicType t)
{
switch (t)
{
case EbtVoid: return "void"; break;
case EbtFloat: return "float"; break;
case EbtInt: return "int"; break;
case EbtUInt: return "uint"; break;
case EbtBool: return "bool"; break;
case EbtSampler2D: return "sampler2D"; break;
case EbtSampler3D: return "sampler3D"; break;
case EbtSamplerCube: return "samplerCube"; break;
case EbtSamplerExternalOES: return "samplerExternalOES"; break;
case EbtSampler2DRect: return "sampler2DRect"; break;
case EbtSampler2DArray: return "sampler2DArray"; break;
case EbtISampler2D: return "isampler2D"; break;
case EbtISampler3D: return "isampler3D"; break;
case EbtISamplerCube: return "isamplerCube"; break;
case EbtISampler2DArray: return "isampler2DArray"; break;
case EbtUSampler2D: return "usampler2D"; break;
case EbtUSampler3D: return "usampler3D"; break;
case EbtUSamplerCube: return "usamplerCube"; break;
case EbtUSampler2DArray: return "usampler2DArray"; break;
case EbtSampler2DShadow: return "sampler2DShadow"; break;
case EbtSamplerCubeShadow: return "samplerCubeShadow"; break;
case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break;
case EbtStruct: return "structure"; break;
case EbtInterfaceBlock: return "interface block"; break;
default: UNREACHABLE(); return "unknown type";
}
}
TType::TType(const TPublicType &p)
: type(p.type), precision(p.precision), qualifier(p.qualifier), layoutQualifier(p.layoutQualifier),
primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize),

View File

@ -140,6 +140,17 @@ class TStructure : public TFieldListCollection
private:
DISALLOW_COPY_AND_ASSIGN(TStructure);
// TODO(zmo): Find a way to get rid of the const_cast in function
// setName(). At the moment keep this function private so only
// friend class RegenerateStructNames may call it.
friend class RegenerateStructNames;
void setName(const TString &name)
{
TString *mutableName = const_cast<TString *>(mName);
*mutableName = name;
}
virtual TString mangledNamePrefix() const
{
return "struct-";

View File

@ -9,7 +9,7 @@
#ifndef COMPILER_UNFOLDSHORTCIRCUIT_H_
#define COMPILER_UNFOLDSHORTCIRCUIT_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/ParseContext.h"
namespace sh

View File

@ -11,7 +11,7 @@
#define COMPILER_UNFOLD_SHORT_CIRCUIT_AST_H_
#include "common/angleutils.h"
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
// This traverser identifies all the short circuit binary nodes that need to
// be replaced, and creates the corresponding replacement nodes. However,

View File

@ -14,6 +14,7 @@
#include "compiler/translator/StructureHLSL.h"
#include "compiler/translator/util.h"
#include "compiler/translator/UtilsHLSL.h"
#include "compiler/translator/TranslatorHLSL.h"
namespace sh
{
@ -30,18 +31,6 @@ static const char *UniformRegisterPrefix(const TType &type)
}
}
static TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
{
if (interfaceBlock.hasInstanceName())
{
return interfaceBlock.name() + "." + field.name();
}
else
{
return field.name();
}
}
static TString InterfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage)
{
const TType &fieldType = *field.type();
@ -72,12 +61,13 @@ static TString InterfaceBlockStructName(const TInterfaceBlock &interfaceBlock)
return DecoratePrivate(interfaceBlock.name()) + "_type";
}
UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType)
UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, TranslatorHLSL *translator)
: mUniformRegister(0),
mInterfaceBlockRegister(0),
mSamplerRegister(0),
mStructureHLSL(structureHLSL),
mOutputType(outputType)
mOutputType(translator->getOutputType()),
mUniforms(translator->getUniforms())
{}
void UniformHLSL::reserveUniformRegisters(unsigned int registerCount)
@ -90,18 +80,32 @@ void UniformHLSL::reserveInterfaceBlockRegisters(unsigned int registerCount)
mInterfaceBlockRegister = registerCount;
}
const Uniform *UniformHLSL::findUniformByName(const TString &name) const
{
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
{
if (mUniforms[uniformIndex].name == name.c_str())
{
return &mUniforms[uniformIndex];
}
}
UNREACHABLE();
return NULL;
}
unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name)
{
unsigned int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister);
GetVariableTraverser<Uniform> traverser(&mActiveUniforms);
traverser.traverse(type, name);
const Uniform *uniform = findUniformByName(name);
ASSERT(uniform);
const sh::Uniform &activeUniform = mActiveUniforms.back();
mUniformRegisterMap[activeUniform.name] = registerIndex;
mUniformRegisterMap[uniform->name] = registerIndex;
unsigned int registerCount = HLSLVariableRegisterCount(activeUniform, mOutputType);
if (IsSampler(type.getBasicType()))
unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);
if (gl::IsSampler(uniform->type))
{
mSamplerRegister += registerCount;
}
@ -137,7 +141,12 @@ TString UniformHLSL::uniformsHeader(ShShaderOutput outputType, const ReferencedS
else
{
const TStructure *structure = type.getStruct();
const TString &typeName = (structure ? QualifiedStructNameString(*structure, false, false) : TypeString(type));
// If this is a nameless struct, we need to use its full definition, rather than its (empty) name.
// TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for
// nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers are
// permitted.
const TString &typeName = ((structure && !structure->name().empty()) ?
QualifiedStructNameString(*structure, false, false) : TypeString(type));
const TString &registerString = TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")";
@ -157,33 +166,14 @@ TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedIn
{
const TType &nodeType = interfaceBlockIt->second->getType();
const TInterfaceBlock &interfaceBlock = *nodeType.getInterfaceBlock();
const TFieldList &fieldList = interfaceBlock.fields();
unsigned int arraySize = static_cast<unsigned int>(interfaceBlock.arraySize());
unsigned int activeRegister = mInterfaceBlockRegister;
InterfaceBlock activeBlock(interfaceBlock.name().c_str(), arraySize);
for (unsigned int typeIndex = 0; typeIndex < fieldList.size(); typeIndex++)
{
const TField &field = *fieldList[typeIndex];
const TString &fullFieldName = InterfaceBlockFieldName(interfaceBlock, field);
bool isRowMajor = (field.type()->getLayoutQualifier().matrixPacking == EmpRowMajor);
GetInterfaceBlockFieldTraverser traverser(&activeBlock.fields, isRowMajor);
traverser.traverse(*field.type(), fullFieldName);
}
mInterfaceBlockRegisterMap[activeBlock.name] = activeRegister;
mInterfaceBlockRegisterMap[interfaceBlock.name().c_str()] = activeRegister;
mInterfaceBlockRegister += std::max(1u, arraySize);
activeBlock.layout = GetBlockLayoutType(interfaceBlock.blockStorage());
if (interfaceBlock.matrixPacking() == EmpRowMajor)
{
activeBlock.isRowMajorLayout = true;
}
mActiveInterfaceBlocks.push_back(activeBlock);
// FIXME: interface block field names
if (interfaceBlock.hasInstanceName())
{
@ -261,7 +251,7 @@ TString UniformHLSL::interfaceBlockMembersString(const TInterfaceBlock &interfac
if (blockStorage == EbsStd140)
{
// 2 and 3 component vector types in some cases need pre-padding
hlsl += padHelper.prePadding(fieldType);
hlsl += padHelper.prePaddingString(fieldType);
}
hlsl += " " + InterfaceBlockFieldTypeString(field, blockStorage) +

View File

@ -10,7 +10,6 @@
#ifndef TRANSLATOR_UNIFORMHLSL_H_
#define TRANSLATOR_UNIFORMHLSL_H_
#include "common/shadervars.h"
#include "compiler/translator/Types.h"
namespace sh
@ -20,7 +19,7 @@ class StructureHLSL;
class UniformHLSL
{
public:
UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType);
UniformHLSL(StructureHLSL *structureHLSL, TranslatorHLSL *translator);
void reserveUniformRegisters(unsigned int registerCount);
void reserveInterfaceBlockRegisters(unsigned int registerCount);
@ -30,8 +29,6 @@ class UniformHLSL
// Used for direct index references
static TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex);
const std::vector<Uniform> &getUniforms() const { return mActiveUniforms; }
const std::vector<InterfaceBlock> &getInterfaceBlocks() const { return mActiveInterfaceBlocks; }
const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const
{
return mInterfaceBlockRegisterMap;
@ -45,6 +42,7 @@ class UniformHLSL
TString interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex);
TString interfaceBlockMembersString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage);
TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock);
const Uniform *findUniformByName(const TString &name) const;
// Returns the uniform's register index
unsigned int declareUniformAndAssignRegister(const TType &type, const TString &name);
@ -55,8 +53,7 @@ class UniformHLSL
StructureHLSL *mStructureHLSL;
ShShaderOutput mOutputType;
std::vector<Uniform> mActiveUniforms;
std::vector<InterfaceBlock> mActiveInterfaceBlocks;
const std::vector<Uniform> &mUniforms;
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
std::map<std::string, unsigned int> mUniformRegisterMap;
};

View File

@ -4,7 +4,7 @@
// found in the LICENSE file.
//
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/LoopInfo.h"
class TInfoSinkBase;

View File

@ -4,7 +4,7 @@
// found in the LICENSE file.
//
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include <set>

View File

@ -9,20 +9,46 @@
#include "compiler/translator/util.h"
#include "common/utilities.h"
template <typename VarT>
static void ExpandUserDefinedVariable(const VarT &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<VarT> *expanded);
namespace sh
{
// Returns info for an attribute, uniform, or varying.
template <typename VarT>
static void ExpandVariable(const VarT &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<VarT> *expanded)
namespace
{
TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
{
if (interfaceBlock.hasInstanceName())
{
return interfaceBlock.name() + "." + field.name();
}
else
{
return field.name();
}
}
BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
{
switch (blockStorage)
{
case EbsPacked: return BLOCKLAYOUT_PACKED;
case EbsShared: return BLOCKLAYOUT_SHARED;
case EbsStd140: return BLOCKLAYOUT_STANDARD;
default: UNREACHABLE(); return BLOCKLAYOUT_SHARED;
}
}
void ExpandUserDefinedVariable(const ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<ShaderVariable> *expanded);
void ExpandVariable(const ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<ShaderVariable> *expanded)
{
if (variable.isStruct())
{
@ -30,8 +56,8 @@ static void ExpandVariable(const VarT &variable,
{
for (size_t elementIndex = 0; elementIndex < variable.elementCount(); elementIndex++)
{
std::string lname = name + ArrayString(elementIndex);
std::string lmappedName = mappedName + ArrayString(elementIndex);
std::string lname = name + ::ArrayString(elementIndex);
std::string lmappedName = mappedName + ::ArrayString(elementIndex);
ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded);
}
}
@ -42,7 +68,7 @@ static void ExpandVariable(const VarT &variable,
}
else
{
VarT expandedVar = variable;
ShaderVariable expandedVar = variable;
expandedVar.name = name;
expandedVar.mappedName = mappedName;
@ -63,20 +89,19 @@ static void ExpandVariable(const VarT &variable,
}
}
template <class VarT>
static void ExpandUserDefinedVariable(const VarT &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<VarT> *expanded)
void ExpandUserDefinedVariable(const ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<ShaderVariable> *expanded)
{
ASSERT(variable.isStruct());
const std::vector<VarT> &fields = variable.fields;
const std::vector<ShaderVariable> &fields = variable.fields;
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
const VarT &field = fields[fieldIndex];
const ShaderVariable &field = fields[fieldIndex];
ExpandVariable(field,
name + "." + field.name,
mappedName + "." + field.mappedName,
@ -86,8 +111,8 @@ static void ExpandUserDefinedVariable(const VarT &variable,
}
template <class VarT>
static VarT *FindVariable(const TString &name,
std::vector<VarT> *infoList)
VarT *FindVariable(const TString &name,
std::vector<VarT> *infoList)
{
// TODO(zmo): optimize this function.
for (size_t ii = 0; ii < infoList->size(); ++ii)
@ -99,6 +124,8 @@ static VarT *FindVariable(const TString &name,
return NULL;
}
}
CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
std::vector<sh::Attribute> *outputVariables,
std::vector<sh::Uniform> *uniforms,
@ -125,14 +152,18 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
void CollectVariables::visitSymbol(TIntermSymbol *symbol)
{
ASSERT(symbol != NULL);
sh::ShaderVariable *var = NULL;
ShaderVariable *var = NULL;
const TString &symbolName = symbol->getSymbol();
if (sh::IsVarying(symbol->getQualifier()))
if (IsVarying(symbol->getQualifier()))
{
var = FindVariable(symbolName, mVaryings);
}
else if (symbol->getType() != EbtInterfaceBlock)
else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
{
UNREACHABLE();
}
else
{
switch (symbol->getQualifier())
{
@ -148,12 +179,13 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
if (interfaceBlock)
{
sh::InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
ASSERT(namedBlock);
var = FindVariable(symbolName, &namedBlock->fields);
// Set static use on the parent interface block here
namedBlock->staticUse = true;
}
else
{
@ -167,7 +199,7 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
case EvqFragCoord:
if (!mFragCoordAdded)
{
sh::Varying info;
Varying info;
info.name = "gl_FragCoord";
info.mappedName = "gl_FragCoord";
info.type = GL_FLOAT_VEC4;
@ -181,7 +213,7 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
case EvqFrontFacing:
if (!mFrontFacingAdded)
{
sh::Varying info;
Varying info;
info.name = "gl_FrontFacing";
info.mappedName = "gl_FrontFacing";
info.type = GL_BOOL;
@ -195,7 +227,7 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
case EvqPointCoord:
if (!mPointCoordAdded)
{
sh::Varying info;
Varying info;
info.name = "gl_PointCoord";
info.mappedName = "gl_PointCoord";
info.type = GL_FLOAT_VEC2;
@ -216,17 +248,17 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
}
}
template <typename VarT>
class NameHashingTraverser : public sh::GetVariableTraverser<VarT>
class NameHashingTraverser : public GetVariableTraverser
{
public:
NameHashingTraverser(std::vector<VarT> *output, ShHashFunction64 hashFunction)
: sh::GetVariableTraverser<VarT>(output),
mHashFunction(hashFunction)
NameHashingTraverser(ShHashFunction64 hashFunction)
: mHashFunction(hashFunction)
{}
private:
void visitVariable(VarT *variable)
DISALLOW_COPY_AND_ASSIGN(NameHashingTraverser);
virtual void visitVariable(ShaderVariable *variable)
{
TString stringName = TString(variable->name.c_str());
variable->mappedName = TIntermTraverser::hash(stringName, mHashFunction).c_str();
@ -238,16 +270,16 @@ class NameHashingTraverser : public sh::GetVariableTraverser<VarT>
// Attributes, which cannot have struct fields, are a special case
template <>
void CollectVariables::visitVariable(const TIntermSymbol *variable,
std::vector<sh::Attribute> *infoList) const
std::vector<Attribute> *infoList) const
{
ASSERT(variable);
const TType &type = variable->getType();
ASSERT(!type.getStruct());
sh::Attribute attribute;
Attribute attribute;
attribute.type = sh::GLVariableType(type);
attribute.precision = sh::GLVariablePrecision(type);
attribute.type = GLVariableType(type);
attribute.precision = GLVariablePrecision(type);
attribute.name = variable->getSymbol().c_str();
attribute.arraySize = static_cast<unsigned int>(type.getArraySize());
attribute.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str();
@ -258,29 +290,32 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable,
template <>
void CollectVariables::visitVariable(const TIntermSymbol *variable,
std::vector<sh::InterfaceBlock> *infoList) const
std::vector<InterfaceBlock> *infoList) const
{
sh::InterfaceBlock interfaceBlock;
InterfaceBlock interfaceBlock;
const TInterfaceBlock *blockType = variable->getType().getInterfaceBlock();
bool isRowMajor = (blockType->matrixPacking() == EmpRowMajor);
ASSERT(blockType);
interfaceBlock.name = blockType->name().c_str();
interfaceBlock.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str();
interfaceBlock.instanceName = (blockType->hasInstanceName() ? blockType->instanceName().c_str() : "");
interfaceBlock.arraySize = variable->getArraySize();
interfaceBlock.isRowMajorLayout = isRowMajor;
interfaceBlock.layout = sh::GetBlockLayoutType(blockType->blockStorage());
interfaceBlock.isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor);
interfaceBlock.layout = GetBlockLayoutType(blockType->blockStorage());
ASSERT(blockType);
const TFieldList &blockFields = blockType->fields();
// Gather field information
const TFieldList &fieldList = blockType->fields();
for (size_t fieldIndex = 0; fieldIndex < blockFields.size(); fieldIndex++)
for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
{
const TField *field = blockFields[fieldIndex];
ASSERT(field);
const TField &field = *fieldList[fieldIndex];
const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
const TType &fieldType = *field.type();
sh::GetInterfaceBlockFieldTraverser traverser(&interfaceBlock.fields, isRowMajor);
traverser.traverse(*field->type(), field->name());
GetVariableTraverser traverser;
traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
}
infoList->push_back(interfaceBlock);
@ -290,8 +325,8 @@ template <typename VarT>
void CollectVariables::visitVariable(const TIntermSymbol *variable,
std::vector<VarT> *infoList) const
{
NameHashingTraverser<VarT> traverser(infoList, mHashFunction);
traverser.traverse(variable->getType(), variable->getSymbol());
NameHashingTraverser traverser(mHashFunction);
traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
}
template <typename VarT>
@ -320,16 +355,19 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
case EOpDeclaration:
{
const TIntermSequence &sequence = *(node->getSequence());
ASSERT(!sequence.empty());
const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
TQualifier qualifier = typedNode.getQualifier();
if (typedNode.getBasicType() == EbtInterfaceBlock)
{
visitInfoList(sequence, mInterfaceBlocks);
visitChildren = false;
}
else if (qualifier == EvqAttribute || qualifier == EvqVertexIn ||
qualifier == EvqFragmentOut || qualifier == EvqUniform ||
sh::IsVarying(qualifier))
IsVarying(qualifier))
{
switch (qualifier)
{
@ -348,10 +386,7 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
break;
}
if (!sequence.empty())
{
visitChildren = false;
}
visitChildren = false;
}
break;
}
@ -361,15 +396,43 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
return visitChildren;
}
bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
{
if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
{
// NOTE: we do not determine static use for individual blocks of an array
TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
ASSERT(blockNode);
TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
ASSERT(constantUnion);
const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
ASSERT(namedBlock);
namedBlock->staticUse = true;
unsigned int fieldIndex = constantUnion->getUConst(0);
ASSERT(fieldIndex < namedBlock->fields.size());
namedBlock->fields[fieldIndex].staticUse = true;
return false;
}
return true;
}
template <typename VarT>
void ExpandVariables(const std::vector<VarT> &compact, std::vector<VarT> *expanded)
void ExpandVariables(const std::vector<VarT> &compact,
std::vector<ShaderVariable> *expanded)
{
for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
{
const VarT &variable = compact[variableIndex];
const ShaderVariable &variable = compact[variableIndex];
ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, expanded);
}
}
template void ExpandVariables(const std::vector<sh::Uniform> &, std::vector<sh::Uniform> *);
template void ExpandVariables(const std::vector<sh::Varying> &, std::vector<sh::Varying> *);
template void ExpandVariables(const std::vector<Uniform> &, std::vector<ShaderVariable> *);
template void ExpandVariables(const std::vector<Varying> &, std::vector<ShaderVariable> *);
}

View File

@ -7,22 +7,27 @@
#ifndef COMPILER_VARIABLE_INFO_H_
#define COMPILER_VARIABLE_INFO_H_
#include "compiler/translator/intermediate.h"
#include "common/shadervars.h"
#include <GLSLANG/ShaderLang.h>
#include "compiler/translator/IntermNode.h"
namespace sh
{
// Traverses intermediate tree to collect all attributes, uniforms, varyings.
class CollectVariables : public TIntermTraverser
{
public:
CollectVariables(std::vector<sh::Attribute> *attribs,
std::vector<sh::Attribute> *outputVariables,
std::vector<sh::Uniform> *uniforms,
std::vector<sh::Varying> *varyings,
std::vector<sh::InterfaceBlock> *interfaceBlocks,
CollectVariables(std::vector<Attribute> *attribs,
std::vector<Attribute> *outputVariables,
std::vector<Uniform> *uniforms,
std::vector<Varying> *varyings,
std::vector<InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction);
virtual void visitSymbol(TIntermSymbol *symbol);
virtual bool visitAggregate(Visit, TIntermAggregate *node);
virtual bool visitBinary(Visit visit, TIntermBinary *binaryNode);
private:
template <typename VarT>
@ -31,13 +36,13 @@ class CollectVariables : public TIntermTraverser
template <typename VarT>
void visitInfoList(const TIntermSequence &sequence, std::vector<VarT> *infoList) const;
std::vector<sh::Attribute> *mAttribs;
std::vector<sh::Attribute> *mOutputVariables;
std::vector<sh::Uniform> *mUniforms;
std::vector<sh::Varying> *mVaryings;
std::vector<sh::InterfaceBlock> *mInterfaceBlocks;
std::vector<Attribute> *mAttribs;
std::vector<Attribute> *mOutputVariables;
std::vector<Uniform> *mUniforms;
std::vector<Varying> *mVaryings;
std::vector<InterfaceBlock> *mInterfaceBlocks;
std::map<std::string, sh::InterfaceBlockField *> mInterfaceBlockFields;
std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
bool mPointCoordAdded;
bool mFrontFacingAdded;
@ -47,8 +52,10 @@ class CollectVariables : public TIntermTraverser
};
// Expand struct variables to flattened lists of split variables
// Implemented for sh::Varying and sh::Uniform.
template <typename VarT>
void ExpandVariables(const std::vector<VarT> &compact, std::vector<VarT> *expanded);
void ExpandVariables(const std::vector<VarT> &compact,
std::vector<ShaderVariable> *expanded);
}
#endif // COMPILER_VARIABLE_INFO_H_

View File

@ -3,12 +3,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/translator/VariablePacker.h"
#include "angle_gl.h"
#include "common/utilities.h"
#include <algorithm>
#include "angle_gl.h"
#include "compiler/translator/VariablePacker.h"
#include "common/utilities.h"
int VariablePacker::GetNumComponentsPerRow(sh::GLenum type)
{
switch (type)

View File

@ -67,6 +67,9 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
}
break;
}
case EOpInvariantDeclaration:
updateVersion(GLSL_VERSION_120);
break;
case EOpParameters:
{
const TIntermSequence &params = *(node->getSequence());

View File

@ -7,7 +7,7 @@
#ifndef COMPILER_TRANSLATOR_VERSIONGLSL_H_
#define COMPILER_TRANSLATOR_VERSIONGLSL_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
// Traverses the intermediate tree to return the minimum GLSL version
// required to legally access all built-in features used in the shader.

View File

@ -7,7 +7,7 @@
#ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H
#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include <set>
#include <stack>

View File

@ -209,38 +209,7 @@ identifier
variable_identifier
: IDENTIFIER {
// The symbol table search was done in the lexical phase
const TSymbol *symbol = $1.symbol;
const TVariable *variable = 0;
if (!symbol)
{
context->error(@1, "undeclared identifier", $1.string->c_str());
context->recover();
}
else if (!symbol->isVariable())
{
context->error(@1, "variable expected", $1.string->c_str());
context->recover();
}
else
{
variable = static_cast<const TVariable*>(symbol);
if (context->symbolTable.findBuiltIn(variable->getName(), context->shaderVersion) &&
!variable->getExtension().empty() &&
context->extensionErrorCheck(@1, variable->getExtension()))
{
context->recover();
}
}
if (!variable)
{
TType type(EbtFloat, EbpUndefined);
TVariable *fakeVariable = new TVariable($1.string, type);
context->symbolTable.declare(fakeVariable);
variable = fakeVariable;
}
const TVariable *variable = context->getNamedVariable(@1, $1.string, $1.symbol);
if (variable->getType().getQualifier() == EvqConst)
{
@ -816,9 +785,10 @@ declaration
context->symbolTable.pop();
}
| init_declarator_list SEMICOLON {
if ($1.intermAggregate)
$1.intermAggregate->setOp(EOpDeclaration);
$$ = $1.intermAggregate;
TIntermAggregate *aggNode = $1.intermAggregate;
if (aggNode && aggNode->getOp() == EOpNull)
aggNode->setOp(EOpDeclaration);
$$ = aggNode;
}
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
if (($2 == EbpHigh) && (context->shaderType == GL_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
@ -1102,22 +1072,8 @@ single_declaration
$$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
}
| INVARIANT IDENTIFIER {
VERTEX_ONLY("invariant declaration", @1);
if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
context->recover();
$$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, @2);
if (!$2.symbol)
{
context->error(@2, "undeclared identifier declared as invariant", $2.string->c_str());
context->recover();
$$.intermAggregate = 0;
}
else
{
TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), @2);
$$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
}
// $$.type is not used in invariant declarations.
$$.intermAggregate = context->parseInvariantDeclaration(@1, @2, $2.string, $2.symbol);
}
;

View File

@ -4,7 +4,7 @@
// found in the LICENSE file.
//
#include "compiler/translator/localintermediate.h"
#include "compiler/translator/Intermediate.h"
#include "compiler/translator/SymbolTable.h"
namespace
@ -342,6 +342,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpMul: out << "component-wise multiply"; break;
case EOpDeclaration: out << "Declaration: "; break;
case EOpInvariantDeclaration: out << "Invariant Declaration: "; break;
default:
out.prefix(EPrefixError);

View File

@ -4,768 +4,64 @@
// found in the LICENSE file.
//
//
// Definition of the in-memory high-level intermediate representation
// of shaders. This is a tree that parser creates.
//
// Nodes in the tree are defined as a hierarchy of classes derived from
// TIntermNode. Each is a node in a tree. There is no preset branching factor;
// each node can have it's own type of list of children.
//
#ifndef COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
#define COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
#ifndef COMPILER_TRANSLATOR_INTERMEDIATE_H_
#define COMPILER_TRANSLATOR_INTERMEDIATE_H_
#include "compiler/translator/IntermNode.h"
#include "GLSLANG/ShaderLang.h"
#include <algorithm>
#include <queue>
#include "compiler/translator/Common.h"
#include "compiler/translator/Types.h"
#include "compiler/translator/ConstantUnion.h"
//
// Operators used by the high-level (parse tree) representation.
//
enum TOperator
struct TVectorFields
{
EOpNull, // if in a node, should only mean a node is still being built
EOpSequence, // denotes a list of statements, or parameters, etc.
EOpFunctionCall,
EOpFunction, // For function definition
EOpParameters, // an aggregate listing the parameters to a function
EOpDeclaration,
EOpPrototype,
//
// Unary operators
//
EOpNegative,
EOpLogicalNot,
EOpVectorLogicalNot,
EOpPostIncrement,
EOpPostDecrement,
EOpPreIncrement,
EOpPreDecrement,
//
// binary operations
//
EOpAdd,
EOpSub,
EOpMul,
EOpDiv,
EOpEqual,
EOpNotEqual,
EOpVectorEqual,
EOpVectorNotEqual,
EOpLessThan,
EOpGreaterThan,
EOpLessThanEqual,
EOpGreaterThanEqual,
EOpComma,
EOpVectorTimesScalar,
EOpVectorTimesMatrix,
EOpMatrixTimesVector,
EOpMatrixTimesScalar,
EOpLogicalOr,
EOpLogicalXor,
EOpLogicalAnd,
EOpIndexDirect,
EOpIndexIndirect,
EOpIndexDirectStruct,
EOpIndexDirectInterfaceBlock,
EOpVectorSwizzle,
//
// Built-in functions potentially mapped to operators
//
EOpRadians,
EOpDegrees,
EOpSin,
EOpCos,
EOpTan,
EOpAsin,
EOpAcos,
EOpAtan,
EOpPow,
EOpExp,
EOpLog,
EOpExp2,
EOpLog2,
EOpSqrt,
EOpInverseSqrt,
EOpAbs,
EOpSign,
EOpFloor,
EOpCeil,
EOpFract,
EOpMod,
EOpMin,
EOpMax,
EOpClamp,
EOpMix,
EOpStep,
EOpSmoothStep,
EOpLength,
EOpDistance,
EOpDot,
EOpCross,
EOpNormalize,
EOpFaceForward,
EOpReflect,
EOpRefract,
EOpDFdx, // Fragment only, OES_standard_derivatives extension
EOpDFdy, // Fragment only, OES_standard_derivatives extension
EOpFwidth, // Fragment only, OES_standard_derivatives extension
EOpMatrixTimesMatrix,
EOpAny,
EOpAll,
//
// Branch
//
EOpKill, // Fragment only
EOpReturn,
EOpBreak,
EOpContinue,
//
// Constructors
//
EOpConstructInt,
EOpConstructUInt,
EOpConstructBool,
EOpConstructFloat,
EOpConstructVec2,
EOpConstructVec3,
EOpConstructVec4,
EOpConstructBVec2,
EOpConstructBVec3,
EOpConstructBVec4,
EOpConstructIVec2,
EOpConstructIVec3,
EOpConstructIVec4,
EOpConstructUVec2,
EOpConstructUVec3,
EOpConstructUVec4,
EOpConstructMat2,
EOpConstructMat3,
EOpConstructMat4,
EOpConstructStruct,
//
// moves
//
EOpAssign,
EOpInitialize,
EOpAddAssign,
EOpSubAssign,
EOpMulAssign,
EOpVectorTimesMatrixAssign,
EOpVectorTimesScalarAssign,
EOpMatrixTimesScalarAssign,
EOpMatrixTimesMatrixAssign,
EOpDivAssign
int offsets[4];
int num;
};
class TIntermTraverser;
class TIntermAggregate;
class TIntermBinary;
class TIntermUnary;
class TIntermConstantUnion;
class TIntermSelection;
class TIntermTyped;
class TIntermSymbol;
class TIntermLoop;
//
// Set of helper functions to help parse and build the tree.
//
class TInfoSink;
class TIntermRaw;
//
// Base class for the tree nodes
//
class TIntermNode
class TIntermediate
{
public:
POOL_ALLOCATOR_NEW_DELETE();
TIntermNode()
{
// TODO: Move this to TSourceLoc constructor
// after getting rid of TPublicType.
mLine.first_file = mLine.last_file = 0;
mLine.first_line = mLine.last_line = 0;
}
virtual ~TIntermNode() { }
TIntermediate(TInfoSink &i)
: mInfoSink(i) { }
const TSourceLoc &getLine() const { return mLine; }
void setLine(const TSourceLoc &l) { mLine = l; }
TIntermSymbol *addSymbol(
int id, const TString &, const TType &, const TSourceLoc &);
TIntermTyped *addBinaryMath(
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
TIntermTyped *addAssign(
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
TIntermTyped *addIndex(
TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &);
TIntermTyped *addUnaryMath(
TOperator op, TIntermNode *child, const TSourceLoc &);
TIntermAggregate *growAggregate(
TIntermNode *left, TIntermNode *right, const TSourceLoc &);
TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &);
TIntermAggregate *setAggregateOperator(TIntermNode *, TOperator, const TSourceLoc &);
TIntermNode *addSelection(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &);
TIntermTyped *addSelection(
TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &);
TIntermTyped *addComma(
TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
TIntermConstantUnion *addConstantUnion(ConstantUnion *, const TType &, const TSourceLoc &);
// TODO(zmo): Get rid of default value.
bool parseConstTree(const TSourceLoc &, TIntermNode *, ConstantUnion *,
TOperator, TType, bool singleConstantParam = false);
TIntermNode *addLoop(TLoopType, TIntermNode *, TIntermTyped *, TIntermTyped *,
TIntermNode *, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &);
TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &);
bool postProcess(TIntermNode *);
void remove(TIntermNode *);
void outputTree(TIntermNode *);
virtual void traverse(TIntermTraverser *) = 0;
virtual TIntermTyped *getAsTyped() { return 0; }
virtual TIntermConstantUnion *getAsConstantUnion() { return 0; }
virtual TIntermAggregate *getAsAggregate() { return 0; }
virtual TIntermBinary *getAsBinaryNode() { return 0; }
virtual TIntermUnary *getAsUnaryNode() { return 0; }
virtual TIntermSelection *getAsSelectionNode() { return 0; }
virtual TIntermSymbol *getAsSymbolNode() { return 0; }
virtual TIntermLoop *getAsLoopNode() { return 0; }
virtual TIntermRaw *getAsRawNode() { return 0; }
private:
void operator=(TIntermediate &); // prevent assignments
// Replace a child node. Return true if |original| is a child
// node and it is replaced; otherwise, return false.
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement) = 0;
// For traversing a tree in no particular order, but using
// heap memory.
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const = 0;
protected:
TSourceLoc mLine;
TInfoSink & mInfoSink;
};
//
// This is just to help yacc.
//
struct TIntermNodePair
{
TIntermNode *node1;
TIntermNode *node2;
};
//
// Intermediate class for nodes that have a type.
//
class TIntermTyped : public TIntermNode
{
public:
TIntermTyped(const TType &t) : mType(t) { }
virtual TIntermTyped *getAsTyped() { return this; }
virtual bool hasSideEffects() const = 0;
void setType(const TType &t) { mType = t; }
const TType &getType() const { return mType; }
TType *getTypePointer() { return &mType; }
TBasicType getBasicType() const { return mType.getBasicType(); }
TQualifier getQualifier() const { return mType.getQualifier(); }
TPrecision getPrecision() const { return mType.getPrecision(); }
int getCols() const { return mType.getCols(); }
int getRows() const { return mType.getRows(); }
int getNominalSize() const { return mType.getNominalSize(); }
int getSecondarySize() const { return mType.getSecondarySize(); }
bool isInterfaceBlock() const { return mType.isInterfaceBlock(); }
bool isMatrix() const { return mType.isMatrix(); }
bool isArray() const { return mType.isArray(); }
bool isVector() const { return mType.isVector(); }
bool isScalar() const { return mType.isScalar(); }
bool isScalarInt() const { return mType.isScalarInt(); }
const char *getBasicString() const { return mType.getBasicString(); }
const char *getQualifierString() const { return mType.getQualifierString(); }
TString getCompleteString() const { return mType.getCompleteString(); }
int getArraySize() const { return mType.getArraySize(); }
protected:
TType mType;
};
//
// Handle for, do-while, and while loops.
//
enum TLoopType
{
ELoopFor,
ELoopWhile,
ELoopDoWhile
};
class TIntermLoop : public TIntermNode
{
public:
TIntermLoop(TLoopType type,
TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr,
TIntermNode *body)
: mType(type),
mInit(init),
mCond(cond),
mExpr(expr),
mBody(body),
mUnrollFlag(false) { }
virtual TIntermLoop *getAsLoopNode() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
TLoopType getType() const { return mType; }
TIntermNode *getInit() { return mInit; }
TIntermTyped *getCondition() { return mCond; }
TIntermTyped *getExpression() { return mExpr; }
TIntermNode *getBody() { return mBody; }
void setUnrollFlag(bool flag) { mUnrollFlag = flag; }
bool getUnrollFlag() const { return mUnrollFlag; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TLoopType mType;
TIntermNode *mInit; // for-loop initialization
TIntermTyped *mCond; // loop exit condition
TIntermTyped *mExpr; // for-loop expression
TIntermNode *mBody; // loop body
bool mUnrollFlag; // Whether the loop should be unrolled or not.
};
//
// Handle break, continue, return, and kill.
//
class TIntermBranch : public TIntermNode
{
public:
TIntermBranch(TOperator op, TIntermTyped *e)
: mFlowOp(op),
mExpression(e) { }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
TOperator getFlowOp() { return mFlowOp; }
TIntermTyped* getExpression() { return mExpression; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TOperator mFlowOp;
TIntermTyped *mExpression; // non-zero except for "return exp;" statements
};
//
// Nodes that correspond to symbols or constants in the source code.
//
class TIntermSymbol : public TIntermTyped
{
public:
// if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym.
// If sym comes from per process globalpoolallocator, then it causes increased memory usage
// per compile it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(int id, const TString &symbol, const TType &type)
: TIntermTyped(type),
mId(id)
{
mSymbol = symbol;
}
virtual bool hasSideEffects() const { return false; }
int getId() const { return mId; }
const TString &getSymbol() const { return mSymbol; }
void setId(int newId) { mId = newId; }
virtual void traverse(TIntermTraverser *);
virtual TIntermSymbol *getAsSymbolNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
protected:
int mId;
TString mSymbol;
};
// A Raw node stores raw code, that the translator will insert verbatim
// into the output stream. Useful for transformation operations that make
// complex code that might not fit naturally into the GLSL model.
class TIntermRaw : public TIntermTyped
{
public:
TIntermRaw(const TType &type, const TString &rawText)
: TIntermTyped(type),
mRawText(rawText) { }
virtual bool hasSideEffects() const { return false; }
TString getRawText() const { return mRawText; }
virtual void traverse(TIntermTraverser *);
virtual TIntermRaw *getAsRawNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
protected:
TString mRawText;
};
class TIntermConstantUnion : public TIntermTyped
{
public:
TIntermConstantUnion(ConstantUnion *unionPointer, const TType &type)
: TIntermTyped(type),
mUnionArrayPointer(unionPointer) { }
virtual bool hasSideEffects() const { return false; }
ConstantUnion *getUnionArrayPointer() const { return mUnionArrayPointer; }
int getIConst(size_t index) const
{
return mUnionArrayPointer ? mUnionArrayPointer[index].getIConst() : 0;
}
unsigned int getUConst(size_t index) const
{
return mUnionArrayPointer ? mUnionArrayPointer[index].getUConst() : 0;
}
float getFConst(size_t index) const
{
return mUnionArrayPointer ? mUnionArrayPointer[index].getFConst() : 0.0f;
}
bool getBConst(size_t index) const
{
return mUnionArrayPointer ? mUnionArrayPointer[index].getBConst() : false;
}
virtual TIntermConstantUnion *getAsConstantUnion() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
TIntermTyped *fold(TOperator, TIntermTyped *, TInfoSink &);
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
protected:
ConstantUnion *mUnionArrayPointer;
};
//
// Intermediate class for node types that hold operators.
//
class TIntermOperator : public TIntermTyped
{
public:
TOperator getOp() const { return mOp; }
void setOp(TOperator op) { mOp = op; }
bool isAssignment() const;
bool isConstructor() const;
virtual bool hasSideEffects() const { return isAssignment(); }
protected:
TIntermOperator(TOperator op)
: TIntermTyped(TType(EbtFloat, EbpUndefined)),
mOp(op) {}
TIntermOperator(TOperator op, const TType &type)
: TIntermTyped(type),
mOp(op) {}
TOperator mOp;
};
//
// Nodes for all the basic binary math operators.
//
class TIntermBinary : public TIntermOperator
{
public:
TIntermBinary(TOperator op)
: TIntermOperator(op),
mAddIndexClamp(false) {}
virtual TIntermBinary *getAsBinaryNode() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
virtual bool hasSideEffects() const
{
return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
}
void setLeft(TIntermTyped *node) { mLeft = node; }
void setRight(TIntermTyped *node) { mRight = node; }
TIntermTyped *getLeft() const { return mLeft; }
TIntermTyped *getRight() const { return mRight; }
bool promote(TInfoSink &);
void setAddIndexClamp() { mAddIndexClamp = true; }
bool getAddIndexClamp() { return mAddIndexClamp; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TIntermTyped* mLeft;
TIntermTyped* mRight;
// If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
bool mAddIndexClamp;
};
//
// Nodes for unary math operators.
//
class TIntermUnary : public TIntermOperator
{
public:
TIntermUnary(TOperator op, const TType &type)
: TIntermOperator(op, type),
mOperand(NULL),
mUseEmulatedFunction(false) {}
TIntermUnary(TOperator op)
: TIntermOperator(op),
mOperand(NULL),
mUseEmulatedFunction(false) {}
virtual void traverse(TIntermTraverser *);
virtual TIntermUnary *getAsUnaryNode() { return this; }
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
virtual bool hasSideEffects() const
{
return isAssignment() || mOperand->hasSideEffects();
}
void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; }
bool promote(TInfoSink &);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TIntermTyped *mOperand;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
bool mUseEmulatedFunction;
};
typedef TVector<TIntermNode *> TIntermSequence;
typedef TVector<int> TQualifierList;
//
// Nodes that operate on an arbitrary sized set of children.
//
class TIntermAggregate : public TIntermOperator
{
public:
TIntermAggregate()
: TIntermOperator(EOpNull),
mUserDefined(false),
mUseEmulatedFunction(false) { }
TIntermAggregate(TOperator op)
: TIntermOperator(op),
mUseEmulatedFunction(false) { }
~TIntermAggregate() { }
virtual TIntermAggregate *getAsAggregate() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
// Conservatively assume function calls and other aggregate operators have side-effects
virtual bool hasSideEffects() const { return true; }
TIntermSequence *getSequence() { return &mSequence; }
void setName(const TString &name) { mName = name; }
const TString &getName() const { return mName; }
void setUserDefined() { mUserDefined = true; }
bool isUserDefined() const { return mUserDefined; }
void setOptimize(bool optimize) { mOptimize = optimize; }
bool getOptimize() const { return mOptimize; }
void setDebug(bool debug) { mDebug = debug; }
bool getDebug() const { return mDebug; }
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator
TIntermSequence mSequence;
TString mName;
bool mUserDefined; // used for user defined function names
bool mOptimize;
bool mDebug;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
bool mUseEmulatedFunction;
};
//
// For if tests. Simplified since there is no switch statement.
//
class TIntermSelection : public TIntermTyped
{
public:
TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB)
: TIntermTyped(TType(EbtVoid, EbpUndefined)),
mCondition(cond),
mTrueBlock(trueB),
mFalseBlock(falseB) {}
TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB,
const TType &type)
: TIntermTyped(type),
mCondition(cond),
mTrueBlock(trueB),
mFalseBlock(falseB) {}
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
// Conservatively assume selections have side-effects
virtual bool hasSideEffects() const { return true; }
bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
TIntermNode *getCondition() const { return mCondition; }
TIntermNode *getTrueBlock() const { return mTrueBlock; }
TIntermNode *getFalseBlock() const { return mFalseBlock; }
TIntermSelection *getAsSelectionNode() { return this; }
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
TIntermTyped *mCondition;
TIntermNode *mTrueBlock;
TIntermNode *mFalseBlock;
};
enum Visit
{
PreVisit,
InVisit,
PostVisit
};
//
// For traversing the tree. User should derive from this,
// put their traversal specific data in it, and then pass
// it to a Traverse method.
//
// When using this, just fill in the methods for nodes you want visited.
// Return false from a pre-visit to skip visiting that node's subtree.
//
class TIntermTraverser
{
public:
POOL_ALLOCATOR_NEW_DELETE();
// TODO(zmo): remove default values.
TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false,
bool rightToLeft = false)
: preVisit(preVisit),
inVisit(inVisit),
postVisit(postVisit),
rightToLeft(rightToLeft),
mDepth(0),
mMaxDepth(0) {}
virtual ~TIntermTraverser() {}
virtual void visitSymbol(TIntermSymbol *) {}
virtual void visitRaw(TIntermRaw *) {}
virtual void visitConstantUnion(TIntermConstantUnion *) {}
virtual bool visitBinary(Visit, TIntermBinary *) { return true; }
virtual bool visitUnary(Visit, TIntermUnary *) { return true; }
virtual bool visitSelection(Visit, TIntermSelection *) { return true; }
virtual bool visitAggregate(Visit, TIntermAggregate *) { return true; }
virtual bool visitLoop(Visit, TIntermLoop *) { return true; }
virtual bool visitBranch(Visit, TIntermBranch *) { return true; }
int getMaxDepth() const { return mMaxDepth; }
void incrementDepth(TIntermNode *current)
{
mDepth++;
mMaxDepth = std::max(mMaxDepth, mDepth);
mPath.push_back(current);
}
void decrementDepth()
{
mDepth--;
mPath.pop_back();
}
TIntermNode *getParentNode()
{
return mPath.size() == 0 ? NULL : mPath.back();
}
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
static TString hash(const TString& name, ShHashFunction64 hashFunction);
const bool preVisit;
const bool inVisit;
const bool postVisit;
const bool rightToLeft;
protected:
int mDepth;
int mMaxDepth;
// All the nodes from root to the current node's parent during traversing.
TVector<TIntermNode *> mPath;
};
//
// For traversing the tree, and computing max depth.
// Takes a maximum depth limit to prevent stack overflow.
//
class TMaxDepthTraverser : public TIntermTraverser
{
public:
POOL_ALLOCATOR_NEW_DELETE();
TMaxDepthTraverser(int depthLimit)
: TIntermTraverser(true, true, false, false),
mDepthLimit(depthLimit) { }
virtual bool visitBinary(Visit, TIntermBinary *) { return depthCheck(); }
virtual bool visitUnary(Visit, TIntermUnary *) { return depthCheck(); }
virtual bool visitSelection(Visit, TIntermSelection *) { return depthCheck(); }
virtual bool visitAggregate(Visit, TIntermAggregate *) { return depthCheck(); }
virtual bool visitLoop(Visit, TIntermLoop *) { return depthCheck(); }
virtual bool visitBranch(Visit, TIntermBranch *) { return depthCheck(); }
protected:
bool depthCheck() const { return mMaxDepth < mDepthLimit; }
int mDepthLimit;
};
#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_
#endif // COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_

View File

@ -1,67 +0,0 @@
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
#define COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
#include "compiler/translator/intermediate.h"
struct TVectorFields
{
int offsets[4];
int num;
};
//
// Set of helper functions to help parse and build the tree.
//
class TInfoSink;
class TIntermediate
{
public:
POOL_ALLOCATOR_NEW_DELETE();
TIntermediate(TInfoSink &i)
: mInfoSink(i) { }
TIntermSymbol *addSymbol(
int id, const TString &, const TType &, const TSourceLoc &);
TIntermTyped *addBinaryMath(
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
TIntermTyped *addAssign(
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
TIntermTyped *addIndex(
TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &);
TIntermTyped *addUnaryMath(
TOperator op, TIntermNode *child, const TSourceLoc &);
TIntermAggregate *growAggregate(
TIntermNode *left, TIntermNode *right, const TSourceLoc &);
TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &);
TIntermAggregate *setAggregateOperator(TIntermNode *, TOperator, const TSourceLoc &);
TIntermNode *addSelection(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &);
TIntermTyped *addSelection(
TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &);
TIntermTyped *addComma(
TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
TIntermConstantUnion *addConstantUnion(ConstantUnion *, const TType &, const TSourceLoc &);
// TODO(zmo): Get rid of default value.
bool parseConstTree(const TSourceLoc &, TIntermNode *, ConstantUnion *,
TOperator, TType, bool singleConstantParam = false);
TIntermNode *addLoop(TLoopType, TIntermNode *, TIntermTyped *, TIntermTyped *,
TIntermNode *, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &);
TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &);
bool postProcess(TIntermNode *);
void remove(TIntermNode *);
void outputTree(TIntermNode *);
private:
void operator=(TIntermediate &); // prevent assignments
TInfoSink & mInfoSink;
};
#endif // COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_

View File

@ -7,7 +7,7 @@
#ifndef COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_
#define COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/depgraph/DependencyGraph.h"
class TInfoSinkBase;

View File

@ -7,7 +7,7 @@
#ifndef COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_
#define COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_
#include "compiler/translator/intermediate.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/InfoSink.h"
class TInfoSinkBase;

View File

@ -9,7 +9,6 @@
#include <limits>
#include "compiler/preprocessor/numeric_lex.h"
#include "common/shadervars.h"
#include "common/utilities.h"
bool atof_clamp(const char *str, float *value)
@ -269,6 +268,8 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
case EvqFragmentIn:
case EvqVaryingIn:
case EvqVaryingOut:
case EvqInvariantVaryingIn:
case EvqInvariantVaryingOut:
return INTERPOLATION_SMOOTH;
case EvqCentroidIn:
@ -281,7 +282,7 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
}
template <typename VarT>
void GetVariableTraverser<VarT>::traverse(const TType &type, const TString &name)
void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
{
const TStructure *structure = type.getStruct();
@ -296,61 +297,27 @@ void GetVariableTraverser<VarT>::traverse(const TType &type, const TString &name
}
else
{
// Note: this enum value is not exposed outside ANGLE
variable.type = GL_STRUCT_ANGLEX;
mOutputStack.push(&variable.fields);
variable.structName = structure->name().c_str();
const TFieldList &fields = structure->fields();
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
TField *field = fields[fieldIndex];
traverse(*field->type(), field->name());
traverse(*field->type(), field->name(), &variable.fields);
}
mOutputStack.pop();
}
visitVariable(&variable);
ASSERT(!mOutputStack.empty());
mOutputStack.top()->push_back(variable);
}
template <typename VarT>
GetVariableTraverser<VarT>::GetVariableTraverser(std::vector<VarT> *output)
{
ASSERT(output);
mOutputStack.push(output);
output->push_back(variable);
}
template class GetVariableTraverser<Uniform>;
template class GetVariableTraverser<Varying>;
template class GetVariableTraverser<InterfaceBlockField>;
GetInterfaceBlockFieldTraverser::GetInterfaceBlockFieldTraverser(std::vector<InterfaceBlockField> *output, bool isRowMajorMatrix)
: GetVariableTraverser(output),
mIsRowMajorMatrix(isRowMajorMatrix)
{
}
void GetInterfaceBlockFieldTraverser::visitVariable(InterfaceBlockField *newField)
{
if (gl::IsMatrixType(newField->type))
{
newField->isRowMajorMatrix = mIsRowMajorMatrix;
}
}
BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
{
switch (blockStorage)
{
case EbsPacked: return BLOCKLAYOUT_PACKED;
case EbsShared: return BLOCKLAYOUT_SHARED;
case EbsStd140: return BLOCKLAYOUT_STANDARD;
default: UNREACHABLE(); return BLOCKLAYOUT_SHARED;
}
}
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
}

View File

@ -9,9 +9,10 @@
#include <stack>
#include "compiler/translator/Types.h"
#include "angle_gl.h"
#include "common/shadervars.h"
#include <GLSLANG/ShaderLang.h>
#include "compiler/translator/Types.h"
// atof_clamp is like atof but
// 1. it forces C locale, i.e. forcing '.' as decimal point.
@ -32,33 +33,22 @@ bool IsVaryingIn(TQualifier qualifier);
bool IsVaryingOut(TQualifier qualifier);
bool IsVarying(TQualifier qualifier);
InterpolationType GetInterpolationType(TQualifier qualifier);
BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage);
TString ArrayString(const TType &type);
template <typename VarT>
class GetVariableTraverser
{
public:
GetVariableTraverser(std::vector<VarT> *output);
void traverse(const TType &type, const TString &name);
GetVariableTraverser() {}
template <typename VarT>
void traverse(const TType &type, const TString &name, std::vector<VarT> *output);
protected:
// May be overloaded
virtual void visitVariable(VarT *newVar) {}
virtual void visitVariable(ShaderVariable *newVar) {}
private:
std::stack<std::vector<VarT> *> mOutputStack;
};
struct GetInterfaceBlockFieldTraverser : public GetVariableTraverser<InterfaceBlockField>
{
public:
GetInterfaceBlockFieldTraverser(std::vector<InterfaceBlockField> *output, bool isRowMajorMatrix);
private:
virtual void visitVariable(InterfaceBlockField *newField);
bool mIsRowMajorMatrix;
DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
};
}

View File

@ -561,8 +561,10 @@ void Display::initDisplayExtensionString()
extensions.push_back("EGL_NV_post_sub_buffer");
}
#if defined (ANGLE_TEST_CONFIG)
// TODO: complete support for the EGL_KHR_create_context extension
//extensions.push_back("EGL_KHR_create_context");
extensions.push_back("EGL_KHR_create_context");
#endif
std::ostringstream stream;
std::copy(extensions.begin(), extensions.end(), std::ostream_iterator<std::string>(stream, " "));
@ -606,6 +608,7 @@ void Display::initVendorString()
{
char adapterLuidString[64];
snprintf(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
mVendorString += adapterLuidString;
}
}

View File

@ -6,6 +6,9 @@
// libEGL.cpp: Implements the exported EGL functions.
#undef EGLAPI
#define EGLAPI
#include <exception>
#include "common/debug.h"
@ -825,12 +828,19 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
egl::Display *display = static_cast<egl::Display*>(dpy);
gl::Context *context = static_cast<gl::Context*>(ctx);
bool noContext = (ctx == EGL_NO_CONTEXT);
bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE);
if (noContext != noSurface)
{
return egl::error(EGL_BAD_MATCH, EGL_FALSE);
}
if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
{
return EGL_FALSE;
}
if (dpy != EGL_NO_DISPLAY)
if (dpy != EGL_NO_DISPLAY && display->isInitialized())
{
rx::Renderer *renderer = display->getRenderer();
if (renderer->testDeviceLost(true))

View File

@ -105,15 +105,15 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
break;
case DLL_THREAD_DETACH:
{
#if !defined(ANGLE_PLATFORM_WINRT)
egl::DeallocateCurrent();
#endif
}
break;
case DLL_PROCESS_DETACH:
{
#if !defined(ANGLE_PLATFORM_WINRT)
egl::DeallocateCurrent();
DestroyTLSIndex(currentTLS);
#endif
}
break;
default:

View File

@ -9,8 +9,6 @@
#ifndef LIBEGL_MAIN_H_
#define LIBEGL_MAIN_H_
#undef EGLAPI
#define EGLAPI
#include <EGL/egl.h>
#include <EGL/eglext.h>

View File

@ -12,6 +12,10 @@
#include "common/angleutils.h"
#include "common/mathutil.h"
#include <cstddef>
#include <string>
#include <vector>
namespace gl
{

View File

@ -1,4 +1,3 @@
#include "precompiled.h"
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@ -31,59 +30,99 @@ Buffer::Buffer(rx::BufferImpl *impl, GLuint id)
Buffer::~Buffer()
{
delete mBuffer;
SafeDelete(mBuffer);
}
void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
{
gl::Error error = mBuffer->setData(data, size, usage);
if (error.isError())
{
return error;
}
mIndexRangeCache.clear();
mUsage = usage;
mSize = size;
mBuffer->setData(data, size, usage);
return error;
}
void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
{
mBuffer->setSubData(data, size, offset);
gl::Error error = mBuffer->setSubData(data, size, offset);
if (error.isError())
{
return error;
}
mIndexRangeCache.invalidateRange(offset, size);
return error;
}
void Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
{
mBuffer->copySubData(source->getImplementation(), size, sourceOffset, destOffset);
gl::Error error = mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size);
if (error.isError())
{
return error;
}
mIndexRangeCache.invalidateRange(destOffset, size);
return error;
}
GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
{
ASSERT(!mMapped);
ASSERT(offset + length <= mSize);
void *dataPointer = mBuffer->map(offset, length, access);
Error error = mBuffer->map(offset, length, access, &mMapPointer);
if (error.isError())
{
mMapPointer = NULL;
return error;
}
mMapped = GL_TRUE;
mMapPointer = static_cast<GLvoid*>(static_cast<GLubyte*>(dataPointer));
mMapOffset = static_cast<GLint64>(offset);
mMapLength = static_cast<GLint64>(length);
mAccessFlags = static_cast<GLint>(access);
return mMapPointer;
if ((access & GL_MAP_WRITE_BIT) > 0)
{
mIndexRangeCache.invalidateRange(offset, length);
}
return error;
}
void Buffer::unmap()
Error Buffer::unmap()
{
ASSERT(mMapped);
mBuffer->unmap();
Error error = mBuffer->unmap();
if (error.isError())
{
return error;
}
mMapped = GL_FALSE;
mMapPointer = NULL;
mMapOffset = 0;
mMapLength = 0;
mAccessFlags = 0;
return error;
}
void Buffer::markTransformFeedbackUsage()
{
// TODO: Only used by the DX11 backend. Refactor to a more appropriate place.
mBuffer->markTransformFeedbackUsage();
mIndexRangeCache.clear();
}
}

View File

@ -11,8 +11,11 @@
#ifndef LIBGLESV2_BUFFER_H_
#define LIBGLESV2_BUFFER_H_
#include "libGLESv2/Error.h"
#include "common/angleutils.h"
#include "common/RefCountObject.h"
#include "libGLESv2/renderer/IndexRangeCache.h"
namespace rx
{
@ -30,13 +33,13 @@ class Buffer : public RefCountObject
virtual ~Buffer();
void bufferData(const void *data, GLsizeiptr size, GLenum usage);
void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
void copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
GLvoid *mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
void unmap();
Error bufferData(const void *data, GLsizeiptr size, GLenum usage);
Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
Error unmap();
GLenum getUsage() const { return mUsage; }
GLenum getUsage() const { return mUsage; }
GLint getAccessFlags() const { return mAccessFlags; }
GLboolean isMapped() const { return mMapped; }
GLvoid *getMapPointer() const { return mMapPointer; }
@ -48,18 +51,23 @@ class Buffer : public RefCountObject
void markTransformFeedbackUsage();
rx::IndexRangeCache *getIndexRangeCache() { return &mIndexRangeCache; }
const rx::IndexRangeCache *getIndexRangeCache() const { return &mIndexRangeCache; }
private:
DISALLOW_COPY_AND_ASSIGN(Buffer);
rx::BufferImpl *mBuffer;
GLenum mUsage;
GLsizeiptr mSize;
GLint64 mSize;
GLint mAccessFlags;
GLboolean mMapped;
GLvoid *mMapPointer;
GLint64 mMapOffset;
GLint64 mMapLength;
rx::IndexRangeCache mIndexRangeCache;
};
}

View File

@ -24,6 +24,30 @@ TextureCaps::TextureCaps()
{
}
GLuint TextureCaps::getMaxSamples() const
{
return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0;
}
GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const
{
if (requestedSamples == 0)
{
return 0;
}
for (SupportedSampleSet::const_iterator i = sampleCounts.begin(); i != sampleCounts.end(); i++)
{
GLuint samples = *i;
if (samples >= requestedSamples)
{
return samples;
}
}
return 0;
}
void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps)
{
mCapsMap.insert(std::make_pair(internalFormat, caps));
@ -158,12 +182,17 @@ std::vector<std::string> Extensions::getStrings() const
}
static bool GetFormatSupport(const TextureCapsMap &textureCaps, const std::vector<GLenum> &requiredFormats,
bool requiresFiltering, bool requiresRendering)
bool requiresTexturing, bool requiresFiltering, bool requiresRendering)
{
for (size_t i = 0; i < requiredFormats.size(); i++)
{
const TextureCaps &cap = textureCaps.get(requiredFormats[i]);
if (requiresTexturing && !cap.texturable)
{
return false;
}
if (requiresFiltering && !cap.filterable)
{
return false;
@ -185,7 +214,7 @@ static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCap
requiredFormats.push_back(GL_RGB8);
requiredFormats.push_back(GL_RGBA8);
return GetFormatSupport(textureCaps, requiredFormats, true, true);
return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
}
// Checks for GL_EXT_texture_format_BGRA8888 support
@ -194,7 +223,7 @@ static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps)
std::vector<GLenum> requiredFormats;
requiredFormats.push_back(GL_BGRA8_EXT);
return GetFormatSupport(textureCaps, requiredFormats, true, true);
return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
}
// Checks for GL_OES_texture_half_float support
@ -204,7 +233,7 @@ static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
requiredFormats.push_back(GL_RGB16F);
requiredFormats.push_back(GL_RGBA16F);
return GetFormatSupport(textureCaps, requiredFormats, false, true);
return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
}
// Checks for GL_OES_texture_half_float_linear support
@ -214,7 +243,7 @@ static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &text
requiredFormats.push_back(GL_RGB16F);
requiredFormats.push_back(GL_RGBA16F);
return GetFormatSupport(textureCaps, requiredFormats, true, false);
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Checks for GL_OES_texture_float support
@ -224,7 +253,7 @@ static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps)
requiredFormats.push_back(GL_RGB32F);
requiredFormats.push_back(GL_RGBA32F);
return GetFormatSupport(textureCaps, requiredFormats, false, true);
return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
}
// Checks for GL_OES_texture_float_linear support
@ -234,7 +263,7 @@ static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureC
requiredFormats.push_back(GL_RGB32F);
requiredFormats.push_back(GL_RGBA32F);
return GetFormatSupport(textureCaps, requiredFormats, true, false);
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Checks for GL_EXT_texture_rg support
@ -254,7 +283,7 @@ static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps, bool ch
requiredFormats.push_back(GL_RG32F);
}
return GetFormatSupport(textureCaps, requiredFormats, true, false);
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Check for GL_EXT_texture_compression_dxt1
@ -264,7 +293,7 @@ static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps)
requiredFormats.push_back(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
return GetFormatSupport(textureCaps, requiredFormats, true, false);
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Check for GL_ANGLE_texture_compression_dxt3
@ -273,7 +302,7 @@ static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps)
std::vector<GLenum> requiredFormats;
requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
return GetFormatSupport(textureCaps, requiredFormats, true, false);
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Check for GL_ANGLE_texture_compression_dxt5
@ -282,7 +311,7 @@ static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps)
std::vector<GLenum> requiredFormats;
requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
return GetFormatSupport(textureCaps, requiredFormats, true, false);
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Check for GL_ANGLE_texture_compression_dxt5
@ -295,8 +324,8 @@ static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps)
std::vector<GLenum> requiredRenderFormats;
requiredRenderFormats.push_back(GL_SRGB8_ALPHA8);
return GetFormatSupport(textureCaps, requiredFilterFormats, true, false) &&
GetFormatSupport(textureCaps, requiredRenderFormats, false, true);
return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false) &&
GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true);
}
// Check for GL_ANGLE_depth_texture
@ -307,7 +336,7 @@ static bool DetermineDepthTextureSupport(const TextureCapsMap &textureCaps)
requiredFormats.push_back(GL_DEPTH_COMPONENT32_OES);
requiredFormats.push_back(GL_DEPTH24_STENCIL8_OES);
return GetFormatSupport(textureCaps, requiredFormats, true, true);
return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
}
// Check for GL_EXT_color_buffer_float
@ -322,7 +351,7 @@ static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps)
requiredFormats.push_back(GL_RGBA32F);
requiredFormats.push_back(GL_R11F_G11F_B10F);
return GetFormatSupport(textureCaps, requiredFormats, false, true);
return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
}
void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
@ -356,7 +385,40 @@ Caps::Caps()
maxViewportHeight(0),
minAliasedPointSize(0),
maxAliasedPointSize(0),
minAliasedLineWidth(0)
minAliasedLineWidth(0),
// Table 6.29
maxElementsIndices(0),
maxElementsVertices(0),
maxServerWaitTimeout(0),
// Table 6.31
maxVertexAttributes(0),
maxVertexUniformComponents(0),
maxVertexUniformVectors(0),
maxVertexUniformBlocks(0),
maxVertexOutputComponents(0),
maxVertexTextureImageUnits(0),
// Table 6.32
maxFragmentUniformComponents(0),
maxFragmentUniformVectors(0),
maxFragmentUniformBlocks(0),
maxFragmentInputComponents(0),
maxTextureImageUnits(0),
minProgramTexelOffset(0),
maxProgramTexelOffset(0),
maxUniformBufferBindings(0),
maxUniformBlockSize(0),
uniformBufferOffsetAlignment(0),
maxCombinedUniformBlocks(0),
maxCombinedVertexUniformComponents(0),
maxCombinedFragmentUniformComponents(0),
maxVaryingComponents(0),
maxVaryingVectors(0),
maxCombinedTextureImageUnits(0),
maxTransformFeedbackInterleavedComponents(0),
maxTransformFeedbackSeparateAttributes(0),
maxTransformFeedbackSeparateComponents(0)
{
}

View File

@ -17,6 +17,8 @@
namespace gl
{
typedef std::set<GLuint> SupportedSampleSet;
struct TextureCaps
{
TextureCaps();
@ -30,7 +32,14 @@ struct TextureCaps
// Support for being used as a framebuffer attachment or renderbuffer format
bool renderable;
std::set<GLuint> sampleCounts;
SupportedSampleSet sampleCounts;
// Get the maximum number of samples supported
GLuint getMaxSamples() const;
// Get the number of supported samples that is at least as many as requested. Returns 0 if
// there are no sample counts available
GLuint getNearestSamples(GLuint requestedSamples) const;
};
class TextureCapsMap
@ -68,6 +77,7 @@ struct Extensions
// GL_OES_texture_float, GL_OES_texture_float_linear
// GL_EXT_texture_rg
// GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3, GL_ANGLE_texture_compression_dxt5
// GL_EXT_sRGB
// GL_ANGLE_depth_texture
// GL_EXT_color_buffer_float
void setTextureExtensionSupport(const TextureCapsMap &textureCaps);
@ -166,6 +176,7 @@ struct Extensions
// GL_ANGLE_framebuffer_multisample
bool framebufferMultisample;
GLuint maxSamples;
// GL_ANGLE_instanced_arrays
bool instancedArrays;
@ -215,6 +226,46 @@ struct Caps
GLfloat minAliasedLineWidth;
GLfloat maxAliasedLineWidth;
// Table 6.29, implementation dependent values (cont.)
GLuint maxElementsIndices;
GLuint maxElementsVertices;
std::vector<GLenum> compressedTextureFormats;
std::vector<GLenum> programBinaryFormats;
std::vector<GLenum> shaderBinaryFormats;
GLuint64 maxServerWaitTimeout;
// Table 6.31, implementation dependent vertex shader limits
GLuint maxVertexAttributes;
GLuint maxVertexUniformComponents;
GLuint maxVertexUniformVectors;
GLuint maxVertexUniformBlocks;
GLuint maxVertexOutputComponents;
GLuint maxVertexTextureImageUnits;
// Table 6.32, implementation dependent fragment shader limits
GLuint maxFragmentUniformComponents;
GLuint maxFragmentUniformVectors;
GLuint maxFragmentUniformBlocks;
GLuint maxFragmentInputComponents;
GLuint maxTextureImageUnits;
GLint minProgramTexelOffset;
GLint maxProgramTexelOffset;
// Table 6.33, implementation dependent aggregate shader limits
GLuint maxUniformBufferBindings;
GLuint64 maxUniformBlockSize;
GLuint uniformBufferOffsetAlignment;
GLuint maxCombinedUniformBlocks;
GLuint64 maxCombinedVertexUniformComponents;
GLuint64 maxCombinedFragmentUniformComponents;
GLuint maxVaryingComponents;
GLuint maxVaryingVectors;
GLuint maxCombinedTextureImageUnits;
// Table 6.34, implementation dependent transform feedback limits
GLuint maxTransformFeedbackInterleavedComponents;
GLuint maxTransformFeedbackSeparateAttributes;
GLuint maxTransformFeedbackSeparateComponents;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,16 @@
#ifndef LIBGLESV2_CONTEXT_H_
#define LIBGLESV2_CONTEXT_H_
#include "common/angleutils.h"
#include "common/RefCountObject.h"
#include "libGLESv2/Caps.h"
#include "libGLESv2/Error.h"
#include "libGLESv2/HandleAllocator.h"
#include "libGLESv2/angletypes.h"
#include "libGLESv2/Constants.h"
#include "libGLESv2/VertexAttribute.h"
#include "libGLESv2/State.h"
#include "angle_gl.h"
#include <string>
@ -18,15 +28,6 @@
#include <unordered_map>
#include <array>
#include "common/angleutils.h"
#include "common/RefCountObject.h"
#include "libGLESv2/Caps.h"
#include "libGLESv2/HandleAllocator.h"
#include "libGLESv2/angletypes.h"
#include "libGLESv2/Constants.h"
#include "libGLESv2/VertexAttribute.h"
#include "libGLESv2/State.h"
namespace rx
{
class Renderer;
@ -114,10 +115,7 @@ class Context
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
void bindTexture2D(GLuint texture);
void bindTextureCubeMap(GLuint texture);
void bindTexture3D(GLuint texture);
void bindTexture2DArray(GLuint texture);
void bindTexture(GLenum target, GLuint texture);
void bindReadFramebuffer(GLuint framebuffer);
void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
@ -133,11 +131,11 @@ class Context
void bindPixelUnpackBuffer(GLuint buffer);
void useProgram(GLuint program);
void linkProgram(GLuint program);
void setProgramBinary(GLuint program, const void *binary, GLint length);
void setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
void bindTransformFeedback(GLuint transformFeedback);
void beginQuery(GLenum target, GLuint query);
void endQuery(GLenum target);
Error beginQuery(GLenum target, GLuint query);
Error endQuery(GLenum target);
void setFramebufferZero(Framebuffer *framebuffer);
@ -169,7 +167,7 @@ class Context
Texture3D *getTexture3D() const;
Texture2DArray *getTexture2DArray() const;
Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
bool isSampler(GLuint samplerName) const;
@ -184,22 +182,20 @@ class Context
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
void clear(GLbitfield mask);
void clearBufferfv(GLenum buffer, int drawbuffer, const float *values);
void clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values);
void clearBufferiv(GLenum buffer, int drawbuffer, const int *values);
void clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil);
Error clear(GLbitfield mask);
Error clearBufferfv(GLenum buffer, int drawbuffer, const float *values);
Error clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values);
Error clearBufferiv(GLenum buffer, int drawbuffer, const int *values);
Error clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil);
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
void drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances);
void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances);
Error readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
Error drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances);
Error drawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei instances,
const rx::RangeUI &indexRange);
void sync(bool block); // flush/finish
void recordInvalidEnum();
void recordInvalidValue();
void recordInvalidOperation();
void recordOutOfMemory();
void recordInvalidFramebufferOperation();
void recordError(const Error &error);
GLenum getError();
GLenum getResetStatus();
@ -211,15 +207,6 @@ class Context
const TextureCapsMap &getTextureCaps() const;
const Extensions &getExtensions() const;
int getMajorShaderModel() const;
unsigned int getMaximumCombinedTextureImageUnits() const;
unsigned int getMaximumCombinedUniformBufferBindings() const;
GLsizei getMaxSupportedSamples() const;
GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const;
GLsizei getNumSampleCounts(GLenum internalFormat) const;
void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const;
unsigned int getMaxTransformFeedbackBufferBindings() const;
GLintptr getUniformBufferOffsetAlignment() const;
const std::string &getRendererString() const;
const std::string &getExtensionString() const;
@ -231,29 +218,26 @@ class Context
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
void invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
GLint x, GLint y, GLsizei width, GLsizei height);
bool hasMappedBuffer(GLenum target) const;
rx::Renderer *getRenderer() { return mRenderer; }
State &getState() { return mState; }
const State &getState() const { return mState; }
void releaseShaderCompiler();
private:
DISALLOW_COPY_AND_ASSIGN(Context);
// TODO: std::array may become unavailable using older versions of GCC
typedef std::array<unsigned int, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray;
bool applyRenderTarget(GLenum drawMode, bool ignoreViewport);
void applyState(GLenum drawMode);
void applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive);
void applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
size_t framebufferSerialCount);
bool applyUniformBuffers();
Error applyRenderTarget(GLenum drawMode, bool ignoreViewport);
Error applyState(GLenum drawMode);
Error applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive);
Error applyTextures(ProgramBinary *programBinary, SamplerType shaderType, const FramebufferTextureSerialArray &framebufferSerials,
size_t framebufferSerialCount);
Error applyTextures(ProgramBinary *programBinary);
Error applyUniformBuffers();
bool applyTransformFeedbackBuffers();
void markTransformFeedbackUsage();
@ -265,10 +249,10 @@ class Context
void detachTransformFeedback(GLuint transformFeedback);
void detachSampler(GLuint sampler);
void generateSwizzles(Texture *textures[], size_t count);
size_t getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
TextureType *outTextureTypes, SamplerState *outSamplers);
Texture *getIncompleteTexture(TextureType type);
Error generateSwizzles(ProgramBinary *programBinary, SamplerType type);
Error generateSwizzles(ProgramBinary *programBinary);
Texture *getIncompleteTexture(GLenum type);
bool skipDraw(GLenum drawMode);
@ -289,10 +273,9 @@ class Context
int mClientVersion;
BindingPointer<Texture2D> mTexture2DZero;
BindingPointer<TextureCubeMap> mTextureCubeMapZero;
BindingPointer<Texture3D> mTexture3DZero;
BindingPointer<Texture2DArray> mTexture2DArrayZero;
typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
TextureMap mZeroTextures;
TextureMap mIncompleteTextures;
typedef std::unordered_map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap;
@ -319,14 +302,9 @@ class Context
std::string mExtensionString;
std::vector<std::string> mExtensionStrings;
BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT];
// Recorded errors
bool mInvalidEnum;
bool mInvalidValue;
bool mInvalidOperation;
bool mOutOfMemory;
bool mInvalidFramebufferOperation;
typedef std::set<GLenum> ErrorSet;
ErrorSet mErrors;
// Current/lost context flags
bool mHasBeenCurrent;
@ -335,10 +313,6 @@ class Context
GLenum mResetStrategy;
bool mRobustAccess;
int mMajorShaderModel;
bool mSupportsVertexTexture;
int mNumCompressedTextureFormats;
ResourceManager *mResourceManager;
};
}

View File

@ -1,96 +0,0 @@
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DynamicHLSL.h: Interface for link and run-time HLSL generation
//
#ifndef LIBGLESV2_DYNAMIC_HLSL_H_
#define LIBGLESV2_DYNAMIC_HLSL_H_
#include "common/angleutils.h"
#include "libGLESv2/constants.h"
namespace rx
{
class Renderer;
}
namespace sh
{
struct Attribute;
struct ShaderVariable;
}
namespace gl
{
class InfoLog;
class FragmentShader;
class VertexShader;
struct VariableLocation;
struct LinkedVarying;
struct VertexAttribute;
struct VertexFormat;
struct PackedVarying;
typedef const PackedVarying *VaryingPacking[IMPLEMENTATION_MAX_VARYING_VECTORS][4];
struct PixelShaderOuputVariable
{
GLenum type;
std::string name;
std::string source;
size_t outputIndex;
};
class DynamicHLSL
{
public:
explicit DynamicHLSL(rx::Renderer *const renderer);
int packVaryings(InfoLog &infoLog, VaryingPacking packing, FragmentShader *fragmentShader,
VertexShader *vertexShader, const std::vector<std::string>& transformFeedbackVaryings);
std::string generateVertexShaderForInputLayout(const std::string &sourceShader, const VertexFormat inputLayout[],
const sh::Attribute shaderAttributes[]) const;
std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOuputVariable> &outputVariables,
bool usesFragDepth, const std::vector<GLenum> &outputLayout) const;
bool generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing,
std::string& pixelHLSL, std::string& vertexHLSL,
FragmentShader *fragmentShader, VertexShader *vertexShader,
const std::vector<std::string>& transformFeedbackVaryings,
std::vector<LinkedVarying> *linkedVaryings,
std::map<int, VariableLocation> *programOutputVars,
std::vector<PixelShaderOuputVariable> *outPixelShaderKey,
bool *outUsesFragDepth) const;
std::string generateGeometryShaderHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const;
void getInputLayoutSignature(const VertexFormat inputLayout[], GLenum signature[]) const;
private:
DISALLOW_COPY_AND_ASSIGN(DynamicHLSL);
rx::Renderer *const mRenderer;
struct SemanticInfo;
std::string getVaryingSemantic(bool pointSize) const;
SemanticInfo getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, bool pointSize,
bool pixelShader) const;
std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
std::string generateVaryingHLSL(VertexShader *shader) const;
void storeUserLinkedVaryings(const VertexShader *vertexShader, std::vector<LinkedVarying> *linkedVaryings) const;
void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<LinkedVarying> *linkedVaryings) const;
void defineOutputVariables(FragmentShader *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const;
std::string generatePointSpriteHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const;
// Prepend an underscore
static std::string decorateVariable(const std::string &name);
std::string generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const;
};
}
#endif // LIBGLESV2_DYNAMIC_HLSL_H_

View File

@ -0,0 +1,48 @@
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Error.cpp: Implements the gl::Error class which encapsulates an OpenGL error
// and optional error message.
#include "libGLESv2/Error.h"
#include "common/angleutils.h"
#include <cstdarg>
namespace gl
{
Error::Error(GLenum errorCode)
: mCode(errorCode),
mMessage()
{
}
Error::Error(GLenum errorCode, const char *msg, ...)
: mCode(errorCode),
mMessage()
{
va_list vararg;
va_start(vararg, msg);
mMessage = FormatString(msg, vararg);
va_end(vararg);
}
Error::Error(const Error &other)
: mCode(other.mCode),
mMessage(other.mMessage)
{
}
Error &Error::operator=(const Error &other)
{
mCode = other.mCode;
mMessage = other.mMessage;
return *this;
}
}

View File

@ -0,0 +1,39 @@
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Error.h: Defines the gl::Error class which encapsulates an OpenGL error
// and optional error message.
#ifndef LIBGLESV2_ERROR_H_
#define LIBGLESV2_ERROR_H_
#include "angle_gl.h"
#include <string>
namespace gl
{
class Error
{
public:
explicit Error(GLenum errorCode);
Error(GLenum errorCode, const char *msg, ...);
Error(const Error &other);
Error &operator=(const Error &other);
GLenum getCode() const { return mCode; }
bool isError() const { return (mCode != GL_NO_ERROR); }
const std::string &getMessage() const { return mMessage; }
private:
GLenum mCode;
std::string mMessage;
};
}
#endif // LIBGLESV2_ERROR_H_

View File

@ -1,4 +1,3 @@
#include "precompiled.h"
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@ -23,6 +22,8 @@
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/main.h"
#include "angle_gl.h"
namespace gl
{

View File

@ -1,4 +1,3 @@
#include "precompiled.h"
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be

View File

@ -1,4 +1,3 @@
#include "precompiled.h"
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@ -9,15 +8,60 @@
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/main.h"
#include "common/utilities.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/RenderTarget.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
#include "common/utilities.h"
namespace rx
{
RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
{
if (attachment->isTexture())
{
gl::Texture *texture = attachment->getTexture();
ASSERT(texture);
TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
const gl::ImageIndex *index = attachment->getTextureImageIndex();
ASSERT(index);
return textureD3D->getRenderTarget(*index);
}
gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
ASSERT(renderbuffer);
// TODO: cast to RenderbufferD3D
return renderbuffer->getStorage()->getRenderTarget();
}
// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
{
if (attachment->isTexture())
{
gl::Texture *texture = attachment->getTexture();
ASSERT(texture);
TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
const gl::ImageIndex *index = attachment->getTextureImageIndex();
ASSERT(index);
return textureD3D->getRenderTargetSerial(*index);
}
gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
ASSERT(renderbuffer);
// TODO: cast to RenderbufferD3D
return renderbuffer->getStorage()->getSerial();
}
}
namespace gl
{
@ -47,7 +91,7 @@ Framebuffer::~Framebuffer()
SafeDelete(mStencilbuffer);
}
FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const
FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const
{
if (handle == 0)
{
@ -62,15 +106,14 @@ FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle,
return NULL;
case GL_RENDERBUFFER:
return new RenderbufferAttachment(context->getRenderbuffer(handle));
return new RenderbufferAttachment(binding, context->getRenderbuffer(handle));
case GL_TEXTURE_2D:
{
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_2D)
{
Texture2D *tex2D = static_cast<Texture2D*>(texture);
return new Texture2DAttachment(tex2D, level);
return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
}
else
{
@ -88,8 +131,7 @@ FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle,
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
{
TextureCubeMap *texCube = static_cast<TextureCubeMap*>(texture);
return new TextureCubeMapAttachment(texCube, type, level);
return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
}
else
{
@ -102,8 +144,7 @@ FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle,
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_3D)
{
Texture3D *tex3D = static_cast<Texture3D*>(texture);
return new Texture3DAttachment(tex3D, level, layer);
return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
}
else
{
@ -116,8 +157,7 @@ FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle,
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
{
Texture2DArray *tex2DArray = static_cast<Texture2DArray*>(texture);
return new Texture2DArrayAttachment(tex2DArray, level, layer);
return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
}
else
{
@ -135,24 +175,25 @@ void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLui
{
ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
SafeDelete(mColorbuffers[colorAttachment]);
mColorbuffers[colorAttachment] = createAttachment(type, colorbuffer, level, layer);
GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0;
mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer);
}
void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
{
SafeDelete(mDepthbuffer);
mDepthbuffer = createAttachment(type, depthbuffer, level, layer);
mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
}
void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
{
SafeDelete(mStencilbuffer);
mStencilbuffer = createAttachment(type, stencilbuffer, level, layer);
mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
}
void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
{
FramebufferAttachment *attachment = createAttachment(type, depthStencilBuffer, level, layer);
FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
SafeDelete(mDepthbuffer);
SafeDelete(mStencilbuffer);
@ -164,7 +205,7 @@ void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer,
// Make a new attachment object to ensure we do not double-delete
// See angle issue 686
mStencilbuffer = createAttachment(type, depthStencilBuffer, level, layer);
mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
}
}
@ -364,6 +405,7 @@ GLenum Framebuffer::completeness() const
GLenum internalformat = colorbuffer->getInternalFormat();
// TODO(geofflang): use context's texture caps
const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (colorbuffer->isTexture())
{
if (!formatCaps.renderable)
@ -371,14 +413,14 @@ GLenum Framebuffer::completeness() const
return GL_FRAMEBUFFER_UNSUPPORTED;
}
if (gl::GetDepthBits(internalformat) > 0 || gl::GetStencilBits(internalformat) > 0)
if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
if (!formatCaps.renderable || gl::GetDepthBits(internalformat) > 0 || gl::GetStencilBits(internalformat) > 0)
if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@ -403,7 +445,7 @@ GLenum Framebuffer::completeness() const
// in GLES 3.0, there is no such restriction
if (clientVersion < 3)
{
if (gl::GetPixelBytes(colorbuffer->getInternalFormat()) != colorbufferSize)
if (formatInfo.pixelBytes != colorbufferSize)
{
return GL_FRAMEBUFFER_UNSUPPORTED;
}
@ -427,7 +469,7 @@ GLenum Framebuffer::completeness() const
width = colorbuffer->getWidth();
height = colorbuffer->getHeight();
samples = colorbuffer->getSamples();
colorbufferSize = gl::GetPixelBytes(colorbuffer->getInternalFormat());
colorbufferSize = formatInfo.pixelBytes;
missingAttachment = false;
}
}
@ -443,10 +485,9 @@ GLenum Framebuffer::completeness() const
GLenum internalformat = mDepthbuffer->getInternalFormat();
// TODO(geofflang): use context's texture caps
const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (mDepthbuffer->isTexture())
{
GLenum internalformat = mDepthbuffer->getInternalFormat();
// depth texture attachments require OES/ANGLE_depth_texture
// TODO(geofflang): use context's extensions
if (!mRenderer->getRendererExtensions().depthTextures)
@ -459,14 +500,14 @@ GLenum Framebuffer::completeness() const
return GL_FRAMEBUFFER_UNSUPPORTED;
}
if (gl::GetDepthBits(internalformat) == 0)
if (formatInfo.depthBits == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
if (!formatCaps.renderable || gl::GetDepthBits(internalformat) == 0)
if (!formatCaps.renderable || formatInfo.depthBits == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@ -499,10 +540,9 @@ GLenum Framebuffer::completeness() const
GLenum internalformat = mStencilbuffer->getInternalFormat();
// TODO(geofflang): use context's texture caps
const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (mStencilbuffer->isTexture())
{
GLenum internalformat = mStencilbuffer->getInternalFormat();
// texture stencil attachments come along as part
// of OES_packed_depth_stencil + OES/ANGLE_depth_texture
// TODO(geofflang): use context's extensions
@ -516,14 +556,14 @@ GLenum Framebuffer::completeness() const
return GL_FRAMEBUFFER_UNSUPPORTED;
}
if (gl::GetStencilBits(internalformat) == 0)
if (formatInfo.stencilBits == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
if (!formatCaps.renderable || gl::GetStencilBits(internalformat) == 0)
if (!formatCaps.renderable || formatInfo.stencilBits == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@ -562,18 +602,47 @@ GLenum Framebuffer::completeness() const
return GL_FRAMEBUFFER_COMPLETE;
}
void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
{
GLuint maxDimension = caps.maxRenderbufferSize;
invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
}
void Framebuffer::invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
GLint x, GLint y, GLsizei width, GLsizei height)
{
ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE);
for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
{
GLenum attachmentTarget = attachments[attachIndex];
gl::FramebufferAttachment *attachment =
(attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() :
getAttachment(attachmentTarget);
if (attachment)
{
rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
if (renderTarget)
{
renderTarget->invalidate(x, y, width, height);
}
}
}
}
DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
: Framebuffer(renderer, 0)
{
Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer);
mColorbuffers[0] = new RenderbufferAttachment(colorRenderbuffer);
mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
// Make a new attachment objects to ensure we do not double-delete
// See angle issue 686
mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(depthStencilBuffer) : NULL);
mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(depthStencilBuffer) : NULL);
mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
mDrawBufferStates[0] = GL_BACK;
mReadBufferState = GL_BACK;
@ -606,6 +675,31 @@ bool Framebuffer::hasValidDepthStencil() const
mDepthbuffer->id() == mStencilbuffer->id());
}
ColorbufferInfo Framebuffer::getColorbuffersForRender() const
{
ColorbufferInfo colorbuffersForRender;
for (size_t colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; ++colorAttachment)
{
GLenum drawBufferState = mDrawBufferStates[colorAttachment];
FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
if (colorbuffer != NULL && drawBufferState != GL_NONE)
{
ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
colorbuffersForRender.push_back(colorbuffer);
}
#if (ANGLE_MRT_PERF_WORKAROUND == ANGLE_WORKAROUND_DISABLED)
else
{
colorbuffersForRender.push_back(NULL);
}
#endif
}
return colorbuffersForRender;
}
GLenum DefaultFramebuffer::completeness() const
{
// The default framebuffer *must* always be complete, though it may not be
@ -617,6 +711,7 @@ FramebufferAttachment *DefaultFramebuffer::getAttachment(GLenum attachment) cons
{
switch (attachment)
{
case GL_COLOR:
case GL_BACK:
return getColorbuffer(0);
case GL_DEPTH:

View File

@ -10,6 +10,8 @@
#ifndef LIBGLESV2_FRAMEBUFFER_H_
#define LIBGLESV2_FRAMEBUFFER_H_
#include <vector>
#include "common/angleutils.h"
#include "common/RefCountObject.h"
#include "constants.h"
@ -26,6 +28,9 @@ class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
class DepthStencilbuffer;
struct Caps;
typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
class Framebuffer
{
@ -67,6 +72,15 @@ class Framebuffer
virtual GLenum completeness() const;
bool hasValidDepthStencil() const;
void invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
void invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
GLint x, GLint y, GLsizei width, GLsizei height);
// Use this method to retrieve the color buffer map when doing rendering.
// It will apply a workaround for poor shader performance on some systems
// by compacting the list to skip NULL values.
ColorbufferInfo getColorbuffersForRender() const;
protected:
rx::Renderer *mRenderer;
@ -79,10 +93,10 @@ class Framebuffer
FramebufferAttachment *mDepthbuffer;
FramebufferAttachment *mStencilbuffer;
private:
private:
DISALLOW_COPY_AND_ASSIGN(Framebuffer);
FramebufferAttachment *createAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const;
FramebufferAttachment *createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const;
};
class DefaultFramebuffer : public Framebuffer
@ -99,4 +113,14 @@ class DefaultFramebuffer : public Framebuffer
}
namespace rx
{
class RenderTarget;
// TODO: place this in FramebufferD3D.h
RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment);
}
#endif // LIBGLESV2_FRAMEBUFFER_H_

View File

@ -1,4 +1,3 @@
#include "precompiled.h"
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@ -9,21 +8,22 @@
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/renderer/RenderTarget.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/d3d/TextureStorage.h"
#include "common/utilities.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/renderer/RenderTarget.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/d3d/TextureStorage.h"
#include "common/utilities.h"
namespace gl
{
////// FramebufferAttachment Implementation //////
FramebufferAttachment::FramebufferAttachment()
FramebufferAttachment::FramebufferAttachment(GLenum binding)
: mBinding(binding)
{
}
@ -33,42 +33,42 @@ FramebufferAttachment::~FramebufferAttachment()
GLuint FramebufferAttachment::getRedSize() const
{
return (gl::GetRedBits(getInternalFormat()) > 0) ? gl::GetRedBits(getActualFormat()) : 0;
return (GetInternalFormatInfo(getInternalFormat()).redBits > 0) ? GetInternalFormatInfo(getActualFormat()).redBits : 0;
}
GLuint FramebufferAttachment::getGreenSize() const
{
return (gl::GetGreenBits(getInternalFormat()) > 0) ? gl::GetGreenBits(getActualFormat()) : 0;
return (GetInternalFormatInfo(getInternalFormat()).greenBits > 0) ? GetInternalFormatInfo(getActualFormat()).greenBits : 0;
}
GLuint FramebufferAttachment::getBlueSize() const
{
return (gl::GetBlueBits(getInternalFormat()) > 0) ? gl::GetBlueBits(getActualFormat()) : 0;
return (GetInternalFormatInfo(getInternalFormat()).blueBits > 0) ? GetInternalFormatInfo(getActualFormat()).blueBits : 0;
}
GLuint FramebufferAttachment::getAlphaSize() const
{
return (gl::GetAlphaBits(getInternalFormat()) > 0) ? gl::GetAlphaBits(getActualFormat()) : 0;
return (GetInternalFormatInfo(getInternalFormat()).alphaBits > 0) ? GetInternalFormatInfo(getActualFormat()).alphaBits : 0;
}
GLuint FramebufferAttachment::getDepthSize() const
{
return (gl::GetDepthBits(getInternalFormat()) > 0) ? gl::GetDepthBits(getActualFormat()) : 0;
return (GetInternalFormatInfo(getInternalFormat()).depthBits > 0) ? GetInternalFormatInfo(getActualFormat()).depthBits : 0;
}
GLuint FramebufferAttachment::getStencilSize() const
{
return (gl::GetStencilBits(getInternalFormat()) > 0) ? gl::GetStencilBits(getActualFormat()) : 0;
return (GetInternalFormatInfo(getInternalFormat()).stencilBits > 0) ? GetInternalFormatInfo(getActualFormat()).stencilBits : 0;
}
GLenum FramebufferAttachment::getComponentType() const
{
return gl::GetComponentType(getActualFormat());
return GetInternalFormatInfo(getActualFormat()).componentType;
}
GLenum FramebufferAttachment::getColorEncoding() const
{
return gl::GetColorEncoding(getActualFormat());
return GetInternalFormatInfo(getActualFormat()).colorEncoding;
}
bool FramebufferAttachment::isTexture() const
@ -76,340 +76,85 @@ bool FramebufferAttachment::isTexture() const
return (type() != GL_RENDERBUFFER);
}
///// Texture2DAttachment Implementation ////////
///// TextureAttachment Implementation ////////
Texture2DAttachment::Texture2DAttachment(Texture2D *texture, GLint level) : mLevel(level)
TextureAttachment::TextureAttachment(GLenum binding, Texture *texture, const ImageIndex &index)
: FramebufferAttachment(binding),
mIndex(index)
{
mTexture2D.set(texture);
mTexture.set(texture);
}
Texture2DAttachment::~Texture2DAttachment()
TextureAttachment::~TextureAttachment()
{
mTexture2D.set(NULL);
mTexture.set(NULL);
}
rx::RenderTarget *Texture2DAttachment::getRenderTarget()
{
return mTexture2D->getRenderTarget(mLevel);
}
rx::RenderTarget *Texture2DAttachment::getDepthStencil()
{
return mTexture2D->getDepthSencil(mLevel);
}
rx::TextureStorage *Texture2DAttachment::getTextureStorage()
{
return mTexture2D->getNativeTexture()->getStorageInstance();
}
GLsizei Texture2DAttachment::getWidth() const
{
return mTexture2D->getWidth(mLevel);
}
GLsizei Texture2DAttachment::getHeight() const
{
return mTexture2D->getHeight(mLevel);
}
GLenum Texture2DAttachment::getInternalFormat() const
{
return mTexture2D->getInternalFormat(mLevel);
}
GLenum Texture2DAttachment::getActualFormat() const
{
return mTexture2D->getActualFormat(mLevel);
}
GLsizei Texture2DAttachment::getSamples() const
GLsizei TextureAttachment::getSamples() const
{
return 0;
}
unsigned int Texture2DAttachment::getSerial() const
GLuint TextureAttachment::id() const
{
return mTexture2D->getRenderTargetSerial(mLevel);
return mTexture->id();
}
GLuint Texture2DAttachment::id() const
GLsizei TextureAttachment::getWidth() const
{
return mTexture2D->id();
return mTexture->getWidth(mIndex);
}
GLenum Texture2DAttachment::type() const
GLsizei TextureAttachment::getHeight() const
{
return GL_TEXTURE_2D;
return mTexture->getHeight(mIndex);
}
GLint Texture2DAttachment::mipLevel() const
GLenum TextureAttachment::getInternalFormat() const
{
return mLevel;
return mTexture->getInternalFormat(mIndex);
}
GLint Texture2DAttachment::layer() const
GLenum TextureAttachment::getActualFormat() const
{
return 0;
return mTexture->getActualFormat(mIndex);
}
unsigned int Texture2DAttachment::getTextureSerial() const
GLenum TextureAttachment::type() const
{
return mTexture2D->getTextureSerial();
return mIndex.type;
}
///// TextureCubeMapAttachment Implementation ////////
TextureCubeMapAttachment::TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level)
: mFaceTarget(faceTarget), mLevel(level)
GLint TextureAttachment::mipLevel() const
{
mTextureCubeMap.set(texture);
return mIndex.mipIndex;
}
TextureCubeMapAttachment::~TextureCubeMapAttachment()
GLint TextureAttachment::layer() const
{
mTextureCubeMap.set(NULL);
return mIndex.layerIndex;
}
rx::RenderTarget *TextureCubeMapAttachment::getRenderTarget()
Texture *TextureAttachment::getTexture()
{
return mTextureCubeMap->getRenderTarget(mFaceTarget, mLevel);
return mTexture.get();
}
rx::RenderTarget *TextureCubeMapAttachment::getDepthStencil()
const ImageIndex *TextureAttachment::getTextureImageIndex() const
{
return mTextureCubeMap->getDepthStencil(mFaceTarget, mLevel);
return &mIndex;
}
rx::TextureStorage *TextureCubeMapAttachment::getTextureStorage()
Renderbuffer *TextureAttachment::getRenderbuffer()
{
return mTextureCubeMap->getNativeTexture()->getStorageInstance();
}
GLsizei TextureCubeMapAttachment::getWidth() const
{
return mTextureCubeMap->getWidth(mFaceTarget, mLevel);
}
GLsizei TextureCubeMapAttachment::getHeight() const
{
return mTextureCubeMap->getHeight(mFaceTarget, mLevel);
}
GLenum TextureCubeMapAttachment::getInternalFormat() const
{
return mTextureCubeMap->getInternalFormat(mFaceTarget, mLevel);
}
GLenum TextureCubeMapAttachment::getActualFormat() const
{
return mTextureCubeMap->getActualFormat(mFaceTarget, mLevel);
}
GLsizei TextureCubeMapAttachment::getSamples() const
{
return 0;
}
unsigned int TextureCubeMapAttachment::getSerial() const
{
return mTextureCubeMap->getRenderTargetSerial(mFaceTarget, mLevel);
}
GLuint TextureCubeMapAttachment::id() const
{
return mTextureCubeMap->id();
}
GLenum TextureCubeMapAttachment::type() const
{
return mFaceTarget;
}
GLint TextureCubeMapAttachment::mipLevel() const
{
return mLevel;
}
GLint TextureCubeMapAttachment::layer() const
{
return 0;
}
unsigned int TextureCubeMapAttachment::getTextureSerial() const
{
return mTextureCubeMap->getTextureSerial();
}
///// Texture3DAttachment Implementation ////////
Texture3DAttachment::Texture3DAttachment(Texture3D *texture, GLint level, GLint layer)
: mLevel(level), mLayer(layer)
{
mTexture3D.set(texture);
}
Texture3DAttachment::~Texture3DAttachment()
{
mTexture3D.set(NULL);
}
rx::RenderTarget *Texture3DAttachment::getRenderTarget()
{
return mTexture3D->getRenderTarget(mLevel, mLayer);
}
rx::RenderTarget *Texture3DAttachment::getDepthStencil()
{
return mTexture3D->getDepthStencil(mLevel, mLayer);
}
rx::TextureStorage *Texture3DAttachment::getTextureStorage()
{
return mTexture3D->getNativeTexture()->getStorageInstance();
}
GLsizei Texture3DAttachment::getWidth() const
{
return mTexture3D->getWidth(mLevel);
}
GLsizei Texture3DAttachment::getHeight() const
{
return mTexture3D->getHeight(mLevel);
}
GLenum Texture3DAttachment::getInternalFormat() const
{
return mTexture3D->getInternalFormat(mLevel);
}
GLenum Texture3DAttachment::getActualFormat() const
{
return mTexture3D->getActualFormat(mLevel);
}
GLsizei Texture3DAttachment::getSamples() const
{
return 0;
}
unsigned int Texture3DAttachment::getSerial() const
{
return mTexture3D->getRenderTargetSerial(mLevel, mLayer);
}
GLuint Texture3DAttachment::id() const
{
return mTexture3D->id();
}
GLenum Texture3DAttachment::type() const
{
return GL_TEXTURE_3D;
}
GLint Texture3DAttachment::mipLevel() const
{
return mLevel;
}
GLint Texture3DAttachment::layer() const
{
return mLayer;
}
unsigned int Texture3DAttachment::getTextureSerial() const
{
return mTexture3D->getTextureSerial();
}
////// Texture2DArrayAttachment Implementation //////
Texture2DArrayAttachment::Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer)
: mLevel(level), mLayer(layer)
{
mTexture2DArray.set(texture);
}
Texture2DArrayAttachment::~Texture2DArrayAttachment()
{
mTexture2DArray.set(NULL);
}
rx::RenderTarget *Texture2DArrayAttachment::getRenderTarget()
{
return mTexture2DArray->getRenderTarget(mLevel, mLayer);
}
rx::RenderTarget *Texture2DArrayAttachment::getDepthStencil()
{
return mTexture2DArray->getDepthStencil(mLevel, mLayer);
}
rx::TextureStorage *Texture2DArrayAttachment::getTextureStorage()
{
return mTexture2DArray->getNativeTexture()->getStorageInstance();
}
GLsizei Texture2DArrayAttachment::getWidth() const
{
return mTexture2DArray->getWidth(mLevel);
}
GLsizei Texture2DArrayAttachment::getHeight() const
{
return mTexture2DArray->getHeight(mLevel);
}
GLenum Texture2DArrayAttachment::getInternalFormat() const
{
return mTexture2DArray->getInternalFormat(mLevel);
}
GLenum Texture2DArrayAttachment::getActualFormat() const
{
return mTexture2DArray->getActualFormat(mLevel);
}
GLsizei Texture2DArrayAttachment::getSamples() const
{
return 0;
}
unsigned int Texture2DArrayAttachment::getSerial() const
{
return mTexture2DArray->getRenderTargetSerial(mLevel, mLayer);
}
GLuint Texture2DArrayAttachment::id() const
{
return mTexture2DArray->id();
}
GLenum Texture2DArrayAttachment::type() const
{
return GL_TEXTURE_2D_ARRAY;
}
GLint Texture2DArrayAttachment::mipLevel() const
{
return mLevel;
}
GLint Texture2DArrayAttachment::layer() const
{
return mLayer;
}
unsigned int Texture2DArrayAttachment::getTextureSerial() const
{
return mTexture2DArray->getTextureSerial();
UNREACHABLE();
return NULL;
}
////// RenderbufferAttachment Implementation //////
RenderbufferAttachment::RenderbufferAttachment(Renderbuffer *renderbuffer)
RenderbufferAttachment::RenderbufferAttachment(GLenum binding, Renderbuffer *renderbuffer)
: FramebufferAttachment(binding)
{
ASSERT(renderbuffer);
mRenderbuffer.set(renderbuffer);
@ -420,22 +165,6 @@ RenderbufferAttachment::~RenderbufferAttachment()
mRenderbuffer.set(NULL);
}
rx::RenderTarget *RenderbufferAttachment::getRenderTarget()
{
return mRenderbuffer->getStorage()->getRenderTarget();
}
rx::RenderTarget *RenderbufferAttachment::getDepthStencil()
{
return mRenderbuffer->getStorage()->getDepthStencil();
}
rx::TextureStorage *RenderbufferAttachment::getTextureStorage()
{
UNREACHABLE();
return NULL;
}
GLsizei RenderbufferAttachment::getWidth() const
{
return mRenderbuffer->getWidth();
@ -461,11 +190,6 @@ GLsizei RenderbufferAttachment::getSamples() const
return mRenderbuffer->getStorage()->getSamples();
}
unsigned int RenderbufferAttachment::getSerial() const
{
return mRenderbuffer->getStorage()->getSerial();
}
GLuint RenderbufferAttachment::id() const
{
return mRenderbuffer->id();
@ -486,10 +210,21 @@ GLint RenderbufferAttachment::layer() const
return 0;
}
unsigned int RenderbufferAttachment::getTextureSerial() const
Texture *RenderbufferAttachment::getTexture()
{
UNREACHABLE();
return 0;
return NULL;
}
const ImageIndex *RenderbufferAttachment::getTextureImageIndex() const
{
UNREACHABLE();
return NULL;
}
Renderbuffer *RenderbufferAttachment::getRenderbuffer()
{
return mRenderbuffer.get();
}
}

View File

@ -10,10 +10,11 @@
#ifndef LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
#define LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
#include "angle_gl.h"
#include "common/angleutils.h"
#include "common/RefCountObject.h"
#include "Texture.h"
#include "angle_gl.h"
namespace rx
{
@ -24,10 +25,6 @@ class TextureStorage;
namespace gl
{
class Texture2D;
class TextureCubeMap;
class Texture3D;
class Texture2DArray;
class Renderbuffer;
// FramebufferAttachment implements a GL framebuffer attachment.
@ -39,7 +36,7 @@ class Renderbuffer;
class FramebufferAttachment
{
public:
FramebufferAttachment();
explicit FramebufferAttachment(GLenum binding);
virtual ~FramebufferAttachment();
// Helper methods
@ -56,184 +53,80 @@ class FramebufferAttachment
bool isTextureWithId(GLuint textureId) const { return isTexture() && id() == textureId; }
bool isRenderbufferWithId(GLuint renderbufferId) const { return !isTexture() && id() == renderbufferId; }
// Child class interface
virtual rx::RenderTarget *getRenderTarget() = 0;
virtual rx::RenderTarget *getDepthStencil() = 0;
virtual rx::TextureStorage *getTextureStorage() = 0;
GLenum getBinding() const { return mBinding; }
// Child class interface
virtual GLsizei getWidth() const = 0;
virtual GLsizei getHeight() const = 0;
virtual GLenum getInternalFormat() const = 0;
virtual GLenum getActualFormat() const = 0;
virtual GLsizei getSamples() const = 0;
virtual unsigned int getSerial() const = 0;
virtual GLuint id() const = 0;
virtual GLenum type() const = 0;
virtual GLint mipLevel() const = 0;
virtual GLint layer() const = 0;
virtual unsigned int getTextureSerial() const = 0;
virtual Texture *getTexture() = 0;
virtual const ImageIndex *getTextureImageIndex() const = 0;
virtual Renderbuffer *getRenderbuffer() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(FramebufferAttachment);
GLenum mBinding;
};
class Texture2DAttachment : public FramebufferAttachment
class TextureAttachment : public FramebufferAttachment
{
public:
Texture2DAttachment(Texture2D *texture, GLint level);
TextureAttachment(GLenum binding, Texture *texture, const ImageIndex &index);
virtual ~TextureAttachment();
virtual ~Texture2DAttachment();
rx::RenderTarget *getRenderTarget();
rx::RenderTarget *getDepthStencil();
rx::TextureStorage *getTextureStorage();
virtual GLsizei getSamples() const;
virtual GLuint id() const;
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const;
virtual GLuint id() const;
virtual GLenum type() const;
virtual GLint mipLevel() const;
virtual GLint layer() const;
virtual unsigned int getTextureSerial() const;
virtual Texture *getTexture();
virtual const ImageIndex *getTextureImageIndex() const;
virtual Renderbuffer *getRenderbuffer();
private:
DISALLOW_COPY_AND_ASSIGN(Texture2DAttachment);
DISALLOW_COPY_AND_ASSIGN(TextureAttachment);
BindingPointer<Texture2D> mTexture2D;
const GLint mLevel;
};
class TextureCubeMapAttachment : public FramebufferAttachment
{
public:
TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level);
virtual ~TextureCubeMapAttachment();
rx::RenderTarget *getRenderTarget();
rx::RenderTarget *getDepthStencil();
rx::TextureStorage *getTextureStorage();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const;
virtual GLuint id() const;
virtual GLenum type() const;
virtual GLint mipLevel() const;
virtual GLint layer() const;
virtual unsigned int getTextureSerial() const;
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMapAttachment);
BindingPointer<TextureCubeMap> mTextureCubeMap;
const GLint mLevel;
const GLenum mFaceTarget;
};
class Texture3DAttachment : public FramebufferAttachment
{
public:
Texture3DAttachment(Texture3D *texture, GLint level, GLint layer);
virtual ~Texture3DAttachment();
rx::RenderTarget *getRenderTarget();
rx::RenderTarget *getDepthStencil();
rx::TextureStorage *getTextureStorage();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const;
virtual GLuint id() const;
virtual GLenum type() const;
virtual GLint mipLevel() const;
virtual GLint layer() const;
virtual unsigned int getTextureSerial() const;
private:
DISALLOW_COPY_AND_ASSIGN(Texture3DAttachment);
BindingPointer<Texture3D> mTexture3D;
const GLint mLevel;
const GLint mLayer;
};
class Texture2DArrayAttachment : public FramebufferAttachment
{
public:
Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer);
virtual ~Texture2DArrayAttachment();
rx::RenderTarget *getRenderTarget();
rx::RenderTarget *getDepthStencil();
rx::TextureStorage *getTextureStorage();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const;
virtual GLuint id() const;
virtual GLenum type() const;
virtual GLint mipLevel() const;
virtual GLint layer() const;
virtual unsigned int getTextureSerial() const;
private:
DISALLOW_COPY_AND_ASSIGN(Texture2DArrayAttachment);
BindingPointer<Texture2DArray> mTexture2DArray;
const GLint mLevel;
const GLint mLayer;
BindingPointer<Texture> mTexture;
ImageIndex mIndex;
};
class RenderbufferAttachment : public FramebufferAttachment
{
public:
RenderbufferAttachment(Renderbuffer *renderbuffer);
RenderbufferAttachment(GLenum binding, Renderbuffer *renderbuffer);
virtual ~RenderbufferAttachment();
rx::RenderTarget *getRenderTarget();
rx::RenderTarget *getDepthStencil();
rx::TextureStorage *getTextureStorage();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const;
virtual GLuint id() const;
virtual GLenum type() const;
virtual GLint mipLevel() const;
virtual GLint layer() const;
virtual unsigned int getTextureSerial() const;
virtual Texture *getTexture();
virtual const ImageIndex *getTextureImageIndex() const;
virtual Renderbuffer *getRenderbuffer();
private:
DISALLOW_COPY_AND_ASSIGN(RenderbufferAttachment);

Some files were not shown because too many files have changed in this diff Show More