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
parent
04d3a89e20
commit
311157c3c6
|
|
@ -20,6 +20,7 @@ Intel Corporation
|
|||
Mozilla Corporation
|
||||
Turbulenz
|
||||
Klarälvdalens Datakonsult AB
|
||||
Microsoft Open Technologies, Inc.
|
||||
|
||||
Jacek Caban
|
||||
Mark Callow
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
// mathutil.cpp: Math and bit manipulation functions.
|
||||
|
||||
#include "common/mathutil.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#ifndef COMPILER_DETECTDISCONTINUITY_H_
|
||||
#define COMPILER_DETECTDISCONTINUITY_H_
|
||||
|
||||
#include "compiler/translator/intermediate.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef COMPILER_FLAGSTD140STRUCTS_H_
|
||||
#define COMPILER_FLAGSTD140STRUCTS_H_
|
||||
|
||||
#include "compiler/translator/intermediate.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
#include "compiler/translator/intermediate.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
#define HASHED_NAME_PREFIX "webgl_"
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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_
|
||||
|
|
@ -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
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef TRANSLATOR_NODESEARCH_H_
|
||||
#define TRANSLATOR_NODESEARCH_H_
|
||||
|
||||
#include "compiler/translator/intermediate.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/translator/intermediate.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
class TAliveTraverser : public TIntermTraverser {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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_
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/translator/intermediate.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
#include "compiler/translator/RemoveTree.h"
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ TSymbol::TSymbol(const TSymbol ©Of)
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
#define COMPILER_TRANSLATORHLSL_H_
|
||||
|
||||
#include "compiler/translator/Compiler.h"
|
||||
#include "common/shadervars.h"
|
||||
|
||||
class TranslatorHLSL : public TCompiler
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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-";
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 ®isterString = 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) +
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/translator/intermediate.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
|
|
|
|||
|
|
@ -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> *);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case EOpInvariantDeclaration:
|
||||
updateVersion(GLSL_VERSION_120);
|
||||
break;
|
||||
case EOpParameters:
|
||||
{
|
||||
const TIntermSequence ¶ms = *(node->getSequence());
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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> *);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@
|
|||
#ifndef LIBEGL_MAIN_H_
|
||||
#define LIBEGL_MAIN_H_
|
||||
|
||||
#undef EGLAPI
|
||||
#define EGLAPI
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
#include "common/angleutils.h"
|
||||
#include "common/mathutil.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue