ANGLE: Upgrade to version 1.2.30d6c255d238
The following patches have been changed: 0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch Removed because it is no longer possible to build ANGLE with MSVC2008 0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch Removed because the minimum version of MinGW moved to 4.8.2 0005-Fix-build-when-SSE2-is-not-available.patch Removed because it was fixed upstream 0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch Removed because older versions of MinGW are not supported 0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch Removed because it was fixed upstream Task-number: QTBUG-41903 Change-Id: I976d30802f7f6fee725cf9a9f1325d5e82609835 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com> Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
This commit is contained in:
parent
32db2f425a
commit
c6df5fe3ed
2
src/3rdparty/angle/AUTHORS
vendored
2
src/3rdparty/angle/AUTHORS
vendored
@ -21,10 +21,12 @@ Mozilla Corporation
|
||||
Turbulenz
|
||||
Klarälvdalens Datakonsult AB
|
||||
Microsoft Open Technologies, Inc.
|
||||
NVIDIA Corporation
|
||||
|
||||
Jacek Caban
|
||||
Mark Callow
|
||||
Ginn Chen
|
||||
Tibor den Ouden
|
||||
James Hauxwell
|
||||
Sam Hocevar
|
||||
Pierre Leveille
|
||||
|
5
src/3rdparty/angle/CONTRIBUTORS
vendored
5
src/3rdparty/angle/CONTRIBUTORS
vendored
@ -78,7 +78,12 @@ Turbulenz
|
||||
Ulrik Persson (ddefrostt)
|
||||
Mark Banner (standard8mbp)
|
||||
David Kilzer
|
||||
Jacek Caban
|
||||
Tibor den Ouden
|
||||
|
||||
Microsoft Open Technologies, Inc.
|
||||
Cooper Partin
|
||||
Austin Kinross
|
||||
|
||||
NVIDIA Corporation
|
||||
Olli Etuaho
|
||||
|
2
src/3rdparty/angle/include/EGL/egl.h
vendored
2
src/3rdparty/angle/include/EGL/egl.h
vendored
@ -238,7 +238,7 @@ EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
|
||||
#ifndef EGL_VERSION_1_5
|
||||
#define EGL_VERSION_1_5 1
|
||||
typedef void *EGLSync;
|
||||
typedef khronos_intptr_t EGLAttrib;
|
||||
typedef intptr_t EGLAttrib;
|
||||
typedef khronos_utime_nanoseconds_t EGLTime;
|
||||
#define EGL_CONTEXT_MAJOR_VERSION 0x3098
|
||||
#define EGL_CONTEXT_MINOR_VERSION 0x30FB
|
||||
|
16
src/3rdparty/angle/include/EGL/eglext.h
vendored
16
src/3rdparty/angle/include/EGL/eglext.h
vendored
@ -59,7 +59,7 @@ extern "C" {
|
||||
#ifndef EGL_KHR_cl_event2
|
||||
#define EGL_KHR_cl_event2 1
|
||||
typedef void *EGLSyncKHR;
|
||||
typedef khronos_intptr_t EGLAttribKHR;
|
||||
typedef intptr_t EGLAttribKHR;
|
||||
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
|
||||
@ -442,20 +442,22 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
|
||||
#define EGL_ANGLE_platform_angle 1
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3203
|
||||
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3203
|
||||
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3204
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3205
|
||||
#endif /* EGL_ANGLE_platform_angle */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle_d3d
|
||||
#define EGL_ANGLE_platform_angle_d3d 1
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3204
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3205
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE 0x3206
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3206
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207
|
||||
#define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208
|
||||
#endif /* EGL_ANGLE_platform_angle_d3d */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle_opengl
|
||||
#define EGL_ANGLE_platform_angle_opengl 1
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3207
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x3208
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3209
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320A
|
||||
#endif /* EGL_ANGLE_platform_angle_opengl */
|
||||
|
||||
#ifndef EGL_ARM_pixmap_multisample_discard
|
||||
|
19
src/3rdparty/angle/include/EGL/eglplatform.h
vendored
19
src/3rdparty/angle/include/EGL/eglplatform.h
vendored
@ -67,23 +67,22 @@
|
||||
* implementations.
|
||||
*/
|
||||
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */
|
||||
|
||||
struct IUnknown;
|
||||
|
||||
typedef IUnknown *EGLNativeDisplayType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
typedef IUnknown *EGLNativeWindowType;
|
||||
|
||||
#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
|
||||
#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HBITMAP EGLNativePixmapType;
|
||||
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) /* Windows Store */
|
||||
#include <inspectable.h>
|
||||
typedef IInspectable* EGLNativeDisplayType;
|
||||
typedef IInspectable* EGLNativeWindowType;
|
||||
#else
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HWND EGLNativeWindowType;
|
||||
#endif
|
||||
|
||||
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
|
||||
|
||||
|
210
src/3rdparty/angle/include/GLSLANG/ShaderLang.h
vendored
210
src/3rdparty/angle/include/GLSLANG/ShaderLang.h
vendored
@ -27,6 +27,10 @@
|
||||
|
||||
#include "KHR/khrplatform.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//
|
||||
// This is the platform independent interface between an OGL driver
|
||||
// and the shading language compiler.
|
||||
@ -42,18 +46,17 @@ typedef unsigned int GLenum;
|
||||
// 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 130
|
||||
#define ANGLE_SH_VERSION 132
|
||||
|
||||
typedef enum {
|
||||
SH_GLES2_SPEC = 0x8B40,
|
||||
SH_WEBGL_SPEC = 0x8B41,
|
||||
|
||||
SH_GLES3_SPEC = 0x8B86,
|
||||
SH_WEBGL2_SPEC = 0x8B87,
|
||||
|
||||
// The CSS Shaders spec is a subset of the WebGL spec.
|
||||
//
|
||||
// In both CSS vertex and fragment shaders, ANGLE:
|
||||
@ -85,31 +88,6 @@ typedef enum {
|
||||
SH_HLSL11_OUTPUT = 0x8B48
|
||||
} ShShaderOutput;
|
||||
|
||||
typedef enum {
|
||||
SH_PRECISION_HIGHP = 0x5001,
|
||||
SH_PRECISION_MEDIUMP = 0x5002,
|
||||
SH_PRECISION_LOWP = 0x5003,
|
||||
SH_PRECISION_UNDEFINED = 0
|
||||
} ShPrecisionType;
|
||||
|
||||
typedef enum {
|
||||
SH_INFO_LOG_LENGTH = 0x8B84,
|
||||
SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
|
||||
SH_ACTIVE_UNIFORMS = 0x8B86,
|
||||
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
|
||||
SH_ACTIVE_ATTRIBUTES = 0x8B89,
|
||||
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
|
||||
SH_VARYINGS = 0x8BBB,
|
||||
SH_VARYING_MAX_LENGTH = 0x8BBC,
|
||||
SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
|
||||
SH_NAME_MAX_LENGTH = 0x6001,
|
||||
SH_HASHED_NAME_MAX_LENGTH = 0x6002,
|
||||
SH_HASHED_NAMES_COUNT = 0x6003,
|
||||
SH_SHADER_VERSION = 0x6004,
|
||||
SH_RESOURCES_STRING_LENGTH = 0x6005,
|
||||
SH_OUTPUT_TYPE = 0x6006
|
||||
} ShShaderInfo;
|
||||
|
||||
// Compile options.
|
||||
typedef enum {
|
||||
SH_VALIDATE = 0,
|
||||
@ -208,14 +186,14 @@ typedef enum {
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler operations.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
//
|
||||
COMPILER_EXPORT int ShInitialize();
|
||||
COMPILER_EXPORT bool ShInitialize();
|
||||
//
|
||||
// Driver should call this at shutdown.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
//
|
||||
COMPILER_EXPORT int ShFinalize();
|
||||
COMPILER_EXPORT bool ShFinalize();
|
||||
|
||||
// The 64 bits hash function. The first parameter is the input string; the
|
||||
// second parameter is the string length.
|
||||
@ -246,6 +224,12 @@ typedef struct
|
||||
int EXT_frag_depth;
|
||||
int EXT_shader_texture_lod;
|
||||
|
||||
// Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
|
||||
// with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
|
||||
// EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers
|
||||
// function. This applies to Tegra K1 devices.
|
||||
int NV_draw_buffers;
|
||||
|
||||
// Set to 1 if highp precision is supported in the fragment language.
|
||||
// Default is 0.
|
||||
int FragmentPrecisionHigh;
|
||||
@ -274,8 +258,10 @@ typedef struct
|
||||
|
||||
//
|
||||
// Initialize built-in resources with minimum expected values.
|
||||
// Parameters:
|
||||
// resources: The object to initialize. Will be comparable with memcmp.
|
||||
//
|
||||
COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
|
||||
COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources);
|
||||
|
||||
//
|
||||
// ShHandle held by but opaque to the driver. It is allocated,
|
||||
@ -284,18 +270,15 @@ COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
|
||||
//
|
||||
// If handle creation fails, 0 will be returned.
|
||||
//
|
||||
typedef void* ShHandle;
|
||||
typedef void *ShHandle;
|
||||
|
||||
//
|
||||
// Returns the a concatenated list of the items in ShBuiltInResources as a string.
|
||||
// Returns the a concatenated list of the items in ShBuiltInResources as a
|
||||
// null-terminated string.
|
||||
// This function must be updated whenever ShBuiltInResources is changed.
|
||||
// Parameters:
|
||||
// handle: Specifies the handle of the compiler to be used.
|
||||
// outStringLen: Specifies the size of the buffer, in number of characters. The size
|
||||
// of the buffer required to store the resources string can be obtained
|
||||
// by calling ShGetInfo with SH_RESOURCES_STRING_LENGTH.
|
||||
// outStr: Returns a null-terminated string representing all the built-in resources.
|
||||
COMPILER_EXPORT void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outStr);
|
||||
COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
|
||||
|
||||
//
|
||||
// Driver calls these to create and destroy compiler objects.
|
||||
@ -313,12 +296,12 @@ COMPILER_EXPORT ShHandle ShConstructCompiler(
|
||||
sh::GLenum type,
|
||||
ShShaderSpec spec,
|
||||
ShShaderOutput output,
|
||||
const ShBuiltInResources* resources);
|
||||
const ShBuiltInResources *resources);
|
||||
COMPILER_EXPORT void ShDestruct(ShHandle handle);
|
||||
|
||||
//
|
||||
// Compiles the given shader source.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
// Parameters:
|
||||
// handle: Specifies the handle of compiler to be used.
|
||||
// shaderStrings: Specifies an array of pointers to null-terminated strings
|
||||
@ -340,123 +323,36 @@ COMPILER_EXPORT void ShDestruct(ShHandle handle);
|
||||
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
|
||||
// Can be queried by calling ShGetVariableInfo().
|
||||
//
|
||||
COMPILER_EXPORT int ShCompile(
|
||||
COMPILER_EXPORT bool ShCompile(
|
||||
const ShHandle handle,
|
||||
const char* const shaderStrings[],
|
||||
const char * const shaderStrings[],
|
||||
size_t numStrings,
|
||||
int compileOptions
|
||||
);
|
||||
int compileOptions);
|
||||
|
||||
// Returns a parameter from a compiled shader.
|
||||
// Return the version of the shader language.
|
||||
COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle);
|
||||
|
||||
// Return the currently set language output type.
|
||||
COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType(
|
||||
const ShHandle handle);
|
||||
|
||||
// Returns null-terminated information log for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// pname: Specifies the parameter to query.
|
||||
// The following parameters are defined:
|
||||
// SH_INFO_LOG_LENGTH: the number of characters in the information log
|
||||
// including the null termination character.
|
||||
// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
|
||||
// including the null termination character.
|
||||
// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
|
||||
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
|
||||
// variable name including the null
|
||||
// termination character.
|
||||
// SH_ACTIVE_UNIFORMS: the number of active uniform variables.
|
||||
// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
|
||||
// variable name including the null
|
||||
// termination character.
|
||||
// SH_VARYINGS: the number of varying variables.
|
||||
// SH_VARYING_MAX_LENGTH: the length of the longest varying variable name
|
||||
// including the null termination character.
|
||||
// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
|
||||
// the null termination character.
|
||||
// SH_NAME_MAX_LENGTH: the max length of a user-defined name including the
|
||||
// null termination character.
|
||||
// SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the
|
||||
// null termination character.
|
||||
// SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile.
|
||||
// SH_SHADER_VERSION: the version of the shader language
|
||||
// SH_OUTPUT_TYPE: the currently set language output type
|
||||
//
|
||||
// params: Requested parameter
|
||||
COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
|
||||
ShShaderInfo pname,
|
||||
size_t* params);
|
||||
|
||||
// Returns nul-terminated information log for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// infoLog: Specifies an array of characters that is used to return
|
||||
// the information log. It is assumed that infoLog has enough memory
|
||||
// to accomodate the information log. The size of the buffer required
|
||||
// to store the returned information log can be obtained by calling
|
||||
// ShGetInfo with SH_INFO_LOG_LENGTH.
|
||||
COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog);
|
||||
COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle);
|
||||
|
||||
// Returns null-terminated object code for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// infoLog: Specifies an array of characters that is used to return
|
||||
// the object code. It is assumed that infoLog has enough memory to
|
||||
// accomodate the object code. The size of the buffer required to
|
||||
// store the returned object code can be obtained by calling
|
||||
// ShGetInfo with SH_OBJECT_CODE_LENGTH.
|
||||
COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
|
||||
COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle);
|
||||
|
||||
// Returns information about a shader variable.
|
||||
// Returns a (original_name, hash) map containing all the user defined
|
||||
// names in the shader, including variable names, function names, struct
|
||||
// names, and struct field names.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// variableType: Specifies the variable type; options include
|
||||
// SH_ACTIVE_ATTRIBUTES, SH_ACTIVE_UNIFORMS, SH_VARYINGS.
|
||||
// index: Specifies the index of the variable to be queried.
|
||||
// length: Returns the number of characters actually written in the string
|
||||
// indicated by name (excluding the null terminator) if a value other
|
||||
// than NULL is passed.
|
||||
// size: Returns the size of the variable.
|
||||
// type: Returns the data type of the variable.
|
||||
// precision: Returns the precision of the variable.
|
||||
// staticUse: Returns 1 if the variable is accessed in a statement after
|
||||
// pre-processing, whether or not run-time flow of control will
|
||||
// cause that statement to be executed.
|
||||
// Returns 0 otherwise.
|
||||
// name: Returns a null terminated string containing the name of the
|
||||
// variable. It is assumed that name has enough memory to accormodate
|
||||
// the variable name. The size of the buffer required to store the
|
||||
// variable name can be obtained by calling ShGetInfo with
|
||||
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_ACTIVE_UNIFORM_MAX_LENGTH,
|
||||
// SH_VARYING_MAX_LENGTH.
|
||||
// mappedName: Returns a null terminated string containing the mapped name of
|
||||
// the variable, It is assumed that mappedName has enough memory
|
||||
// (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care about the
|
||||
// mapped name. If the name is not mapped, then name and mappedName
|
||||
// are the same.
|
||||
COMPILER_EXPORT void ShGetVariableInfo(const ShHandle handle,
|
||||
ShShaderInfo variableType,
|
||||
int index,
|
||||
size_t* length,
|
||||
int* size,
|
||||
sh::GLenum* type,
|
||||
ShPrecisionType* precision,
|
||||
int* staticUse,
|
||||
char* name,
|
||||
char* mappedName);
|
||||
|
||||
// Returns information about a name hashing entry from the latest compile.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// index: Specifies the index of the name hashing entry to be queried.
|
||||
// name: Returns a null terminated string containing the user defined name.
|
||||
// It is assumed that name has enough memory to accomodate the name.
|
||||
// The size of the buffer required to store the user defined name can
|
||||
// be obtained by calling ShGetInfo with SH_NAME_MAX_LENGTH.
|
||||
// hashedName: Returns a null terminated string containing the hashed name of
|
||||
// the uniform variable, It is assumed that hashedName has enough
|
||||
// memory to accomodate the name. The size of the buffer required
|
||||
// to store the name can be obtained by calling ShGetInfo with
|
||||
// SH_HASHED_NAME_MAX_LENGTH.
|
||||
COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle,
|
||||
int index,
|
||||
char* name,
|
||||
char* hashedName);
|
||||
COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
|
||||
const ShHandle handle);
|
||||
|
||||
// Shader variable inspection.
|
||||
// Returns a pointer to a list of variables of the designated type.
|
||||
@ -476,17 +372,17 @@ typedef struct
|
||||
int size;
|
||||
} ShVariableInfo;
|
||||
|
||||
// Returns 1 if the passed in variables pack in maxVectors following
|
||||
// Returns true if the passed in variables pack in maxVectors following
|
||||
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
|
||||
// Returns 0 otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
|
||||
// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
|
||||
// flag above.
|
||||
// Parameters:
|
||||
// maxVectors: the available rows of registers.
|
||||
// varInfoArray: an array of variable info (types and sizes).
|
||||
// varInfoArraySize: the size of the variable array.
|
||||
COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
|
||||
COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
|
||||
int maxVectors,
|
||||
ShVariableInfo* varInfoArray,
|
||||
ShVariableInfo *varInfoArray,
|
||||
size_t varInfoArraySize);
|
||||
|
||||
// Gives the compiler-assigned register for an interface block.
|
||||
@ -497,7 +393,7 @@ COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
|
||||
// interfaceBlockName: Specifies the interface block
|
||||
// indexOut: output variable that stores the assigned register
|
||||
COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
const char *interfaceBlockName,
|
||||
const std::string &interfaceBlockName,
|
||||
unsigned int *indexOut);
|
||||
|
||||
// Gives the compiler-assigned register for uniforms in the default
|
||||
@ -509,11 +405,7 @@ COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
// interfaceBlockName: Specifies the uniform
|
||||
// indexOut: output variable that stores the assigned register
|
||||
COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
|
||||
const char *uniformName,
|
||||
const std::string &uniformName,
|
||||
unsigned int *indexOut);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _COMPILER_INTERFACE_INCLUDED_
|
||||
|
64
src/3rdparty/angle/include/GLSLANG/ShaderVars.h
vendored
64
src/3rdparty/angle/include/GLSLANG/ShaderVars.h
vendored
@ -52,6 +52,21 @@ struct COMPILER_EXPORT ShaderVariable
|
||||
unsigned int elementCount() const { return std::max(1u, arraySize); }
|
||||
bool isStruct() const { return !fields.empty(); }
|
||||
|
||||
// All of the shader's variables are described using nested data
|
||||
// structures. This is needed in order to disambiguate similar looking
|
||||
// types, such as two structs containing the same fields, but in
|
||||
// different orders. "findInfoByMappedName" provides an easy query for
|
||||
// users to dive into the data structure and fetch the unique variable
|
||||
// instance corresponding to a dereferencing chain of the top-level
|
||||
// variable.
|
||||
// Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
|
||||
// that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
|
||||
// in |originalName|, based on the assumption that |this| defines 'a'.
|
||||
// If no match is found, return false.
|
||||
bool findInfoByMappedName(const std::string &mappedFullName,
|
||||
const ShaderVariable **leafVar,
|
||||
std::string* originalFullName) const;
|
||||
|
||||
GLenum type;
|
||||
GLenum precision;
|
||||
std::string name;
|
||||
@ -60,6 +75,16 @@ struct COMPILER_EXPORT ShaderVariable
|
||||
bool staticUse;
|
||||
std::vector<ShaderVariable> fields;
|
||||
std::string structName;
|
||||
|
||||
protected:
|
||||
bool isSameVariableAtLinkTime(const ShaderVariable &other,
|
||||
bool matchPrecision) const;
|
||||
|
||||
bool operator==(const ShaderVariable &other) const;
|
||||
bool operator!=(const ShaderVariable &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
struct COMPILER_EXPORT Uniform : public ShaderVariable
|
||||
@ -68,6 +93,16 @@ struct COMPILER_EXPORT Uniform : public ShaderVariable
|
||||
~Uniform();
|
||||
Uniform(const Uniform &other);
|
||||
Uniform &operator=(const Uniform &other);
|
||||
bool operator==(const Uniform &other) const;
|
||||
bool operator!=(const Uniform &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
// Decide whether two uniforms are the same at shader link time,
|
||||
// assuming one from vertex shader and the other from fragment shader.
|
||||
// See GLSL ES Spec 3.00.3, sec 4.3.5.
|
||||
bool isSameUniformAtLinkTime(const Uniform &other) const;
|
||||
};
|
||||
|
||||
struct COMPILER_EXPORT Attribute : public ShaderVariable
|
||||
@ -76,6 +111,11 @@ struct COMPILER_EXPORT Attribute : public ShaderVariable
|
||||
~Attribute();
|
||||
Attribute(const Attribute &other);
|
||||
Attribute &operator=(const Attribute &other);
|
||||
bool operator==(const Attribute &other) const;
|
||||
bool operator!=(const Attribute &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
int location;
|
||||
};
|
||||
@ -86,6 +126,18 @@ struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
|
||||
~InterfaceBlockField();
|
||||
InterfaceBlockField(const InterfaceBlockField &other);
|
||||
InterfaceBlockField &operator=(const InterfaceBlockField &other);
|
||||
bool operator==(const InterfaceBlockField &other) const;
|
||||
bool operator!=(const InterfaceBlockField &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
// Decide whether two InterfaceBlock fields are the same at shader
|
||||
// link time, assuming one from vertex shader and the other from
|
||||
// fragment shader.
|
||||
// See GLSL ES Spec 3.00.3, sec 4.3.7.
|
||||
bool isSameInterfaceBlockFieldAtLinkTime(
|
||||
const InterfaceBlockField &other) const;
|
||||
|
||||
bool isRowMajorLayout;
|
||||
};
|
||||
@ -94,8 +146,18 @@ struct COMPILER_EXPORT Varying : public ShaderVariable
|
||||
{
|
||||
Varying();
|
||||
~Varying();
|
||||
Varying(const Varying &other);
|
||||
Varying(const Varying &otherg);
|
||||
Varying &operator=(const Varying &other);
|
||||
bool operator==(const Varying &other) const;
|
||||
bool operator!=(const Varying &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
// Decide whether two varyings are the same at shader link time,
|
||||
// assuming one from vertex shader and the other from fragment shader.
|
||||
// See GLSL ES Spec 3.00.3, sec 4.3.9.
|
||||
bool isSameVaryingAtLinkTime(const Varying &other) const;
|
||||
|
||||
InterpolationType interpolation;
|
||||
bool isInvariant;
|
||||
|
37
src/3rdparty/angle/include/angle_windowsstore.h
vendored
Normal file
37
src/3rdparty/angle/include/angle_windowsstore.h
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// angle_windowsstore.h:
|
||||
|
||||
#ifndef ANGLE_WINDOWSSTORE_H_
|
||||
#define ANGLE_WINDOWSSTORE_H_
|
||||
|
||||
// The following properties can be set on the CoreApplication to support additional
|
||||
// ANGLE configuration options.
|
||||
//
|
||||
// The Visual Studio sample templates provided with this version of ANGLE have examples
|
||||
// of how to set these property values.
|
||||
|
||||
//
|
||||
// Property: EGLNativeWindowTypeProperty
|
||||
// Type: IInspectable
|
||||
// Description: Set this property to specify the window type to use for creating a surface.
|
||||
// If this property is missing, surface creation will fail.
|
||||
//
|
||||
const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty";
|
||||
|
||||
//
|
||||
// Property: EGLRenderSurfaceSizeProperty
|
||||
// Type: Size
|
||||
// Description: Set this property to specify a preferred size in pixels of the render surface.
|
||||
// The render surface size width and height must be greater than 0.
|
||||
// If this property is set, then the render surface size is fixed.
|
||||
// If this property is missing, a default behavior will be provided.
|
||||
// The default behavior uses the window size if a CoreWindow is specified or
|
||||
// the size of the SwapChainPanel control if one is specified.
|
||||
//
|
||||
const wchar_t EGLRenderSurfaceSizeProperty[] = L"EGLRenderSurfaceSizeProperty";
|
||||
|
||||
#endif // ANGLE_WINDOWSSTORE_H_
|
4
src/3rdparty/angle/src/commit.h
vendored
4
src/3rdparty/angle/src/commit.h
vendored
@ -7,6 +7,6 @@
|
||||
// This is a default commit hash header, when git is not available.
|
||||
//
|
||||
|
||||
#define ANGLE_COMMIT_HASH "abce76206141"
|
||||
#define ANGLE_COMMIT_HASH "30d6c255d238"
|
||||
#define ANGLE_COMMIT_HASH_SIZE 12
|
||||
#define ANGLE_COMMIT_DATE "2014-09-23 19:37:05 +0000"
|
||||
#define ANGLE_COMMIT_DATE "2014-11-13 17:37:03 +0000"
|
||||
|
77
src/3rdparty/angle/src/common/NativeWindow.h
vendored
Normal file
77
src/3rdparty/angle/src/common/NativeWindow.h
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// NativeWindow.h: Defines NativeWindow, a class for managing and
|
||||
// performing operations on an EGLNativeWindowType.
|
||||
// It is used for HWND (Desktop Windows) and IInspectable objects
|
||||
//(Windows Store Applications).
|
||||
|
||||
#ifndef COMMON_NATIVEWINDOW_H_
|
||||
#define COMMON_NATIVEWINDOW_H_
|
||||
|
||||
#include <EGL/eglplatform.h>
|
||||
#include "common/debug.h"
|
||||
#include "common/platform.h"
|
||||
|
||||
// DXGISwapChain and DXGIFactory are typedef'd to specific required
|
||||
// types. The HWND NativeWindow implementation requires IDXGISwapChain
|
||||
// and IDXGIFactory and the Windows Store NativeWindow
|
||||
// implementation requires IDXGISwapChain1 and IDXGIFactory2.
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
typedef IDXGISwapChain1 DXGISwapChain;
|
||||
typedef IDXGIFactory2 DXGIFactory;
|
||||
|
||||
#include <wrl.h>
|
||||
#include <wrl/wrappers/corewrappers.h>
|
||||
#include <windows.applicationmodel.core.h>
|
||||
#include <memory>
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class InspectableNativeWindow;
|
||||
}
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
|
||||
#else
|
||||
typedef IDXGISwapChain DXGISwapChain;
|
||||
typedef IDXGIFactory DXGIFactory;
|
||||
#endif
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
class NativeWindow
|
||||
{
|
||||
public:
|
||||
explicit NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display);
|
||||
|
||||
bool initialize();
|
||||
bool getClientRect(LPRECT rect);
|
||||
bool isIconic();
|
||||
|
||||
HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory,
|
||||
DXGI_FORMAT format, UINT width, UINT height,
|
||||
DXGISwapChain** swapChain);
|
||||
|
||||
inline EGLNativeWindowType getNativeWindow() const { return mWindow; }
|
||||
inline EGLNativeDisplayType getNativeDisplay() const { return mDisplay; }
|
||||
|
||||
private:
|
||||
EGLNativeWindowType mWindow;
|
||||
EGLNativeDisplayType mDisplay;
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
std::shared_ptr<InspectableNativeWindow> mImpl;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
bool IsValidEGLNativeWindowType(EGLNativeWindowType window);
|
||||
}
|
||||
|
||||
#endif // COMMON_NATIVEWINDOW_H_
|
35
src/3rdparty/angle/src/common/angleutils.cpp
vendored
35
src/3rdparty/angle/src/common/angleutils.cpp
vendored
@ -5,26 +5,33 @@
|
||||
//
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
|
||||
{
|
||||
// Attempt to just print to the current buffer
|
||||
int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
|
||||
if (len < 0 || static_cast<size_t>(len) >= outBuffer.size())
|
||||
{
|
||||
// Buffer was not large enough, calculate the required size and resize the buffer
|
||||
len = vsnprintf(NULL, 0, fmt, vararg);
|
||||
outBuffer.resize(len + 1);
|
||||
|
||||
// Print again
|
||||
len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
|
||||
}
|
||||
ASSERT(len >= 0);
|
||||
return static_cast<size_t>(len);
|
||||
}
|
||||
|
||||
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);
|
||||
size_t len = FormatStringIntoVector(fmt, vararg, buffer);
|
||||
return std::string(&buffer[0], len);
|
||||
}
|
||||
|
||||
std::string FormatString(const char *fmt, ...)
|
||||
|
11
src/3rdparty/angle/src/common/angleutils.h
vendored
11
src/3rdparty/angle/src/common/angleutils.h
vendored
@ -17,6 +17,7 @@
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <cstdarg>
|
||||
#include <vector>
|
||||
|
||||
// A macro to disallow the copy constructor and operator= functions
|
||||
// This must be used in the private: declarations for a class
|
||||
@ -95,6 +96,13 @@ inline void StructZero(T *obj)
|
||||
memset(obj, 0, sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool IsMaskFlagSet(T mask, T flag)
|
||||
{
|
||||
// Handles multibit flags as well
|
||||
return (mask & flag) == flag;
|
||||
}
|
||||
|
||||
inline const char* MakeStaticString(const std::string &str)
|
||||
{
|
||||
static std::set<std::string> strings;
|
||||
@ -132,9 +140,12 @@ inline std::string Str(int i)
|
||||
return strstr.str();
|
||||
}
|
||||
|
||||
size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& buffer);
|
||||
|
||||
std::string FormatString(const char *fmt, va_list vararg);
|
||||
std::string FormatString(const char *fmt, ...);
|
||||
|
||||
// snprintf is not defined with MSVC prior to to msvc14
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
246
src/3rdparty/angle/src/common/debug.cpp
vendored
246
src/3rdparty/angle/src/common/debug.cpp
vendored
@ -17,41 +17,211 @@
|
||||
|
||||
namespace gl
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
|
||||
#else
|
||||
typedef void (*PerfOutputFunction)(unsigned int, const wchar_t*);
|
||||
#endif
|
||||
|
||||
static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
// Wraps the D3D9/D3D11 debug annotation functions.
|
||||
class DebugAnnotationWrapper
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE)
|
||||
std::string formattedMessage = FormatString(format, vararg);
|
||||
public:
|
||||
DebugAnnotationWrapper() { };
|
||||
virtual ~DebugAnnotationWrapper() { };
|
||||
virtual void beginEvent(const std::wstring &eventName) = 0;
|
||||
virtual void endEvent() = 0;
|
||||
virtual void setMarker(const std::wstring &markerName) = 0;
|
||||
virtual bool getStatus() = 0;
|
||||
};
|
||||
|
||||
#if defined(ANGLE_ENABLE_D3D9)
|
||||
class D3D9DebugAnnotationWrapper : public DebugAnnotationWrapper
|
||||
{
|
||||
public:
|
||||
void beginEvent(const std::wstring &eventName)
|
||||
{
|
||||
D3DPERF_BeginEvent(0, eventName.c_str());
|
||||
}
|
||||
|
||||
void endEvent()
|
||||
{
|
||||
D3DPERF_EndEvent();
|
||||
}
|
||||
|
||||
void setMarker(const std::wstring &markerName)
|
||||
{
|
||||
D3DPERF_SetMarker(0, markerName.c_str());
|
||||
}
|
||||
|
||||
bool getStatus()
|
||||
{
|
||||
return !!D3DPERF_GetStatus();
|
||||
}
|
||||
};
|
||||
#endif // ANGLE_ENABLE_D3D9
|
||||
|
||||
#if defined(ANGLE_ENABLE_D3D11)
|
||||
class D3D11DebugAnnotationWrapper : public DebugAnnotationWrapper
|
||||
{
|
||||
public:
|
||||
|
||||
D3D11DebugAnnotationWrapper()
|
||||
: mInitialized(false),
|
||||
mD3d11Module(NULL),
|
||||
mUserDefinedAnnotation(NULL)
|
||||
{
|
||||
// D3D11 devices can't be created during DllMain.
|
||||
// We defer device creation until the object is actually used.
|
||||
}
|
||||
|
||||
~D3D11DebugAnnotationWrapper()
|
||||
{
|
||||
if (mInitialized)
|
||||
{
|
||||
SafeRelease(mUserDefinedAnnotation);
|
||||
FreeLibrary(mD3d11Module);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void beginEvent(const std::wstring &eventName)
|
||||
{
|
||||
initializeDevice();
|
||||
|
||||
mUserDefinedAnnotation->BeginEvent(eventName.c_str());
|
||||
}
|
||||
|
||||
virtual void endEvent()
|
||||
{
|
||||
initializeDevice();
|
||||
|
||||
mUserDefinedAnnotation->EndEvent();
|
||||
}
|
||||
|
||||
virtual void setMarker(const std::wstring &markerName)
|
||||
{
|
||||
initializeDevice();
|
||||
|
||||
mUserDefinedAnnotation->SetMarker(markerName.c_str());
|
||||
}
|
||||
|
||||
virtual bool getStatus()
|
||||
{
|
||||
// ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
|
||||
|
||||
#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
// In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture.
|
||||
// This should only be called in DEBUG mode.
|
||||
// If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks.
|
||||
IDXGraphicsAnalysis* graphicsAnalysis;
|
||||
DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis));
|
||||
bool underCapture = (graphicsAnalysis != NULL);
|
||||
SafeRelease(graphicsAnalysis);
|
||||
return underCapture;
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
// Otherwise, we have to return true here.
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void initializeDevice()
|
||||
{
|
||||
if (!mInitialized)
|
||||
{
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
|
||||
ASSERT(mD3d11Module);
|
||||
|
||||
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
|
||||
ASSERT(D3D11CreateDevice != NULL);
|
||||
#endif // !ANGLE_ENABLE_WINDOWS_STORE
|
||||
|
||||
ID3D11Device* device = NULL;
|
||||
ID3D11DeviceContext* context = NULL;
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
// Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device.
|
||||
hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, NULL, &context);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = context->QueryInterface(__uuidof(mUserDefinedAnnotation), reinterpret_cast<void**>(&mUserDefinedAnnotation));
|
||||
ASSERT(SUCCEEDED(hr) && mUserDefinedAnnotation != NULL);
|
||||
|
||||
SafeRelease(device);
|
||||
SafeRelease(context);
|
||||
|
||||
mInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool mInitialized;
|
||||
HMODULE mD3d11Module;
|
||||
ID3DUserDefinedAnnotation* mUserDefinedAnnotation;
|
||||
};
|
||||
#endif // ANGLE_ENABLE_D3D11
|
||||
|
||||
static DebugAnnotationWrapper* g_DebugAnnotationWrapper = NULL;
|
||||
|
||||
void InitializeDebugAnnotations()
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_D3D9)
|
||||
g_DebugAnnotationWrapper = new D3D9DebugAnnotationWrapper();
|
||||
#elif defined(ANGLE_ENABLE_D3D11)
|
||||
// If the project uses D3D9 then we can use the D3D9 debug annotations, even with the D3D11 renderer.
|
||||
// However, if D3D9 is unavailable (e.g. in Windows Store), then we use D3D11 debug annotations.
|
||||
// The D3D11 debug annotations are methods on ID3DUserDefinedAnnotation, which is implemented by the DeviceContext.
|
||||
// This doesn't have to be the same DeviceContext that the renderer uses, though.
|
||||
g_DebugAnnotationWrapper = new D3D11DebugAnnotationWrapper();
|
||||
#endif
|
||||
}
|
||||
|
||||
void UninitializeDebugAnnotations()
|
||||
{
|
||||
if (g_DebugAnnotationWrapper != NULL)
|
||||
{
|
||||
SafeDelete(g_DebugAnnotationWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
|
||||
enum DebugTraceOutputType
|
||||
{
|
||||
DebugTraceOutputTypeNone,
|
||||
DebugTraceOutputTypeSetMarker,
|
||||
DebugTraceOutputTypeBeginEvent
|
||||
};
|
||||
|
||||
static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const char *format, va_list vararg)
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
static std::vector<char> buffer(512);
|
||||
|
||||
if (perfActive())
|
||||
{
|
||||
// The perf function only accepts wide strings, widen the ascii message
|
||||
static std::wstring wideMessage;
|
||||
if (wideMessage.capacity() < formattedMessage.length())
|
||||
size_t len = FormatStringIntoVector(format, vararg, buffer);
|
||||
std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
|
||||
|
||||
switch (outputType)
|
||||
{
|
||||
wideMessage.reserve(formattedMessage.size());
|
||||
case DebugTraceOutputTypeNone:
|
||||
break;
|
||||
case DebugTraceOutputTypeBeginEvent:
|
||||
g_DebugAnnotationWrapper->beginEvent(formattedWideMessage);
|
||||
break;
|
||||
case DebugTraceOutputTypeSetMarker:
|
||||
g_DebugAnnotationWrapper->setMarker(formattedWideMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
wideMessage.assign(formattedMessage.begin(), formattedMessage.end());
|
||||
|
||||
perfFunc(0, wideMessage.c_str());
|
||||
}
|
||||
#endif // ANGLE_ENABLE_PERF
|
||||
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
|
||||
#if defined(ANGLE_ENABLE_TRACE)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
#if defined(NDEBUG)
|
||||
if (traceFileDebugOnly)
|
||||
if (traceInDebugOnly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif // NDEBUG
|
||||
std::string formattedMessage = FormatString(format, vararg);
|
||||
|
||||
static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
|
||||
if (file)
|
||||
@ -60,25 +230,29 @@ static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const c
|
||||
file.flush();
|
||||
}
|
||||
|
||||
#endif // ANGLE_ENABLE_TRACE
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
|
||||
OutputDebugStringA(formattedMessage.c_str());
|
||||
#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
|
||||
|
||||
#endif // ANGLE_ENABLE_DEBUG_TRACE
|
||||
}
|
||||
|
||||
void trace(bool traceFileDebugOnly, const char *format, ...)
|
||||
void trace(bool traceInDebugOnly, const char *format, ...)
|
||||
{
|
||||
va_list vararg;
|
||||
va_start(vararg, format);
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
output(traceInDebugOnly, DebugTraceOutputTypeSetMarker, format, vararg);
|
||||
#else
|
||||
output(traceFileDebugOnly, NULL, format, vararg);
|
||||
output(traceInDebugOnly, DebugTraceOutputTypeNone, format, vararg);
|
||||
#endif
|
||||
va_end(vararg);
|
||||
}
|
||||
|
||||
bool perfActive()
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
static bool active = D3DPERF_GetStatus() != 0;
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
static bool active = g_DebugAnnotationWrapper->getStatus();
|
||||
return active;
|
||||
#else
|
||||
return false;
|
||||
@ -87,26 +261,28 @@ bool perfActive()
|
||||
|
||||
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
#if !defined(ANGLE_ENABLE_TRACE)
|
||||
#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
if (!perfActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif // !ANGLE_ENABLE_TRACE
|
||||
#endif // !ANGLE_ENABLE_DEBUG_TRACE
|
||||
va_list vararg;
|
||||
va_start(vararg, format);
|
||||
output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
output(true, DebugTraceOutputTypeBeginEvent, format, vararg);
|
||||
#else
|
||||
output(true, DebugTraceOutputTypeNone, format, vararg);
|
||||
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
va_end(vararg);
|
||||
#endif // ANGLE_ENABLE_PERF
|
||||
}
|
||||
|
||||
ScopedPerfEventHelper::~ScopedPerfEventHelper()
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
if (perfActive())
|
||||
{
|
||||
D3DPERF_EndEvent();
|
||||
g_DebugAnnotationWrapper->endEvent();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
19
src/3rdparty/angle/src/common/debug.h
vendored
19
src/3rdparty/angle/src/common/debug.h
vendored
@ -20,8 +20,8 @@
|
||||
|
||||
namespace gl
|
||||
{
|
||||
// Outputs text to the debugging log
|
||||
void trace(bool traceFileDebugOnly, const char *format, ...);
|
||||
// Outputs text to the debugging log, or the debugging window
|
||||
void trace(bool traceInDebugOnly, const char *format, ...);
|
||||
|
||||
// Returns whether D3DPERF is active.
|
||||
bool perfActive();
|
||||
@ -36,31 +36,34 @@ namespace gl
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper);
|
||||
};
|
||||
|
||||
void InitializeDebugAnnotations();
|
||||
void UninitializeDebugAnnotations();
|
||||
}
|
||||
|
||||
// A macro to output a trace of a function call and its arguments to the debugging log
|
||||
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#define TRACE(message, ...) gl::trace(true, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#else
|
||||
#define TRACE(message, ...) (void(0))
|
||||
#endif
|
||||
|
||||
// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.
|
||||
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#else
|
||||
#define FIXME(message, ...) (void(0))
|
||||
#endif
|
||||
|
||||
// A macro to output a function call and its arguments to the debugging log, in case of error.
|
||||
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#define ERR(message, ...) gl::trace(false, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#else
|
||||
#define ERR(message, ...) (void(0))
|
||||
#endif
|
||||
|
||||
// A macro to log a performance event around a scope.
|
||||
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#if defined(_MSC_VER)
|
||||
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
|
||||
#else
|
||||
@ -83,7 +86,7 @@ namespace gl
|
||||
#define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
|
||||
#endif
|
||||
|
||||
#ifndef ANGLE_ENABLE_TRACE
|
||||
#ifndef ANGLE_ENABLE_DEBUG_TRACE
|
||||
#define UNUSED_TRACE_VARIABLE(variable) ((void)variable)
|
||||
#else
|
||||
#define UNUSED_TRACE_VARIABLE(variable)
|
||||
@ -128,7 +131,7 @@ namespace gl
|
||||
#endif
|
||||
|
||||
// A macro functioning as a compile-time assert to validate constant conditions
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
#if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__GNUC__) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3))
|
||||
#define META_ASSERT_MSG(condition, msg) static_assert(condition, msg)
|
||||
#else
|
||||
#define META_ASSERT_CONCAT(a, b) a ## b
|
||||
|
35
src/3rdparty/angle/src/common/features.h
vendored
Normal file
35
src/3rdparty/angle/src/common/features.h
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#define ANGLE_DISABLED 0
|
||||
#define ANGLE_ENABLED 1
|
||||
|
||||
// Feature defaults
|
||||
|
||||
// Direct3D9EX
|
||||
// The "Debug This Pixel..." feature in PIX often fails when using the
|
||||
// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7
|
||||
// machine, define "ANGLE_D3D9EX=0" in your project file.
|
||||
#if !defined(ANGLE_D3D9EX)
|
||||
#define ANGLE_D3D9EX ANGLE_ENABLED
|
||||
#endif
|
||||
|
||||
// Vsync
|
||||
// ENABLED allows Vsync to be configured at runtime
|
||||
// DISABLED disallows Vsync
|
||||
#if !defined(ANGLE_VSYNC)
|
||||
#define ANGLE_VSYNC ANGLE_ENABLED
|
||||
#endif
|
||||
|
||||
// Program binary loading
|
||||
#if !defined(ANGLE_PROGRAM_BINARY_LOAD)
|
||||
#define ANGLE_PROGRAM_BINARY_LOAD ANGLE_ENABLED
|
||||
#endif
|
||||
|
||||
// Shader debug info
|
||||
#if !defined(ANGLE_SHADER_DEBUG_INFO)
|
||||
#define ANGLE_SHADER_DEBUG_INFO ANGLE_DISABLED
|
||||
#endif
|
4
src/3rdparty/angle/src/common/mathutil.h
vendored
4
src/3rdparty/angle/src/common/mathutil.h
vendored
@ -109,7 +109,7 @@ inline unsigned int unorm(float x)
|
||||
|
||||
inline bool supportsSSE2()
|
||||
{
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM)
|
||||
static bool checked = false;
|
||||
static bool supports = false;
|
||||
|
||||
@ -118,7 +118,6 @@ inline bool supportsSSE2()
|
||||
return supports;
|
||||
}
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_AMD64) // ARM doesn't provide __cpuid()
|
||||
int info[4];
|
||||
__cpuid(info, 0);
|
||||
|
||||
@ -128,7 +127,6 @@ inline bool supportsSSE2()
|
||||
|
||||
supports = (info[3] >> 26) & 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
checked = true;
|
||||
|
||||
|
89
src/3rdparty/angle/src/common/platform.h
vendored
89
src/3rdparty/angle/src/common/platform.h
vendored
@ -11,9 +11,6 @@
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# define ANGLE_PLATFORM_WINDOWS 1
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
|
||||
# define ANGLE_PLATFORM_WINRT 1
|
||||
# endif
|
||||
#elif defined(__APPLE__)
|
||||
# define ANGLE_PLATFORM_APPLE 1
|
||||
# define ANGLE_PLATFORM_POSIX 1
|
||||
@ -37,6 +34,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
# define ANGLE_ENABLE_WINDOWS_STORE 1
|
||||
# endif
|
||||
# ifndef STRICT
|
||||
# define STRICT 1
|
||||
# endif
|
||||
@ -50,7 +50,7 @@
|
||||
# include <windows.h>
|
||||
# include <intrin.h>
|
||||
|
||||
# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF)
|
||||
# if defined(ANGLE_ENABLE_D3D9)
|
||||
# include <d3d9.h>
|
||||
# if !defined(COMPILER_IMPLEMENTATION)
|
||||
# include <d3dcompiler.h>
|
||||
@ -62,13 +62,26 @@
|
||||
# include <d3d10.h>
|
||||
# include <d3d11.h>
|
||||
# include <dxgi.h>
|
||||
# if _MSC_VER >= 1700
|
||||
# if defined(_MSC_VER) && (_MSC_VER >= 1700)
|
||||
# include <d3d11_1.h>
|
||||
# include <dxgi1_2.h>
|
||||
# endif
|
||||
# if !defined(COMPILER_IMPLEMENTATION)
|
||||
# include <d3dcompiler.h>
|
||||
# endif
|
||||
# if defined(__MINGW32__)
|
||||
# endif
|
||||
|
||||
# if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
# include <dxgi1_3.h>
|
||||
# if defined(_DEBUG)
|
||||
# if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
|
||||
# include <DXProgrammableCapture.h>
|
||||
# endif
|
||||
# include <dxgidebug.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(__MINGW32__) // Missing defines on MinGW
|
||||
typedef enum D3D11_MAP_FLAG
|
||||
{
|
||||
D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L
|
||||
@ -78,8 +91,68 @@ typedef struct D3D11_QUERY_DATA_SO_STATISTICS
|
||||
UINT64 NumPrimitivesWritten;
|
||||
UINT64 PrimitivesStorageNeeded;
|
||||
} D3D11_QUERY_DATA_SO_STATISTICS;
|
||||
# endif
|
||||
# endif
|
||||
typedef HRESULT (WINAPI *PFN_D3D11_CREATE_DEVICE)(
|
||||
IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL *,
|
||||
UINT FeatureLevels, UINT, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **);
|
||||
#define D3D11_MESSAGE_CATEGORY UINT
|
||||
#define D3D11_MESSAGE_SEVERITY UINT
|
||||
#define D3D11_MESSAGE_ID UINT
|
||||
struct D3D11_MESSAGE;
|
||||
typedef struct D3D11_INFO_QUEUE_FILTER_DESC
|
||||
{
|
||||
UINT NumCategories;
|
||||
D3D11_MESSAGE_CATEGORY *pCategoryList;
|
||||
UINT NumSeverities;
|
||||
D3D11_MESSAGE_SEVERITY *pSeverityList;
|
||||
UINT NumIDs;
|
||||
D3D11_MESSAGE_ID *pIDList;
|
||||
} D3D11_INFO_QUEUE_FILTER_DESC;
|
||||
typedef struct D3D11_INFO_QUEUE_FILTER
|
||||
{
|
||||
D3D11_INFO_QUEUE_FILTER_DESC AllowList;
|
||||
D3D11_INFO_QUEUE_FILTER_DESC DenyList;
|
||||
} D3D11_INFO_QUEUE_FILTER;
|
||||
static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 };
|
||||
MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0;
|
||||
virtual void __stdcall ClearStoredMessages() = 0;
|
||||
virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0;
|
||||
virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0;
|
||||
virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0;
|
||||
virtual UINT64 __stdcall GetNumStoredMessages() = 0;
|
||||
virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0;
|
||||
virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0;
|
||||
virtual UINT64 __stdcall GetMessageCountLimit() = 0;
|
||||
virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
|
||||
virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
|
||||
virtual void __stdcall ClearStorageFilter() = 0;
|
||||
virtual HRESULT __stdcall PushEmptyStorageFilter() = 0;
|
||||
virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0;
|
||||
virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
|
||||
virtual void __stdcall PopStorageFilter() = 0;
|
||||
virtual UINT __stdcall GetStorageFilterStackSize() = 0;
|
||||
virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
|
||||
virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
|
||||
virtual void __stdcall ClearRetrievalFilter() = 0;
|
||||
virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0;
|
||||
virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0;
|
||||
virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
|
||||
virtual void __stdcall PopRetrievalFilter() = 0;
|
||||
virtual UINT __stdcall GetRetrievalFilterStackSize() = 0;
|
||||
virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0;
|
||||
virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0;
|
||||
virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0;
|
||||
virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0;
|
||||
virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0;
|
||||
virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0;
|
||||
virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0;
|
||||
virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0;
|
||||
virtual void __stdcall SetMuteDebugOutput(BOOL) = 0;
|
||||
virtual BOOL __stdcall GetMuteDebugOutput() = 0;
|
||||
};
|
||||
#endif // __MINGW32__
|
||||
|
||||
# undef near
|
||||
# undef far
|
||||
|
107
src/3rdparty/angle/src/common/tls.cpp
vendored
107
src/3rdparty/angle/src/common/tls.cpp
vendored
@ -10,29 +10,50 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
#include <vector>
|
||||
std::vector<void *> *tls = nullptr;
|
||||
std::vector<TLSIndex> *freeIndices = nullptr;
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
#include <wrl/client.h>
|
||||
#include <wrl/async.h>
|
||||
#include <Windows.System.Threading.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace ABI::Windows::System::Threading;
|
||||
|
||||
// Thread local storage for Windows Store support
|
||||
typedef vector<void*> ThreadLocalData;
|
||||
|
||||
static __declspec(thread) ThreadLocalData* currentThreadData = nullptr;
|
||||
static set<ThreadLocalData*> allThreadData;
|
||||
static DWORD nextTlsIndex = 0;
|
||||
static vector<DWORD> freeTlsIndices;
|
||||
|
||||
#endif
|
||||
|
||||
TLSIndex CreateTLSIndex()
|
||||
{
|
||||
TLSIndex index;
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!tls)
|
||||
tls = new std::vector<void *>;
|
||||
if (freeIndices && !freeIndices->empty()) {
|
||||
index = freeIndices->back();
|
||||
freeIndices->pop_back();
|
||||
return index;
|
||||
} else {
|
||||
tls->push_back(nullptr);
|
||||
return tls->size() - 1;
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
if (!freeTlsIndices.empty())
|
||||
{
|
||||
DWORD result = freeTlsIndices.back();
|
||||
freeTlsIndices.pop_back();
|
||||
index = result;
|
||||
}
|
||||
#elif defined(ANGLE_PLATFORM_WINDOWS)
|
||||
else
|
||||
{
|
||||
index = nextTlsIndex++;
|
||||
}
|
||||
#else
|
||||
index = TlsAlloc();
|
||||
#endif
|
||||
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
// Create global pool key
|
||||
if ((pthread_key_create(&index, NULL)) != 0)
|
||||
@ -53,13 +74,23 @@ bool DestroyTLSIndex(TLSIndex index)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!freeIndices)
|
||||
freeIndices = new std::vector<TLSIndex>;
|
||||
freeIndices->push_back(index);
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
assert(index < nextTlsIndex);
|
||||
assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end());
|
||||
|
||||
freeTlsIndices.push_back(index);
|
||||
for (auto threadData : allThreadData)
|
||||
{
|
||||
if (threadData->size() > index)
|
||||
{
|
||||
threadData->at(index) = nullptr;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
#elif ANGLE_PLATFORM_WINDOWS
|
||||
#else
|
||||
return (TlsFree(index) == TRUE);
|
||||
#endif
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
return (pthread_key_delete(index) == 0);
|
||||
#endif
|
||||
@ -73,11 +104,25 @@ bool SetTLSValue(TLSIndex index, void *value)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
tls->at(index) = value;
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
ThreadLocalData* threadData = currentThreadData;
|
||||
if (!threadData)
|
||||
{
|
||||
threadData = new ThreadLocalData(index + 1, nullptr);
|
||||
allThreadData.insert(threadData);
|
||||
currentThreadData = threadData;
|
||||
}
|
||||
else if (threadData->size() <= index)
|
||||
{
|
||||
threadData->resize(index + 1, nullptr);
|
||||
}
|
||||
|
||||
threadData->at(index) = value;
|
||||
return true;
|
||||
#elif defined(ANGLE_PLATFORM_WINDOWS)
|
||||
#else
|
||||
return (TlsSetValue(index, value) == TRUE);
|
||||
#endif
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
return (pthread_setspecific(index, value) == 0);
|
||||
#endif
|
||||
@ -85,18 +130,26 @@ bool SetTLSValue(TLSIndex index, void *value)
|
||||
|
||||
void *GetTLSValue(TLSIndex index)
|
||||
{
|
||||
#if !defined(ANGLE_PLATFORM_WINRT) // Valid on WinRT, as Alloc handles the index creation
|
||||
assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
|
||||
#endif
|
||||
if (index == TLS_INVALID_INDEX)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
return tls->at(index);
|
||||
#elif defined(ANGLE_PLATFORM_WINDOWS)
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
ThreadLocalData* threadData = currentThreadData;
|
||||
if (threadData && threadData->size() > index)
|
||||
{
|
||||
return threadData->at(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
return TlsGetValue(index);
|
||||
#endif
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
return pthread_getspecific(index);
|
||||
#endif
|
||||
|
17
src/3rdparty/angle/src/common/tls.h
vendored
17
src/3rdparty/angle/src/common/tls.h
vendored
@ -11,11 +11,15 @@
|
||||
|
||||
#include "common/platform.h"
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
typedef size_t TLSIndex;
|
||||
# define TLS_OUT_OF_INDEXES (static_cast<TLSIndex>(-1))
|
||||
# define TLS_INVALID_INDEX TLS_OUT_OF_INDEXES
|
||||
#elif defined(ANGLE_PLATFORM_WINDOWS)
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
|
||||
// TLS does not exist for Windows Store and needs to be emulated
|
||||
# ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
# define TLS_OUT_OF_INDEXES -1
|
||||
# ifndef CREATE_SUSPENDED
|
||||
# define CREATE_SUSPENDED 0x00000004
|
||||
# endif
|
||||
# endif
|
||||
typedef DWORD TLSIndex;
|
||||
# define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
@ -28,6 +32,9 @@
|
||||
# error Unsupported platform.
|
||||
#endif
|
||||
|
||||
// TODO(kbr): for POSIX platforms this will have to be changed to take
|
||||
// in a destructor function pointer, to allow the thread-local storage
|
||||
// to be properly deallocated upon thread exit.
|
||||
TLSIndex CreateTLSIndex();
|
||||
bool DestroyTLSIndex(TLSIndex index);
|
||||
|
||||
|
89
src/3rdparty/angle/src/common/utilities.cpp
vendored
89
src/3rdparty/angle/src/common/utilities.cpp
vendored
@ -9,17 +9,16 @@
|
||||
#include "common/utilities.h"
|
||||
#include "common/mathutil.h"
|
||||
#include "common/platform.h"
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
# include <locale>
|
||||
# include <codecvt>
|
||||
# include <wrl.h>
|
||||
# include <windows.storage.h>
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace ABI::Windows::Storage;
|
||||
#endif
|
||||
|
||||
#include <set>
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
# include <wrl.h>
|
||||
# include <wrl/wrappers/corewrappers.h>
|
||||
# include <windows.applicationmodel.core.h>
|
||||
# include <windows.graphics.display.h>
|
||||
#endif
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
@ -447,50 +446,10 @@ int VariableSortOrder(GLenum type)
|
||||
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
std::string getTempPath()
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
static std::string path;
|
||||
|
||||
while (path.empty())
|
||||
{
|
||||
ComPtr<IApplicationDataStatics> factory;
|
||||
Wrappers::HStringReference classId(RuntimeClass_Windows_Storage_ApplicationData);
|
||||
HRESULT result = RoGetActivationFactory(classId.Get(), IID_PPV_ARGS(&factory));
|
||||
if (FAILED(result))
|
||||
break;
|
||||
|
||||
ComPtr<IApplicationData> applicationData;
|
||||
result = factory->get_Current(&applicationData);
|
||||
if (FAILED(result))
|
||||
break;
|
||||
|
||||
ComPtr<IStorageFolder> storageFolder;
|
||||
result = applicationData->get_LocalFolder(&storageFolder);
|
||||
if (FAILED(result))
|
||||
break;
|
||||
|
||||
ComPtr<IStorageItem> localFolder;
|
||||
result = storageFolder.As(&localFolder);
|
||||
if (FAILED(result))
|
||||
break;
|
||||
|
||||
HSTRING localFolderPath;
|
||||
result = localFolder->get_Path(&localFolderPath);
|
||||
if (FAILED(result))
|
||||
break;
|
||||
|
||||
std::wstring_convert< std::codecvt_utf8<wchar_t> > converter;
|
||||
path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL));
|
||||
if (path.empty())
|
||||
{
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
#elif defined(ANGLE_PLATFORM_WINDOWS)
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
char path[MAX_PATH];
|
||||
DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
|
||||
if (pathLen == 0)
|
||||
@ -525,3 +484,33 @@ void writeFile(const char* path, const void* content, size_t size)
|
||||
fwrite(content, sizeof(char), size, file);
|
||||
fclose(file);
|
||||
}
|
||||
#endif // !ANGLE_ENABLE_WINDOWS_STORE
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
|
||||
void Sleep(unsigned long dwMilliseconds)
|
||||
{
|
||||
static HANDLE singletonEvent = nullptr;
|
||||
HANDLE sleepEvent = singletonEvent;
|
||||
if (!sleepEvent)
|
||||
{
|
||||
sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
|
||||
|
||||
if (!sleepEvent)
|
||||
return;
|
||||
|
||||
HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr);
|
||||
|
||||
if (previousEvent)
|
||||
{
|
||||
// Back out if multiple threads try to demand create at the same time.
|
||||
CloseHandle(sleepEvent);
|
||||
sleepEvent = previousEvent;
|
||||
}
|
||||
}
|
||||
|
||||
// Emulate sleep by waiting with timeout on an event that is never signalled.
|
||||
WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false);
|
||||
}
|
||||
|
||||
#endif // ANGLE_ENABLE_WINDOWS_STORE
|
||||
|
6
src/3rdparty/angle/src/common/utilities.h
vendored
6
src/3rdparty/angle/src/common/utilities.h
vendored
@ -46,7 +46,13 @@ template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(
|
||||
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
std::string getTempPath();
|
||||
void writeFile(const char* path, const void* data, size_t size);
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
void Sleep(_In_ unsigned long dwMilliseconds);
|
||||
#endif
|
||||
|
||||
#endif // LIBGLESV2_UTILITIES_H
|
||||
|
66
src/3rdparty/angle/src/common/win32/NativeWindow.cpp
vendored
Normal file
66
src/3rdparty/angle/src/common/win32/NativeWindow.cpp
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// NativeWindow.cpp: Handler for managing HWND native window types.
|
||||
|
||||
#include "common/NativeWindow.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
|
||||
{
|
||||
return (IsWindow(window) == TRUE);
|
||||
}
|
||||
|
||||
NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display) : mWindow(window), mDisplay(display)
|
||||
{
|
||||
}
|
||||
|
||||
bool NativeWindow::initialize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NativeWindow::getClientRect(LPRECT rect)
|
||||
{
|
||||
return GetClientRect(mWindow, rect) == TRUE;
|
||||
}
|
||||
|
||||
bool NativeWindow::isIconic()
|
||||
{
|
||||
return IsIconic(mWindow) == TRUE;
|
||||
}
|
||||
|
||||
HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory,
|
||||
DXGI_FORMAT format, unsigned int width, unsigned int height,
|
||||
DXGISwapChain** swapChain)
|
||||
{
|
||||
if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
|
||||
swapChainDesc.BufferCount = 1;
|
||||
swapChainDesc.BufferDesc.Format = format;
|
||||
swapChainDesc.BufferDesc.Width = width;
|
||||
swapChainDesc.BufferDesc.Height = height;
|
||||
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
|
||||
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
|
||||
swapChainDesc.Flags = 0;
|
||||
swapChainDesc.OutputWindow = mWindow;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.Windowed = TRUE;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
|
||||
return factory->CreateSwapChain(device, &swapChainDesc, swapChain);
|
||||
}
|
||||
}
|
200
src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
vendored
Normal file
200
src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
vendored
Normal file
@ -0,0 +1,200 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// CoreWindowNativeWindow.cpp: NativeWindow for managing ICoreWindow native window types.
|
||||
|
||||
#include <algorithm>
|
||||
#include "common/winrt/CoreWindowNativeWindow.h"
|
||||
using namespace ABI::Windows::Foundation::Collections;
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
typedef ITypedEventHandler<ABI::Windows::UI::Core::CoreWindow *, ABI::Windows::UI::Core::WindowSizeChangedEventArgs *> SizeChangedHandler;
|
||||
|
||||
CoreWindowNativeWindow::~CoreWindowNativeWindow()
|
||||
{
|
||||
unregisterForSizeChangeEvents();
|
||||
}
|
||||
|
||||
bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
|
||||
{
|
||||
ComPtr<IPropertySet> props = propertySet;
|
||||
ComPtr<IInspectable> win = window;
|
||||
ComPtr<IInspectable> displayInformation = display;
|
||||
SIZE swapChainSize = {};
|
||||
bool swapChainSizeSpecified = false;
|
||||
HRESULT result = S_OK;
|
||||
|
||||
// IPropertySet is an optional parameter and can be null.
|
||||
// If one is specified, cache as an IMap and read the properties
|
||||
// used for initial host initialization.
|
||||
if (propertySet)
|
||||
{
|
||||
result = props.As(&mPropertyMap);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
|
||||
// was prevalidated to contain the EGLNativeWindowType before being passed to
|
||||
// this host.
|
||||
result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = win.As(&mCoreWindow);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = displayInformation.As(&mDisplayInformation);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation2> displayInformation2;
|
||||
result = mDisplayInformation.As(&displayInformation2);
|
||||
ASSERT(SUCCEEDED(result));
|
||||
|
||||
result = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
|
||||
ASSERT(SUCCEEDED(result));
|
||||
#else
|
||||
ABI::Windows::Graphics::Display::ResolutionScale resolutionScale;
|
||||
result = mDisplayInformation->get_ResolutionScale(&resolutionScale);
|
||||
ASSERT(SUCCEEDED(result));
|
||||
|
||||
mScaleFactor = DOUBLE(resolutionScale) / 100.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// If a swapchain size is specfied, then the automatic resize
|
||||
// behaviors implemented by the host should be disabled. The swapchain
|
||||
// will be still be scaled when being rendered to fit the bounds
|
||||
// of the host.
|
||||
// Scaling of the swapchain output occurs automatically because if
|
||||
// the scaling mode setting DXGI_SCALING_STRETCH on the swapchain.
|
||||
if (swapChainSizeSpecified)
|
||||
{
|
||||
mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
|
||||
mSupportsSwapChainResize = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ABI::Windows::Foundation::Rect rect;
|
||||
HRESULT result = mCoreWindow->get_Bounds(&rect);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
LONG width = std::floor(rect.Width * mScaleFactor + 0.5);
|
||||
LONG height = std::floor(rect.Height * mScaleFactor + 0.5);
|
||||
mClientRect = { 0, 0, width, height };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
mNewClientRect = mClientRect;
|
||||
mClientRectChanged = false;
|
||||
return registerForSizeChangeEvents();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CoreWindowNativeWindow::registerForSizeChangeEvents()
|
||||
{
|
||||
HRESULT result = mCoreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &CoreWindowNativeWindow::onSizeChanged).Get(),
|
||||
&mSizeChangedEventToken);
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CoreWindowNativeWindow::unregisterForSizeChangeEvents()
|
||||
{
|
||||
if (mCoreWindow)
|
||||
{
|
||||
(void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken);
|
||||
}
|
||||
mSizeChangedEventToken.value = 0;
|
||||
}
|
||||
|
||||
HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
|
||||
{
|
||||
if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
|
||||
swapChainDesc.Width = width;
|
||||
swapChainDesc.Height = height;
|
||||
swapChainDesc.Format = format;
|
||||
swapChainDesc.Stereo = FALSE;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
|
||||
swapChainDesc.BufferCount = 2;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
|
||||
*swapChain = nullptr;
|
||||
|
||||
ComPtr<IDXGISwapChain1> newSwapChain;
|
||||
HRESULT result = factory->CreateSwapChainForCoreWindow(device, mCoreWindow.Get(), &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
|
||||
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // This block is disabled for Qt applications, as the resize events are expected
|
||||
// Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On
|
||||
// other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed
|
||||
// (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations.
|
||||
if (newSwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.Width, swapChainDesc.Height, swapChainDesc.Format, DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) == DXGI_ERROR_UNSUPPORTED)
|
||||
{
|
||||
mSupportsSwapChainResize = false;
|
||||
}
|
||||
#endif // (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
|
||||
result = newSwapChain.CopyTo(swapChain);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// If automatic swapchain resize behaviors have been disabled, then
|
||||
// unregister for the resize change events.
|
||||
if (mSupportsSwapChainResize == false)
|
||||
{
|
||||
unregisterForSizeChangeEvents();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Basically, this shouldn't be used on Phone
|
||||
HRESULT CoreWindowNativeWindow::onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *e)
|
||||
{
|
||||
ABI::Windows::Foundation::Size size;
|
||||
if (SUCCEEDED(e->get_Size(&size)))
|
||||
{
|
||||
SIZE windowSizeInPixels = {
|
||||
std::floor(size.Width * mScaleFactor + 0.5),
|
||||
std::floor(size.Height * mScaleFactor + 0.5)
|
||||
};
|
||||
setNewClientSize(windowSizeInPixels);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
39
src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
vendored
Normal file
39
src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// CoreWindowNativeWindow.h: NativeWindow for managing ICoreWindow native window types.
|
||||
|
||||
#ifndef COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
|
||||
#define COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
|
||||
|
||||
#include "common/winrt/InspectableNativeWindow.h"
|
||||
#include <memory>
|
||||
#include <windows.graphics.display.h>
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
|
||||
{
|
||||
public:
|
||||
~CoreWindowNativeWindow();
|
||||
|
||||
bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
|
||||
bool registerForSizeChangeEvents();
|
||||
void unregisterForSizeChangeEvents();
|
||||
HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
|
||||
|
||||
private:
|
||||
HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
|
||||
|
||||
ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
|
||||
ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation> mDisplayInformation;
|
||||
ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
|
274
src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
vendored
Normal file
274
src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
vendored
Normal file
@ -0,0 +1,274 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// InspectableNativeWindow.cpp: NativeWindow base class for managing IInspectable native window types.
|
||||
|
||||
#include "common/winrt/CoreWindowNativeWindow.h"
|
||||
#include "common/winrt/SwapChainPanelNativeWindow.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display)
|
||||
: mWindow(window), mDisplay(display)
|
||||
{
|
||||
}
|
||||
|
||||
bool NativeWindow::initialize()
|
||||
{
|
||||
// If the native window type is a IPropertySet, extract the
|
||||
// EGLNativeWindowType (IInspectable) and initialize the
|
||||
// proper host with this IPropertySet.
|
||||
ComPtr<ABI::Windows::Foundation::Collections::IPropertySet> propertySet;
|
||||
ComPtr<IInspectable> eglNativeWindow;
|
||||
if (IsEGLConfiguredPropertySet(mWindow, &propertySet, &eglNativeWindow))
|
||||
{
|
||||
// A property set was found and the EGLNativeWindowType was
|
||||
// retrieved. The mWindow member of the host to must be updated
|
||||
// to use the EGLNativeWindowType specified in the property set.
|
||||
// mWindow is treated as a raw pointer not an AddRef'd interface, so
|
||||
// the old mWindow does not need a Release() before this assignment.
|
||||
mWindow = eglNativeWindow.Get();
|
||||
}
|
||||
|
||||
ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWindow;
|
||||
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel;
|
||||
if (IsCoreWindow(mWindow, &coreWindow))
|
||||
{
|
||||
mImpl = std::make_shared<CoreWindowNativeWindow>();
|
||||
if (mImpl)
|
||||
{
|
||||
return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
|
||||
}
|
||||
}
|
||||
else if (IsSwapChainPanel(mWindow, &swapChainPanel))
|
||||
{
|
||||
mImpl = std::make_shared<SwapChainPanelNativeWindow>();
|
||||
if (mImpl)
|
||||
{
|
||||
return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include ICoreWindow, ISwapChainPanel and IPropertySet");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeWindow::getClientRect(RECT *rect)
|
||||
{
|
||||
if (mImpl)
|
||||
{
|
||||
return mImpl->getClientRect(rect);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeWindow::isIconic()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
|
||||
{
|
||||
if (mImpl)
|
||||
{
|
||||
return mImpl->createSwapChain(device, factory, format, width, height, swapChain);
|
||||
}
|
||||
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ComPtr<IInspectable> win = window;
|
||||
ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWin;
|
||||
if (SUCCEEDED(win.As(&coreWin)))
|
||||
{
|
||||
if (coreWindow != nullptr)
|
||||
{
|
||||
*coreWindow = coreWin.Detach();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ComPtr<IInspectable> win = window;
|
||||
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> panel;
|
||||
if (SUCCEEDED(win.As(&panel)))
|
||||
{
|
||||
if (swapChainPanel != nullptr)
|
||||
{
|
||||
*swapChainPanel = panel.Detach();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet, IInspectable **eglNativeWindow)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ComPtr<IInspectable> props = window;
|
||||
ComPtr<IPropertySet> propSet;
|
||||
ComPtr<IInspectable> nativeWindow;
|
||||
ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> propMap;
|
||||
boolean hasEglNativeWindowPropertyKey = false;
|
||||
|
||||
HRESULT result = props.As(&propSet);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = propSet.As(&propMap);
|
||||
}
|
||||
|
||||
// Look for the presence of the EGLNativeWindowType in the property set
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = propMap->HasKey(HStringReference(EGLNativeWindowTypeProperty).Get(), &hasEglNativeWindowPropertyKey);
|
||||
}
|
||||
|
||||
// If the IPropertySet does not contain the required EglNativeWindowType key, the property set is
|
||||
// considered invalid.
|
||||
if (SUCCEEDED(result) && !hasEglNativeWindowPropertyKey)
|
||||
{
|
||||
ERR("Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid EGLNativeWindowTypeProperty values include ICoreWindow");
|
||||
return false;
|
||||
}
|
||||
|
||||
// The EglNativeWindowType property exists, so retreive the IInspectable that represents the EGLNativeWindowType
|
||||
if (SUCCEEDED(result) && hasEglNativeWindowPropertyKey)
|
||||
{
|
||||
result = propMap->Lookup(HStringReference(EGLNativeWindowTypeProperty).Get(), &nativeWindow);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
if (propertySet != nullptr)
|
||||
{
|
||||
result = propSet.CopyTo(propertySet);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
if (eglNativeWindow != nullptr)
|
||||
{
|
||||
result = nativeWindow.CopyTo(eglNativeWindow);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// A Valid EGLNativeWindowType IInspectable can only be:
|
||||
//
|
||||
// ICoreWindow
|
||||
// IPropertySet
|
||||
//
|
||||
// Anything else will be rejected as an invalid IInspectable.
|
||||
bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
|
||||
{
|
||||
return IsCoreWindow(window) || IsSwapChainPanel(window) || IsEGLConfiguredPropertySet(window);
|
||||
}
|
||||
|
||||
// Attempts to read an optional SIZE property value that is assumed to be in the form of
|
||||
// an ABI::Windows::Foundation::Size. This function validates the Size value before returning
|
||||
// it to the caller.
|
||||
//
|
||||
// Possible return values are:
|
||||
// S_OK, valueExists == true - optional SIZE value was successfully retrieved and validated
|
||||
// S_OK, valueExists == false - optional SIZE value was not found
|
||||
// E_INVALIDARG, valueExists = false - optional SIZE value was malformed in the property set.
|
||||
// * Incorrect property type ( must be PropertyType_Size)
|
||||
// * Invalid property value (width/height must be > 0)
|
||||
// Additional errors may be returned from IMap or IPropertyValue
|
||||
//
|
||||
HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists)
|
||||
{
|
||||
if (!propertyMap || !propertyName || !value || !valueExists)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assume that the value does not exist
|
||||
*valueExists = false;
|
||||
*value = { 0, 0 };
|
||||
|
||||
ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue;
|
||||
ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
|
||||
Size sizeValue = { 0, 0 };
|
||||
boolean hasKey = false;
|
||||
|
||||
HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), &hasKey);
|
||||
if (SUCCEEDED(result) && !hasKey)
|
||||
{
|
||||
// Value does not exist, so return S_OK and set the exists parameter to false to indicate
|
||||
// that a the optional property does not exist.
|
||||
*valueExists = false;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = propertyValue->get_Type(&propertyType);
|
||||
}
|
||||
|
||||
// Check if the expected Size property is of PropertyType_Size type.
|
||||
if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size)
|
||||
{
|
||||
if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0))
|
||||
{
|
||||
// A valid property value exists
|
||||
*value = { static_cast<long>(sizeValue.Width), static_cast<long>(sizeValue.Height) };
|
||||
*valueExists = true;
|
||||
result = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// An invalid Size property was detected. Width/Height values must > 0
|
||||
result = E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// An invalid property type was detected. Size property must be of PropertyType_Size
|
||||
result = E_INVALIDARG;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
91
src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
vendored
Normal file
91
src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// InspectableNativeWindow.h: Host specific implementation interface for
|
||||
// managing IInspectable native window types.
|
||||
|
||||
#ifndef COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
|
||||
#define COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
|
||||
|
||||
#include "common/platform.h"
|
||||
#include "common/NativeWindow.h"
|
||||
#include "angle_windowsstore.h"
|
||||
|
||||
#include <windows.ui.xaml.h>
|
||||
#include <windows.ui.xaml.media.dxinterop.h>
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace ABI::Windows::Foundation::Collections;
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class InspectableNativeWindow
|
||||
{
|
||||
public:
|
||||
InspectableNativeWindow() :
|
||||
mSupportsSwapChainResize(true),
|
||||
mRequiresSwapChainScaling(false),
|
||||
mClientRectChanged(false),
|
||||
mClientRect({0,0,0,0}),
|
||||
mNewClientRect({0,0,0,0}),
|
||||
mScaleFactor(1.0)
|
||||
{
|
||||
mSizeChangedEventToken.value = 0;
|
||||
}
|
||||
virtual ~InspectableNativeWindow(){}
|
||||
|
||||
virtual bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) = 0;
|
||||
virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
|
||||
virtual bool registerForSizeChangeEvents() = 0;
|
||||
virtual void unregisterForSizeChangeEvents() = 0;
|
||||
virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; }
|
||||
|
||||
bool getClientRect(RECT *rect)
|
||||
{
|
||||
if (mClientRectChanged && mSupportsSwapChainResize)
|
||||
{
|
||||
mClientRect = mNewClientRect;
|
||||
mClientRectChanged = false;
|
||||
}
|
||||
|
||||
*rect = mClientRect;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setNewClientSize(const SIZE &newSize)
|
||||
{
|
||||
if (mSupportsSwapChainResize && !mRequiresSwapChainScaling)
|
||||
{
|
||||
mNewClientRect = { 0, 0, newSize.cx, newSize.cy };
|
||||
mClientRectChanged = true;
|
||||
}
|
||||
|
||||
if (mRequiresSwapChainScaling)
|
||||
{
|
||||
scaleSwapChain(newSize);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
bool mSupportsSwapChainResize;
|
||||
bool mRequiresSwapChainScaling;
|
||||
RECT mClientRect;
|
||||
RECT mNewClientRect;
|
||||
bool mClientRectChanged;
|
||||
DOUBLE mScaleFactor;
|
||||
|
||||
EventRegistrationToken mSizeChangedEventToken;
|
||||
};
|
||||
|
||||
bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr);
|
||||
bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel = nullptr);
|
||||
bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr);
|
||||
HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists);
|
||||
}
|
||||
#endif // COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
|
226
src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
vendored
Normal file
226
src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// SwapChainPanelNativeWindow.cpp: NativeWindow for managing ISwapChainPanel native window types.
|
||||
|
||||
#include "common/winrt/SwapChainPanelNativeWindow.h"
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
using namespace ABI::Windows::Foundation::Collections;
|
||||
|
||||
namespace rx
|
||||
{
|
||||
SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow()
|
||||
{
|
||||
unregisterForSizeChangeEvents();
|
||||
}
|
||||
|
||||
bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
|
||||
{
|
||||
ComPtr<IPropertySet> props = propertySet;
|
||||
ComPtr<IInspectable> win = window;
|
||||
SIZE swapChainSize = {};
|
||||
bool swapChainSizeSpecified = false;
|
||||
HRESULT result = S_OK;
|
||||
|
||||
// IPropertySet is an optional parameter and can be null.
|
||||
// If one is specified, cache as an IMap and read the properties
|
||||
// used for initial host initialization.
|
||||
if (propertySet)
|
||||
{
|
||||
result = props.As(&mPropertyMap);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
|
||||
// was prevalidated to contain the EGLNativeWindowType before being passed to
|
||||
// this host.
|
||||
result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = win.As(&mSwapChainPanel);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// If a swapchain size is specfied, then the automatic resize
|
||||
// behaviors implemented by the host should be disabled. The swapchain
|
||||
// will be still be scaled when being rendered to fit the bounds
|
||||
// of the host.
|
||||
// Scaling of the swapchain output needs to be handled by the
|
||||
// host for swapchain panels even though the scaling mode setting
|
||||
// DXGI_SCALING_STRETCH is configured on the swapchain.
|
||||
if (swapChainSizeSpecified)
|
||||
{
|
||||
mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
|
||||
|
||||
// Enable host swapchain scaling
|
||||
mRequiresSwapChainScaling = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
mNewClientRect = mClientRect;
|
||||
mClientRectChanged = false;
|
||||
return registerForSizeChangeEvents();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SwapChainPanelNativeWindow::registerForSizeChangeEvents()
|
||||
{
|
||||
ComPtr<ABI::Windows::UI::Xaml::ISizeChangedEventHandler> sizeChangedHandler;
|
||||
ComPtr<ABI::Windows::UI::Xaml::IFrameworkElement> frameworkElement;
|
||||
HRESULT result = Microsoft::WRL::MakeAndInitialize<SwapChainPanelSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = mSwapChainPanel.As(&frameworkElement);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = frameworkElement->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SwapChainPanelNativeWindow::unregisterForSizeChangeEvents()
|
||||
{
|
||||
ComPtr<ABI::Windows::UI::Xaml::IFrameworkElement> frameworkElement;
|
||||
if (SUCCEEDED(mSwapChainPanel.As(&frameworkElement)))
|
||||
{
|
||||
(void)frameworkElement->remove_SizeChanged(mSizeChangedEventToken);
|
||||
}
|
||||
|
||||
mSizeChangedEventToken.value = 0;
|
||||
}
|
||||
|
||||
HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
|
||||
{
|
||||
if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
|
||||
swapChainDesc.Width = width;
|
||||
swapChainDesc.Height = height;
|
||||
swapChainDesc.Format = format;
|
||||
swapChainDesc.Stereo = FALSE;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
|
||||
swapChainDesc.BufferCount = 2;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
||||
|
||||
*swapChain = nullptr;
|
||||
|
||||
ComPtr<IDXGISwapChain1> newSwapChain;
|
||||
ComPtr<ISwapChainPanelNative> swapChainPanelNative;
|
||||
RECT currentPanelSize = {};
|
||||
|
||||
HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = mSwapChainPanel.As(&swapChainPanelNative);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = swapChainPanelNative->SetSwapChain(newSwapChain.Get());
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// The swapchain panel host requires an instance of the swapchain set on the SwapChainPanel
|
||||
// to perform the runtime-scale behavior. This swapchain is cached here because there are
|
||||
// no methods for retreiving the currently configured on from ISwapChainPanelNative.
|
||||
mSwapChain = newSwapChain;
|
||||
result = newSwapChain.CopyTo(swapChain);
|
||||
}
|
||||
|
||||
// If the host is responsible for scaling the output of the swapchain, then
|
||||
// scale it now before returning an instance to the caller. This is done by
|
||||
// first reading the current size of the swapchain panel, then scaling
|
||||
if (SUCCEEDED(result) && mRequiresSwapChainScaling)
|
||||
{
|
||||
result = GetSwapChainPanelSize(mSwapChainPanel, ¤tPanelSize);
|
||||
}
|
||||
|
||||
// Scale the swapchain to fit inside the contents of the panel.
|
||||
if (SUCCEEDED(result) && mRequiresSwapChainScaling)
|
||||
{
|
||||
SIZE currentSize = { currentPanelSize.right, currentPanelSize.bottom };
|
||||
result = scaleSwapChain(currentSize);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// If automatic swapchain resize behaviors have been disabled, then
|
||||
// unregister for the resize change events.
|
||||
if (mSupportsSwapChainResize == false)
|
||||
{
|
||||
unregisterForSizeChangeEvents();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
|
||||
{
|
||||
ABI::Windows::Foundation::Size renderScale = { (float)newSize.cx/(float)mClientRect.right, (float)newSize.cy/(float)mClientRect.bottom };
|
||||
// Setup a scale matrix for the swap chain
|
||||
DXGI_MATRIX_3X2_F scaleMatrix = {};
|
||||
scaleMatrix._11 = renderScale.Width;
|
||||
scaleMatrix._22 = renderScale.Height;
|
||||
|
||||
ComPtr<IDXGISwapChain2> swapChain2;
|
||||
HRESULT result = mSwapChain.As(&swapChain2);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = swapChain2->SetMatrixTransform(&scaleMatrix);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize)
|
||||
{
|
||||
ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
|
||||
ABI::Windows::Foundation::Size renderSize = { 0, 0 };
|
||||
HRESULT result = swapChainPanel.As(&uiElement);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = uiElement->get_RenderSize(&renderSize);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
*windowSize = { 0, 0, lround(renderSize.Width), lround(renderSize.Height) };
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
79
src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
vendored
Normal file
79
src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// SwapChainPanelNativeWindow.h: NativeWindow for managing ISwapChainPanel native window types.
|
||||
|
||||
#ifndef COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
|
||||
#define COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
|
||||
|
||||
#include "common/winrt/InspectableNativeWindow.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<SwapChainPanelNativeWindow>
|
||||
{
|
||||
public:
|
||||
~SwapChainPanelNativeWindow();
|
||||
|
||||
bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
|
||||
bool registerForSizeChangeEvents();
|
||||
void unregisterForSizeChangeEvents();
|
||||
HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
|
||||
HRESULT scaleSwapChain(const SIZE &newSize);
|
||||
|
||||
private:
|
||||
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
|
||||
ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
|
||||
ComPtr<DXGISwapChain> mSwapChain;
|
||||
};
|
||||
|
||||
[uuid(8ACBD974-8187-4508-AD80-AEC77F93CF36)]
|
||||
class SwapChainPanelSizeChangedHandler :
|
||||
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, ABI::Windows::UI::Xaml::ISizeChangedEventHandler>
|
||||
{
|
||||
public:
|
||||
SwapChainPanelSizeChangedHandler() { }
|
||||
HRESULT RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)
|
||||
{
|
||||
if (!host)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
mHost = host;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// ISizeChangedEventHandler
|
||||
IFACEMETHOD(Invoke)(IInspectable *sender, ABI::Windows::UI::Xaml::ISizeChangedEventArgs *sizeChangedEventArgs)
|
||||
{
|
||||
std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
|
||||
if (host)
|
||||
{
|
||||
// The size of the ISwapChainPanel control is returned in DIPs.
|
||||
// We are keeping these in dips because the swapchain created for composition
|
||||
// also uses dip units. This keeps dimensions, viewports, etc in the same unit.
|
||||
// XAML Clients of the ISwapChainPanel are required to use dips to define their
|
||||
// layout sizes as well.
|
||||
ABI::Windows::Foundation::Size newSize;
|
||||
HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
SIZE windowSize = { lround(newSize.Width), lround(newSize.Height) };
|
||||
host->setNewClientSize(windowSize);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
std::weak_ptr<InspectableNativeWindow> mHost;
|
||||
};
|
||||
|
||||
HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize);
|
||||
}
|
||||
#endif // COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
|
@ -29,7 +29,8 @@ class DirectiveHandler
|
||||
// Handle pragma of form: #pragma name[(value)]
|
||||
virtual void handlePragma(const SourceLocation &loc,
|
||||
const std::string &name,
|
||||
const std::string &value) = 0;
|
||||
const std::string &value,
|
||||
bool stdgl) = 0;
|
||||
|
||||
virtual void handleExtension(const SourceLocation &loc,
|
||||
const std::string &name,
|
||||
|
@ -38,19 +38,19 @@ enum DirectiveType
|
||||
|
||||
DirectiveType getDirective(const pp::Token *token)
|
||||
{
|
||||
static const std::string kDirectiveDefine("define");
|
||||
static const std::string kDirectiveUndef("undef");
|
||||
static const std::string kDirectiveIf("if");
|
||||
static const std::string kDirectiveIfdef("ifdef");
|
||||
static const std::string kDirectiveIfndef("ifndef");
|
||||
static const std::string kDirectiveElse("else");
|
||||
static const std::string kDirectiveElif("elif");
|
||||
static const std::string kDirectiveEndif("endif");
|
||||
static const std::string kDirectiveError("error");
|
||||
static const std::string kDirectivePragma("pragma");
|
||||
static const std::string kDirectiveExtension("extension");
|
||||
static const std::string kDirectiveVersion("version");
|
||||
static const std::string kDirectiveLine("line");
|
||||
const char kDirectiveDefine[] = "define";
|
||||
const char kDirectiveUndef[] = "undef";
|
||||
const char kDirectiveIf[] = "if";
|
||||
const char kDirectiveIfdef[] = "ifdef";
|
||||
const char kDirectiveIfndef[] = "ifndef";
|
||||
const char kDirectiveElse[] = "else";
|
||||
const char kDirectiveElif[] = "elif";
|
||||
const char kDirectiveEndif[] = "endif";
|
||||
const char kDirectiveError[] = "error";
|
||||
const char kDirectivePragma[] = "pragma";
|
||||
const char kDirectiveExtension[] = "extension";
|
||||
const char kDirectiveVersion[] = "version";
|
||||
const char kDirectiveLine[] = "line";
|
||||
|
||||
if (token->type != pp::Token::IDENTIFIER)
|
||||
return DIRECTIVE_NONE;
|
||||
@ -155,7 +155,7 @@ class DefinedParser : public Lexer
|
||||
protected:
|
||||
virtual void lex(Token *token)
|
||||
{
|
||||
static const std::string kDefined("defined");
|
||||
const char kDefined[] = "defined";
|
||||
|
||||
mLexer->lex(token);
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
@ -592,6 +592,11 @@ void DirectiveParser::parsePragma(Token *token)
|
||||
int state = PRAGMA_NAME;
|
||||
|
||||
mTokenizer->lex(token);
|
||||
bool stdgl = token->text == "STDGL";
|
||||
if (stdgl)
|
||||
{
|
||||
mTokenizer->lex(token);
|
||||
}
|
||||
while ((token->type != '\n') && (token->type != Token::LAST))
|
||||
{
|
||||
switch(state++)
|
||||
@ -627,7 +632,7 @@ void DirectiveParser::parsePragma(Token *token)
|
||||
}
|
||||
else if (state > PRAGMA_NAME) // Do not notify for empty pragma.
|
||||
{
|
||||
mDirectiveHandler->handlePragma(token->location, name, value);
|
||||
mDirectiveHandler->handlePragma(token->location, name, value, stdgl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,8 +194,8 @@ bool MacroExpander::expandMacro(const Macro ¯o,
|
||||
|
||||
if (macro.predefined)
|
||||
{
|
||||
static const std::string kLine = "__LINE__";
|
||||
static const std::string kFile = "__FILE__";
|
||||
const char kLine[] = "__LINE__";
|
||||
const char kFile[] = "__FILE__";
|
||||
|
||||
assert(replacements->size() == 1);
|
||||
Token& repl = replacements->front();
|
||||
|
@ -29,24 +29,27 @@
|
||||
|
||||
bool IsWebGLBasedSpec(ShShaderSpec spec)
|
||||
{
|
||||
return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
|
||||
return (spec == SH_WEBGL_SPEC ||
|
||||
spec == SH_CSS_SHADERS_SPEC ||
|
||||
spec == SH_WEBGL2_SPEC);
|
||||
}
|
||||
|
||||
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
|
||||
{
|
||||
// WebGL defines a max token legnth of 256, while ES2 leaves max token
|
||||
// size undefined. ES3 defines a max size of 1024 characters.
|
||||
if (IsWebGLBasedSpec(spec))
|
||||
switch (spec)
|
||||
{
|
||||
case SH_WEBGL_SPEC:
|
||||
case SH_CSS_SHADERS_SPEC:
|
||||
return 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
default:
|
||||
return 1024;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class TScopedPoolAllocator
|
||||
{
|
||||
public:
|
||||
@ -82,6 +85,24 @@ class TScopedSymbolTableLevel
|
||||
private:
|
||||
TSymbolTable* mTable;
|
||||
};
|
||||
|
||||
int MapSpecToShaderVersion(ShShaderSpec spec)
|
||||
{
|
||||
switch (spec)
|
||||
{
|
||||
case SH_GLES2_SPEC:
|
||||
case SH_WEBGL_SPEC:
|
||||
case SH_CSS_SHADERS_SPEC:
|
||||
return 100;
|
||||
case SH_GLES3_SPEC:
|
||||
case SH_WEBGL2_SPEC:
|
||||
return 300;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TShHandleBase::TShHandleBase()
|
||||
@ -178,9 +199,21 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
||||
(parseContext.treeRoot != NULL);
|
||||
|
||||
shaderVersion = parseContext.getShaderVersion();
|
||||
if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion)
|
||||
{
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "unsupported shader version";
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
mPragma = parseContext.pragma();
|
||||
if (mPragma.stdgl.invariantAll)
|
||||
{
|
||||
symbolTable.setGlobalInvariant();
|
||||
}
|
||||
|
||||
TIntermNode* root = parseContext.treeRoot;
|
||||
success = intermediate.postProcess(root);
|
||||
|
||||
@ -360,7 +393,8 @@ void TCompiler::setResourceString()
|
||||
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
|
||||
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
|
||||
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
|
||||
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset;
|
||||
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
|
||||
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers;
|
||||
|
||||
builtInResourcesString = strstream.str();
|
||||
}
|
||||
@ -377,7 +411,6 @@ void TCompiler::clearResults()
|
||||
uniforms.clear();
|
||||
expandedUniforms.clear();
|
||||
varyings.clear();
|
||||
expandedVaryings.clear();
|
||||
interfaceBlocks.clear();
|
||||
|
||||
builtInFunctionEmulator.Cleanup();
|
||||
@ -507,13 +540,12 @@ void TCompiler::collectVariables(TIntermNode* root)
|
||||
&uniforms,
|
||||
&varyings,
|
||||
&interfaceBlocks,
|
||||
hashFunction);
|
||||
hashFunction,
|
||||
symbolTable);
|
||||
root->traverse(&collect);
|
||||
|
||||
// For backwards compatiblity with ShGetVariableInfo, expand struct
|
||||
// uniforms and varyings into separate variables for each field.
|
||||
sh::ExpandVariables(uniforms, &expandedUniforms);
|
||||
sh::ExpandVariables(varyings, &expandedVaryings);
|
||||
// This is for enforcePackingRestriction().
|
||||
sh::ExpandUniforms(uniforms, &expandedUniforms);
|
||||
}
|
||||
|
||||
bool TCompiler::enforcePackingRestrictions()
|
||||
@ -581,3 +613,10 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
|
||||
{
|
||||
return builtInFunctionEmulator;
|
||||
}
|
||||
|
||||
void TCompiler::writePragma()
|
||||
{
|
||||
TInfoSinkBase &sink = infoSink.obj;
|
||||
if (mPragma.stdgl.invariantAll)
|
||||
sink << "#pragma STDGL invariant(all)\n";
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "compiler/translator/ExtensionBehavior.h"
|
||||
#include "compiler/translator/HashNames.h"
|
||||
#include "compiler/translator/InfoSink.h"
|
||||
#include "compiler/translator/Pragma.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
#include "compiler/translator/VariableInfo.h"
|
||||
#include "third_party/compiler/ArrayBoundsClamper.h"
|
||||
@ -71,9 +72,7 @@ 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::ShaderVariable> &getExpandedUniforms() const { return expandedUniforms; }
|
||||
const std::vector<sh::Varying> &getVaryings() const { return varyings; }
|
||||
const std::vector<sh::ShaderVariable> &getExpandedVaryings() const { return expandedVaryings; }
|
||||
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
|
||||
|
||||
ShHashFunction64 getHashFunction() const { return hashFunction; }
|
||||
@ -81,7 +80,7 @@ class TCompiler : public TShHandleBase
|
||||
TSymbolTable& getSymbolTable() { return symbolTable; }
|
||||
ShShaderSpec getShaderSpec() const { return shaderSpec; }
|
||||
ShShaderOutput getOutputType() const { return outputType; }
|
||||
std::string getBuiltInResourcesString() const { return builtInResourcesString; }
|
||||
const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
|
||||
|
||||
// Get the resources set by InitBuiltInSymbolTable
|
||||
const ShBuiltInResources& getResources() const;
|
||||
@ -131,6 +130,8 @@ class TCompiler : public TShHandleBase
|
||||
bool limitExpressionComplexity(TIntermNode* root);
|
||||
// Get built-in extensions with default behavior.
|
||||
const TExtensionBehavior& getExtensionBehavior() const;
|
||||
const TPragma& getPragma() const { return mPragma; }
|
||||
void writePragma();
|
||||
|
||||
const ArrayBoundsClamper& getArrayBoundsClamper() const;
|
||||
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
|
||||
@ -141,7 +142,6 @@ class TCompiler : public TShHandleBase
|
||||
std::vector<sh::Uniform> uniforms;
|
||||
std::vector<sh::ShaderVariable> expandedUniforms;
|
||||
std::vector<sh::Varying> varyings;
|
||||
std::vector<sh::ShaderVariable> expandedVaryings;
|
||||
std::vector<sh::InterfaceBlock> interfaceBlocks;
|
||||
|
||||
private:
|
||||
@ -174,6 +174,8 @@ class TCompiler : public TShHandleBase
|
||||
// name hashing.
|
||||
ShHashFunction64 hashFunction;
|
||||
NameMap nameMap;
|
||||
|
||||
TPragma mPragma;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -14,6 +14,9 @@
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
// Detect Loop Discontinuity
|
||||
|
||||
bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
|
||||
{
|
||||
mLoopDepth = 0;
|
||||
@ -74,6 +77,55 @@ bool containsLoopDiscontinuity(TIntermNode *node)
|
||||
return detectLoopDiscontinuity.traverse(node);
|
||||
}
|
||||
|
||||
// Detect Any Loop
|
||||
|
||||
bool DetectAnyLoop::traverse(TIntermNode *node)
|
||||
{
|
||||
mHasLoop = false;
|
||||
node->traverse(this);
|
||||
return mHasLoop;
|
||||
}
|
||||
|
||||
bool DetectAnyLoop::visitLoop(Visit visit, TIntermLoop *loop)
|
||||
{
|
||||
mHasLoop = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// The following definitions stop all traversal when we have found a loop
|
||||
bool DetectAnyLoop::visitBinary(Visit, TIntermBinary *)
|
||||
{
|
||||
return !mHasLoop;
|
||||
}
|
||||
|
||||
bool DetectAnyLoop::visitUnary(Visit, TIntermUnary *)
|
||||
{
|
||||
return !mHasLoop;
|
||||
}
|
||||
|
||||
bool DetectAnyLoop::visitSelection(Visit, TIntermSelection *)
|
||||
{
|
||||
return !mHasLoop;
|
||||
}
|
||||
|
||||
bool DetectAnyLoop::visitAggregate(Visit, TIntermAggregate *)
|
||||
{
|
||||
return !mHasLoop;
|
||||
}
|
||||
|
||||
bool DetectAnyLoop::visitBranch(Visit, TIntermBranch *)
|
||||
{
|
||||
return !mHasLoop;
|
||||
}
|
||||
|
||||
bool containsAnyLoop(TIntermNode *node)
|
||||
{
|
||||
DetectAnyLoop detectAnyLoop;
|
||||
return detectAnyLoop.traverse(node);
|
||||
}
|
||||
|
||||
// Detect Gradient Operation
|
||||
|
||||
bool DetectGradientOperation::traverse(TIntermNode *node)
|
||||
{
|
||||
mGradientOperation = false;
|
||||
|
@ -32,6 +32,25 @@ class DetectLoopDiscontinuity : public TIntermTraverser
|
||||
|
||||
bool containsLoopDiscontinuity(TIntermNode *node);
|
||||
|
||||
// Checks for the existence of any loop
|
||||
class DetectAnyLoop : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
bool traverse(TIntermNode *node);
|
||||
|
||||
protected:
|
||||
bool visitBinary(Visit, TIntermBinary *);
|
||||
bool visitUnary(Visit, TIntermUnary *);
|
||||
bool visitSelection(Visit, TIntermSelection *);
|
||||
bool visitAggregate(Visit, TIntermAggregate *);
|
||||
bool visitLoop(Visit, TIntermLoop *);
|
||||
bool visitBranch(Visit, TIntermBranch *);
|
||||
|
||||
bool mHasLoop;
|
||||
};
|
||||
|
||||
bool containsAnyLoop(TIntermNode *node);
|
||||
|
||||
// Checks for intrinsic functions which compute gradients
|
||||
class DetectGradientOperation : public TIntermTraverser
|
||||
{
|
||||
|
@ -13,10 +13,10 @@
|
||||
|
||||
static TBehavior getBehavior(const std::string& str)
|
||||
{
|
||||
static const std::string kRequire("require");
|
||||
static const std::string kEnable("enable");
|
||||
static const std::string kDisable("disable");
|
||||
static const std::string kWarn("warn");
|
||||
const char kRequire[] = "require";
|
||||
const char kEnable[] = "enable";
|
||||
const char kDisable[] = "disable";
|
||||
const char kWarn[] = "warn";
|
||||
|
||||
if (str == kRequire) return EBhRequire;
|
||||
else if (str == kEnable) return EBhEnable;
|
||||
@ -46,50 +46,61 @@ void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
|
||||
|
||||
void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
const std::string& value)
|
||||
const std::string& value,
|
||||
bool stdgl)
|
||||
{
|
||||
static const std::string kSTDGL("STDGL");
|
||||
static const std::string kOptimize("optimize");
|
||||
static const std::string kDebug("debug");
|
||||
static const std::string kOn("on");
|
||||
static const std::string kOff("off");
|
||||
if (stdgl)
|
||||
{
|
||||
const char kInvariant[] = "invariant";
|
||||
const char kAll[] = "all";
|
||||
|
||||
bool invalidValue = false;
|
||||
if (name == kSTDGL)
|
||||
{
|
||||
if (name == kInvariant && value == kAll)
|
||||
mPragma.stdgl.invariantAll = true;
|
||||
// The STDGL pragma is used to reserve pragmas for use by future
|
||||
// revisions of GLSL. Ignore it.
|
||||
// revisions of GLSL. Do not generate an error on unexpected
|
||||
// name and value.
|
||||
return;
|
||||
}
|
||||
else if (name == kOptimize)
|
||||
{
|
||||
if (value == kOn) mPragma.optimize = true;
|
||||
else if (value == kOff) mPragma.optimize = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else if (name == kDebug)
|
||||
{
|
||||
if (value == kOn) mPragma.debug = true;
|
||||
else if (value == kOff) mPragma.debug = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
|
||||
return;
|
||||
}
|
||||
const char kOptimize[] = "optimize";
|
||||
const char kDebug[] = "debug";
|
||||
const char kOn[] = "on";
|
||||
const char kOff[] = "off";
|
||||
|
||||
if (invalidValue)
|
||||
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
|
||||
"invalid pragma value", value,
|
||||
"'on' or 'off' expected");
|
||||
bool invalidValue = false;
|
||||
if (name == kOptimize)
|
||||
{
|
||||
if (value == kOn) mPragma.optimize = true;
|
||||
else if (value == kOff) mPragma.optimize = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else if (name == kDebug)
|
||||
{
|
||||
if (value == kOn) mPragma.debug = true;
|
||||
else if (value == kOff) mPragma.debug = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (invalidValue)
|
||||
{
|
||||
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
|
||||
"invalid pragma value", value,
|
||||
"'on' or 'off' expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
const std::string& behavior)
|
||||
{
|
||||
static const std::string kExtAll("all");
|
||||
const char kExtAll[] = "all";
|
||||
|
||||
TBehavior behaviorVal = getBehavior(behavior);
|
||||
if (behaviorVal == EBhUndefined)
|
||||
|
@ -29,7 +29,8 @@ class TDirectiveHandler : public pp::DirectiveHandler
|
||||
|
||||
virtual void handlePragma(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
const std::string& value);
|
||||
const std::string& value,
|
||||
bool stdgl);
|
||||
|
||||
virtual void handleExtension(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
|
@ -133,6 +133,14 @@ bool CompareStructure(const TType &leftNodeType,
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void TIntermTyped::setTypePreservePrecision(const TType &t)
|
||||
{
|
||||
TPrecision precision = getPrecision();
|
||||
mType = t;
|
||||
ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined);
|
||||
mType.setPrecision(precision);
|
||||
}
|
||||
|
||||
#define REPLACE_IF_IS(node, type, original, replacement) \
|
||||
if (node == original) { \
|
||||
node = static_cast<type *>(replacement); \
|
||||
@ -237,6 +245,52 @@ void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) con
|
||||
}
|
||||
}
|
||||
|
||||
void TIntermAggregate::setPrecisionFromChildren()
|
||||
{
|
||||
if (getBasicType() == EbtBool)
|
||||
{
|
||||
mType.setPrecision(EbpUndefined);
|
||||
return;
|
||||
}
|
||||
|
||||
TPrecision precision = EbpUndefined;
|
||||
TIntermSequence::iterator childIter = mSequence.begin();
|
||||
while (childIter != mSequence.end())
|
||||
{
|
||||
TIntermTyped *typed = (*childIter)->getAsTyped();
|
||||
if (typed)
|
||||
precision = GetHigherPrecision(typed->getPrecision(), precision);
|
||||
++childIter;
|
||||
}
|
||||
mType.setPrecision(precision);
|
||||
}
|
||||
|
||||
void TIntermAggregate::setBuiltInFunctionPrecision()
|
||||
{
|
||||
// All built-ins returning bool should be handled as ops, not functions.
|
||||
ASSERT(getBasicType() != EbtBool);
|
||||
|
||||
TPrecision precision = EbpUndefined;
|
||||
TIntermSequence::iterator childIter = mSequence.begin();
|
||||
while (childIter != mSequence.end())
|
||||
{
|
||||
TIntermTyped *typed = (*childIter)->getAsTyped();
|
||||
// ESSL spec section 8: texture functions get their precision from the sampler.
|
||||
if (typed && IsSampler(typed->getBasicType()))
|
||||
{
|
||||
precision = typed->getPrecision();
|
||||
break;
|
||||
}
|
||||
++childIter;
|
||||
}
|
||||
// ESSL 3.0 spec section 8: textureSize always gets highp precision.
|
||||
// All other functions that take a sampler are assumed to be texture functions.
|
||||
if (mName.find("textureSize") == 0)
|
||||
mType.setPrecision(EbpHigh);
|
||||
else
|
||||
mType.setPrecision(precision);
|
||||
}
|
||||
|
||||
bool TIntermSelection::replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement)
|
||||
{
|
||||
@ -336,6 +390,7 @@ bool TIntermUnary::promote(TInfoSink &)
|
||||
return false;
|
||||
break;
|
||||
case EOpNegative:
|
||||
case EOpPositive:
|
||||
case EOpPostIncrement:
|
||||
case EOpPostDecrement:
|
||||
case EOpPreIncrement:
|
||||
@ -1068,6 +1123,27 @@ TIntermTyped *TIntermConstantUnion::fold(
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpPositive:
|
||||
switch (getType().getBasicType())
|
||||
{
|
||||
case EbtFloat:
|
||||
tempConstArray[i].setFConst(unionArray[i].getFConst());
|
||||
break;
|
||||
case EbtInt:
|
||||
tempConstArray[i].setIConst(unionArray[i].getIConst());
|
||||
break;
|
||||
case EbtUInt:
|
||||
tempConstArray[i].setUConst(static_cast<unsigned int>(
|
||||
static_cast<int>(unionArray[i].getUConst())));
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(
|
||||
EPrefixInternalError, getLine(),
|
||||
"Unary operation not folded into constant");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpLogicalNot:
|
||||
// this code is written for possible future use,
|
||||
// will not get executed currently
|
||||
|
@ -45,6 +45,7 @@ enum TOperator
|
||||
//
|
||||
|
||||
EOpNegative,
|
||||
EOpPositive,
|
||||
EOpLogicalNot,
|
||||
EOpVectorLogicalNot,
|
||||
|
||||
@ -265,6 +266,7 @@ class TIntermTyped : public TIntermNode
|
||||
virtual bool hasSideEffects() const = 0;
|
||||
|
||||
void setType(const TType &t) { mType = t; }
|
||||
void setTypePreservePrecision(const TType &t);
|
||||
const TType &getType() const { return mType; }
|
||||
TType *getTypePointer() { return &mType; }
|
||||
|
||||
@ -613,6 +615,9 @@ class TIntermAggregate : public TIntermOperator
|
||||
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
|
||||
|
||||
void setPrecisionFromChildren();
|
||||
void setBuiltInFunctionPrecision();
|
||||
|
||||
protected:
|
||||
TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
|
||||
TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator
|
||||
|
@ -198,6 +198,7 @@ TIntermTyped *TIntermediate::addUnaryMath(
|
||||
case EOpPostDecrement:
|
||||
case EOpPreDecrement:
|
||||
case EOpNegative:
|
||||
case EOpPositive:
|
||||
if (child->getType().getBasicType() == EbtStruct ||
|
||||
child->getType().isArray())
|
||||
{
|
||||
|
@ -395,6 +395,7 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpNegative: preString = "(-"; break;
|
||||
case EOpPositive: preString = "(+"; break;
|
||||
case EOpVectorLogicalNot: preString = "not("; break;
|
||||
case EOpLogicalNot: preString = "(!"; break;
|
||||
|
||||
@ -574,7 +575,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
// Function declaration.
|
||||
ASSERT(visit == PreVisit);
|
||||
writeVariableType(node->getType());
|
||||
out << " " << hashName(node->getName());
|
||||
out << " " << hashFunctionName(node->getName());
|
||||
|
||||
out << "(";
|
||||
writeFunctionParameters(*(node->getSequence()));
|
||||
@ -649,17 +650,18 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
mDeclaringVariables = false;
|
||||
}
|
||||
break;
|
||||
case EOpInvariantDeclaration: {
|
||||
// Invariant declaration.
|
||||
ASSERT(visit == PreVisit);
|
||||
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;
|
||||
out << "invariant " << hashVariableName(symbol->getSymbol());
|
||||
}
|
||||
visitChildren = false;
|
||||
break;
|
||||
case EOpConstructFloat:
|
||||
writeTriplet(visit, "float(", NULL, ")");
|
||||
break;
|
||||
@ -741,7 +743,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction);
|
||||
break;
|
||||
case EOpComma:
|
||||
writeTriplet(visit, NULL, ", ", NULL);
|
||||
writeTriplet(visit, "(", ", ", ")");
|
||||
break;
|
||||
|
||||
case EOpMod:
|
||||
|
@ -135,6 +135,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
|
||||
mUniqueIndex = 0;
|
||||
|
||||
mContainsLoopDiscontinuity = false;
|
||||
mContainsAnyLoop = false;
|
||||
mOutputLod0Function = false;
|
||||
mInsideDiscontinuousLoop = false;
|
||||
mNestedLoopDepth = 0;
|
||||
@ -172,6 +173,7 @@ OutputHLSL::~OutputHLSL()
|
||||
void OutputHLSL::output()
|
||||
{
|
||||
mContainsLoopDiscontinuity = mContext.shaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
|
||||
mContainsAnyLoop = containsAnyLoop(mContext.treeRoot);
|
||||
const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot);
|
||||
makeFlaggedStructMaps(flaggedStructs);
|
||||
|
||||
@ -320,14 +322,22 @@ void OutputHLSL::header()
|
||||
|
||||
if (mUsesDiscardRewriting)
|
||||
{
|
||||
out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n";
|
||||
out << "#define ANGLE_USES_DISCARD_REWRITING\n";
|
||||
}
|
||||
|
||||
if (mUsesNestedBreak)
|
||||
{
|
||||
out << "#define ANGLE_USES_NESTED_BREAK" << "\n";
|
||||
out << "#define ANGLE_USES_NESTED_BREAK\n";
|
||||
}
|
||||
|
||||
out << "#ifdef ANGLE_ENABLE_LOOP_FLATTEN\n"
|
||||
"#define LOOP [loop]\n"
|
||||
"#define FLATTEN [flatten]\n"
|
||||
"#else\n"
|
||||
"#define LOOP\n"
|
||||
"#define FLATTEN\n"
|
||||
"#endif\n";
|
||||
|
||||
if (mContext.shaderType == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
|
||||
@ -1747,6 +1757,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpNegative: outputTriplet(visit, "(-", "", ")"); break;
|
||||
case EOpPositive: outputTriplet(visit, "(+", "", ")"); break;
|
||||
case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
|
||||
case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
|
||||
case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break;
|
||||
@ -1860,15 +1871,20 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
|
||||
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
|
||||
{
|
||||
if (!mInsideFunction)
|
||||
{
|
||||
out << "static ";
|
||||
}
|
||||
|
||||
out << TypeString(variable->getType()) + " ";
|
||||
|
||||
for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
|
||||
{
|
||||
if (isSingleStatement(*sit))
|
||||
{
|
||||
mUnfoldShortCircuit->traverse(*sit);
|
||||
}
|
||||
|
||||
if (!mInsideFunction)
|
||||
{
|
||||
out << "static ";
|
||||
}
|
||||
|
||||
out << TypeString(variable->getType()) + " ";
|
||||
|
||||
TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
|
||||
|
||||
if (symbol)
|
||||
@ -1884,7 +1900,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
|
||||
if (*sit != sequence->back())
|
||||
{
|
||||
out << ", ";
|
||||
out << ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1925,7 +1941,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
case EOpPrototype:
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
out << TypeString(node->getType()) << " " << Decorate(node->getName()) << (mOutputLod0Function ? "Lod0(" : "(");
|
||||
out << TypeString(node->getType()) << " " << Decorate(TFunction::unmangleName(node->getName())) << (mOutputLod0Function ? "Lod0(" : "(");
|
||||
|
||||
TIntermSequence *arguments = node->getSequence();
|
||||
|
||||
@ -2287,6 +2303,15 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
|
||||
{
|
||||
mUnfoldShortCircuit->traverse(node->getCondition());
|
||||
|
||||
// D3D errors when there is a gradient operation in a loop in an unflattened if
|
||||
// however flattening all the ifs in branch heavy shaders made D3D error too.
|
||||
// As a temporary workaround we flatten the ifs only if there is at least a loop
|
||||
// present somewhere in the shader.
|
||||
if (mContext.shaderType == GL_FRAGMENT_SHADER && mContainsAnyLoop)
|
||||
{
|
||||
out << "FLATTEN ";
|
||||
}
|
||||
|
||||
out << "if (";
|
||||
|
||||
node->getCondition()->traverse(this);
|
||||
@ -2367,14 +2392,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
|
||||
|
||||
if (node->getType() == ELoopDoWhile)
|
||||
{
|
||||
out << "{do\n";
|
||||
out << "{LOOP do\n";
|
||||
|
||||
outputLineDirective(node->getLine().first_line);
|
||||
out << "{\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "{for(";
|
||||
out << "{LOOP for(";
|
||||
|
||||
if (node->getInit())
|
||||
{
|
||||
@ -2503,6 +2528,12 @@ bool OutputHLSL::isSingleStatement(TIntermNode *node)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (aggregate->getOp() == EOpDeclaration)
|
||||
{
|
||||
// Declaring multiple comma-separated variables must be considered multiple statements
|
||||
// because each individual declaration has side effects which are visible in the next.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++)
|
||||
@ -2675,7 +2706,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
|
||||
|
||||
// for(int index = initial; index < clampedLimit; index += increment)
|
||||
|
||||
out << "for(";
|
||||
out << "LOOP for(";
|
||||
index->traverse(this);
|
||||
out << " = ";
|
||||
out << initial;
|
||||
|
@ -144,6 +144,7 @@ class OutputHLSL : public TIntermTraverser
|
||||
int mUniqueIndex; // For creating unique names
|
||||
|
||||
bool mContainsLoopDiscontinuity;
|
||||
bool mContainsAnyLoop;
|
||||
bool mOutputLod0Function;
|
||||
bool mInsideDiscontinuousLoop;
|
||||
int mNestedLoopDepth;
|
||||
|
@ -1004,12 +1004,12 @@ void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char*
|
||||
directiveHandler.handleExtension(srcLoc, extName, behavior);
|
||||
}
|
||||
|
||||
void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value)
|
||||
void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl)
|
||||
{
|
||||
pp::SourceLocation srcLoc;
|
||||
srcLoc.file = loc.first_file;
|
||||
srcLoc.line = loc.first_line;
|
||||
directiveHandler.handlePragma(srcLoc, name, value);
|
||||
directiveHandler.handlePragma(srcLoc, name, value, stdgl);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1364,11 +1364,18 @@ TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &inv
|
||||
{
|
||||
error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
|
||||
recover();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
const TString kGlFrontFacing("gl_FrontFacing");
|
||||
if (*identifier == kGlFrontFacing)
|
||||
{
|
||||
error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
|
||||
recover();
|
||||
return NULL;
|
||||
}
|
||||
symbolTable.addInvariantVarying(*identifier);
|
||||
const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
|
||||
ASSERT(variable);
|
||||
const TType &type = variable->getType();
|
||||
|
@ -116,7 +116,7 @@ struct TParseContext {
|
||||
bool supportsExtension(const char* extension);
|
||||
bool isExtensionEnabled(const char* extension) const;
|
||||
void handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior);
|
||||
void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value);
|
||||
void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl);
|
||||
|
||||
bool containsSampler(TType& type);
|
||||
bool areAllChildConst(TIntermAggregate* aggrNode);
|
||||
|
@ -7,13 +7,23 @@
|
||||
#ifndef COMPILER_PRAGMA_H_
|
||||
#define COMPILER_PRAGMA_H_
|
||||
|
||||
struct TPragma {
|
||||
struct TPragma
|
||||
{
|
||||
struct STDGL
|
||||
{
|
||||
STDGL() : invariantAll(false) { }
|
||||
|
||||
bool invariantAll;
|
||||
};
|
||||
|
||||
|
||||
// By default optimization is turned on and debug is turned off.
|
||||
TPragma() : optimize(true), debug(false) { }
|
||||
TPragma(bool o, bool d) : optimize(o), debug(d) { }
|
||||
|
||||
bool optimize;
|
||||
bool debug;
|
||||
STDGL stdgl;
|
||||
};
|
||||
|
||||
#endif // COMPILER_PRAGMA_H_
|
||||
|
@ -37,72 +37,6 @@ bool isInitialized = false;
|
||||
// and the shading language compiler.
|
||||
//
|
||||
|
||||
static bool CheckVariableMaxLengths(const ShHandle handle,
|
||||
size_t expectedValue)
|
||||
{
|
||||
size_t activeUniformLimit = 0;
|
||||
ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
|
||||
size_t activeAttribLimit = 0;
|
||||
ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
|
||||
size_t varyingLimit = 0;
|
||||
ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
|
||||
return (expectedValue == activeUniformLimit &&
|
||||
expectedValue == activeAttribLimit &&
|
||||
expectedValue == varyingLimit);
|
||||
}
|
||||
|
||||
bool CheckMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
|
||||
{
|
||||
size_t mappedNameMaxLength = 0;
|
||||
ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
|
||||
return (expectedValue == mappedNameMaxLength);
|
||||
}
|
||||
|
||||
template <typename VarT>
|
||||
const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoList, int index)
|
||||
{
|
||||
if (index < 0 || static_cast<size_t>(index) >= infoList.size())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &infoList[index];
|
||||
}
|
||||
|
||||
const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index)
|
||||
{
|
||||
switch (varType)
|
||||
{
|
||||
case SH_ACTIVE_ATTRIBUTES:
|
||||
return ReturnVariable(compiler->getAttributes(), index);
|
||||
case SH_ACTIVE_UNIFORMS:
|
||||
return ReturnVariable(compiler->getExpandedUniforms(), index);
|
||||
case SH_VARYINGS:
|
||||
return ReturnVariable(compiler->getExpandedVaryings(), index);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ShPrecisionType ConvertPrecision(sh::GLenum precision)
|
||||
{
|
||||
switch (precision)
|
||||
{
|
||||
case GL_HIGH_FLOAT:
|
||||
case GL_HIGH_INT:
|
||||
return SH_PRECISION_HIGHP;
|
||||
case GL_MEDIUM_FLOAT:
|
||||
case GL_MEDIUM_INT:
|
||||
return SH_PRECISION_MEDIUMP;
|
||||
case GL_LOW_FLOAT:
|
||||
case GL_LOW_INT:
|
||||
return SH_PRECISION_LOWP;
|
||||
default:
|
||||
return SH_PRECISION_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VarT>
|
||||
const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
|
||||
|
||||
@ -150,32 +84,48 @@ const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariabl
|
||||
return GetVariableList<VarT>(compiler, variableType);
|
||||
}
|
||||
|
||||
TCompiler *GetCompilerFromHandle(ShHandle handle)
|
||||
{
|
||||
if (!handle)
|
||||
return NULL;
|
||||
TShHandleBase *base = static_cast<TShHandleBase *>(handle);
|
||||
return base->getAsCompiler();
|
||||
}
|
||||
|
||||
TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
|
||||
{
|
||||
if (!handle)
|
||||
return NULL;
|
||||
TShHandleBase *base = static_cast<TShHandleBase *>(handle);
|
||||
return base->getAsTranslatorHLSL();
|
||||
}
|
||||
|
||||
} // namespace anonymous
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other compiler operations.
|
||||
// Subsequent calls to this function are no-op.
|
||||
//
|
||||
int ShInitialize()
|
||||
bool ShInitialize()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
isInitialized = InitProcess();
|
||||
}
|
||||
return isInitialized ? 1 : 0;
|
||||
return isInitialized;
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup symbol tables
|
||||
//
|
||||
int ShFinalize()
|
||||
bool ShFinalize()
|
||||
{
|
||||
if (isInitialized)
|
||||
{
|
||||
DetachProcess();
|
||||
isInitialized = false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
@ -183,6 +133,9 @@ int ShFinalize()
|
||||
//
|
||||
void ShInitBuiltInResources(ShBuiltInResources* resources)
|
||||
{
|
||||
// Make comparable.
|
||||
memset(resources, 0, sizeof(*resources));
|
||||
|
||||
// Constants.
|
||||
resources->MaxVertexAttribs = 8;
|
||||
resources->MaxVertexUniformVectors = 128;
|
||||
@ -201,6 +154,8 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
|
||||
resources->EXT_frag_depth = 0;
|
||||
resources->EXT_shader_texture_lod = 0;
|
||||
|
||||
resources->NV_draw_buffers = 0;
|
||||
|
||||
// Disable highp precision in fragment shader by default.
|
||||
resources->FragmentPrecisionHigh = 0;
|
||||
|
||||
@ -251,23 +206,13 @@ void ShDestruct(ShHandle handle)
|
||||
DeleteCompiler(base->getAsCompiler());
|
||||
}
|
||||
|
||||
void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outString)
|
||||
const std::string &ShGetBuiltInResourcesString(const ShHandle handle)
|
||||
{
|
||||
if (!handle || !outString)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TShHandleBase *base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler *compiler = base->getAsCompiler();
|
||||
if (!compiler)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(outString, compiler->getBuiltInResourcesString().c_str(), outStringLen);
|
||||
outString[outStringLen - 1] = '\0';
|
||||
TCompiler *compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
return compiler->getBuiltInResourcesString();
|
||||
}
|
||||
|
||||
//
|
||||
// Do an actual compile on the given strings. The result is left
|
||||
// in the given compile object.
|
||||
@ -275,219 +220,62 @@ void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, cha
|
||||
// Return: The return value of ShCompile is really boolean, indicating
|
||||
// success or failure.
|
||||
//
|
||||
int ShCompile(
|
||||
bool ShCompile(
|
||||
const ShHandle handle,
|
||||
const char* const shaderStrings[],
|
||||
const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
int compileOptions)
|
||||
{
|
||||
if (handle == 0)
|
||||
return 0;
|
||||
TCompiler *compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
|
||||
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
return 0;
|
||||
|
||||
bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
|
||||
return success ? 1 : 0;
|
||||
return compiler->compile(shaderStrings, numStrings, compileOptions);
|
||||
}
|
||||
|
||||
void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
|
||||
int ShGetShaderVersion(const ShHandle handle)
|
||||
{
|
||||
if (!handle || !params)
|
||||
return;
|
||||
TCompiler* compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
return compiler->getShaderVersion();
|
||||
}
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
case SH_INFO_LOG_LENGTH:
|
||||
*params = compiler->getInfoSink().info.size() + 1;
|
||||
break;
|
||||
case SH_OBJECT_CODE_LENGTH:
|
||||
*params = compiler->getInfoSink().obj.size() + 1;
|
||||
break;
|
||||
case SH_ACTIVE_UNIFORMS:
|
||||
*params = compiler->getExpandedUniforms().size();
|
||||
break;
|
||||
case SH_ACTIVE_UNIFORM_MAX_LENGTH:
|
||||
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
break;
|
||||
case SH_ACTIVE_ATTRIBUTES:
|
||||
*params = compiler->getAttributes().size();
|
||||
break;
|
||||
case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
|
||||
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
break;
|
||||
case SH_VARYINGS:
|
||||
*params = compiler->getExpandedVaryings().size();
|
||||
break;
|
||||
case SH_VARYING_MAX_LENGTH:
|
||||
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
break;
|
||||
case SH_MAPPED_NAME_MAX_LENGTH:
|
||||
// Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
|
||||
// handle array and struct dereferences.
|
||||
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
break;
|
||||
case SH_NAME_MAX_LENGTH:
|
||||
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
break;
|
||||
case SH_HASHED_NAME_MAX_LENGTH:
|
||||
if (compiler->getHashFunction() == NULL) {
|
||||
*params = 0;
|
||||
} else {
|
||||
// 64 bits hashing output requires 16 bytes for hex
|
||||
// representation.
|
||||
const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
|
||||
(void)HashedNamePrefix;
|
||||
*params = 16 + sizeof(HashedNamePrefix);
|
||||
}
|
||||
break;
|
||||
case SH_HASHED_NAMES_COUNT:
|
||||
*params = compiler->getNameMap().size();
|
||||
break;
|
||||
case SH_SHADER_VERSION:
|
||||
*params = compiler->getShaderVersion();
|
||||
break;
|
||||
case SH_RESOURCES_STRING_LENGTH:
|
||||
*params = compiler->getBuiltInResourcesString().length() + 1;
|
||||
break;
|
||||
case SH_OUTPUT_TYPE:
|
||||
*params = compiler->getOutputType();
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
ShShaderOutput ShGetShaderOutputType(const ShHandle handle)
|
||||
{
|
||||
TCompiler* compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
return compiler->getOutputType();
|
||||
}
|
||||
|
||||
//
|
||||
// Return any compiler log of messages for the application.
|
||||
//
|
||||
void ShGetInfoLog(const ShHandle handle, char* infoLog)
|
||||
const std::string &ShGetInfoLog(const ShHandle handle)
|
||||
{
|
||||
if (!handle || !infoLog)
|
||||
return;
|
||||
TCompiler *compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
TInfoSink& infoSink = compiler->getInfoSink();
|
||||
strcpy(infoLog, infoSink.info.c_str());
|
||||
TInfoSink &infoSink = compiler->getInfoSink();
|
||||
return infoSink.info.str();
|
||||
}
|
||||
|
||||
//
|
||||
// Return any object code.
|
||||
//
|
||||
void ShGetObjectCode(const ShHandle handle, char* objCode)
|
||||
const std::string &ShGetObjectCode(const ShHandle handle)
|
||||
{
|
||||
if (!handle || !objCode)
|
||||
return;
|
||||
TCompiler *compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
TInfoSink& infoSink = compiler->getInfoSink();
|
||||
strcpy(objCode, infoSink.obj.c_str());
|
||||
TInfoSink &infoSink = compiler->getInfoSink();
|
||||
return infoSink.obj.str();
|
||||
}
|
||||
|
||||
void ShGetVariableInfo(const ShHandle handle,
|
||||
ShShaderInfo varType,
|
||||
int index,
|
||||
size_t* length,
|
||||
int* size,
|
||||
sh::GLenum* type,
|
||||
ShPrecisionType* precision,
|
||||
int* staticUse,
|
||||
char* name,
|
||||
char* mappedName)
|
||||
const std::map<std::string, std::string> *ShGetNameHashingMap(
|
||||
const ShHandle handle)
|
||||
{
|
||||
if (!handle || !size || !type || !precision || !staticUse || !name)
|
||||
return;
|
||||
ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
|
||||
(varType == SH_ACTIVE_UNIFORMS) ||
|
||||
(varType == SH_VARYINGS));
|
||||
|
||||
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
return;
|
||||
|
||||
const sh::ShaderVariable *varInfo = GetVariable(compiler, varType, index);
|
||||
if (!varInfo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (length) *length = varInfo->name.size();
|
||||
*size = varInfo->elementCount();
|
||||
*type = varInfo->type;
|
||||
*precision = ConvertPrecision(varInfo->precision);
|
||||
*staticUse = varInfo->staticUse ? 1 : 0;
|
||||
|
||||
// This size must match that queried by
|
||||
// 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));
|
||||
strncpy(name, varInfo->name.c_str(), variableLength);
|
||||
name[variableLength - 1] = 0;
|
||||
if (mappedName)
|
||||
{
|
||||
// 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));
|
||||
strncpy(mappedName, varInfo->mappedName.c_str(), maxMappedNameLength);
|
||||
mappedName[maxMappedNameLength - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ShGetNameHashingEntry(const ShHandle handle,
|
||||
int index,
|
||||
char* name,
|
||||
char* hashedName)
|
||||
{
|
||||
if (!handle || !name || !hashedName || index < 0)
|
||||
return;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
const NameMap& nameMap = compiler->getNameMap();
|
||||
if (index >= static_cast<int>(nameMap.size()))
|
||||
return;
|
||||
|
||||
NameMap::const_iterator it = nameMap.begin();
|
||||
for (int i = 0; i < index; ++i)
|
||||
++it;
|
||||
|
||||
size_t len = it->first.length() + 1;
|
||||
size_t max_len = 0;
|
||||
ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
|
||||
if (len > max_len) {
|
||||
ASSERT(false);
|
||||
len = max_len;
|
||||
}
|
||||
strncpy(name, it->first.c_str(), len);
|
||||
// To be on the safe side in case the source is longer than expected.
|
||||
name[len - 1] = '\0';
|
||||
|
||||
len = it->second.length() + 1;
|
||||
max_len = 0;
|
||||
ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
|
||||
if (len > max_len) {
|
||||
ASSERT(false);
|
||||
len = max_len;
|
||||
}
|
||||
strncpy(hashedName, it->second.c_str(), len);
|
||||
// To be on the safe side in case the source is longer than expected.
|
||||
hashedName[len - 1] = '\0';
|
||||
TCompiler *compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
return &(compiler->getNameMap());
|
||||
}
|
||||
|
||||
const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
|
||||
@ -515,11 +303,11 @@ const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handl
|
||||
return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
|
||||
}
|
||||
|
||||
int ShCheckVariablesWithinPackingLimits(
|
||||
int maxVectors, ShVariableInfo* varInfoArray, size_t varInfoArraySize)
|
||||
bool ShCheckVariablesWithinPackingLimits(
|
||||
int maxVectors, ShVariableInfo *varInfoArray, size_t varInfoArraySize)
|
||||
{
|
||||
if (varInfoArraySize == 0)
|
||||
return 1;
|
||||
return true;
|
||||
ASSERT(varInfoArray);
|
||||
std::vector<sh::ShaderVariable> variables;
|
||||
for (size_t ii = 0; ii < varInfoArraySize; ++ii)
|
||||
@ -528,24 +316,17 @@ int ShCheckVariablesWithinPackingLimits(
|
||||
variables.push_back(var);
|
||||
}
|
||||
VariablePacker packer;
|
||||
return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0;
|
||||
return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
|
||||
}
|
||||
|
||||
bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
const char *interfaceBlockName,
|
||||
const std::string &interfaceBlockName,
|
||||
unsigned int *indexOut)
|
||||
{
|
||||
if (!handle || !interfaceBlockName || !indexOut)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ASSERT(indexOut);
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TranslatorHLSL* translator = base->getAsTranslatorHLSL();
|
||||
if (!translator)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
|
||||
ASSERT(translator);
|
||||
|
||||
if (!translator->hasInterfaceBlock(interfaceBlockName))
|
||||
{
|
||||
@ -557,20 +338,12 @@ bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
}
|
||||
|
||||
bool ShGetUniformRegister(const ShHandle handle,
|
||||
const char *uniformName,
|
||||
const std::string &uniformName,
|
||||
unsigned int *indexOut)
|
||||
{
|
||||
if (!handle || !uniformName || !indexOut)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TranslatorHLSL* translator = base->getAsTranslatorHLSL();
|
||||
if (!translator)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ASSERT(indexOut);
|
||||
TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
|
||||
ASSERT(translator);
|
||||
|
||||
if (!translator->hasUniform(uniformName))
|
||||
{
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include <GLSLANG/ShaderLang.h>
|
||||
|
||||
#include "compiler/translator/compilerdebug.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
@ -53,6 +55,126 @@ ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool ShaderVariable::operator==(const ShaderVariable &other) const
|
||||
{
|
||||
if (type != other.type ||
|
||||
precision != other.precision ||
|
||||
name != other.name ||
|
||||
mappedName != other.mappedName ||
|
||||
arraySize != other.arraySize ||
|
||||
staticUse != other.staticUse ||
|
||||
fields.size() != other.fields.size() ||
|
||||
structName != other.structName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (size_t ii = 0; ii < fields.size(); ++ii)
|
||||
{
|
||||
if (fields[ii] != other.fields[ii])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShaderVariable::findInfoByMappedName(
|
||||
const std::string &mappedFullName,
|
||||
const ShaderVariable **leafVar, std::string *originalFullName) const
|
||||
{
|
||||
ASSERT(leafVar && originalFullName);
|
||||
// There are three cases:
|
||||
// 1) the top variable is of struct type;
|
||||
// 2) the top variable is an array;
|
||||
// 3) otherwise.
|
||||
size_t pos = mappedFullName.find_first_of(".[");
|
||||
std::string topName;
|
||||
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
// Case 3.
|
||||
if (mappedFullName != this->mappedName)
|
||||
return false;
|
||||
*originalFullName = this->name;
|
||||
*leafVar = this;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string topName = mappedFullName.substr(0, pos);
|
||||
if (topName != this->mappedName)
|
||||
return false;
|
||||
std::string originalName = this->name;
|
||||
std::string remaining;
|
||||
if (mappedFullName[pos] == '[')
|
||||
{
|
||||
// Case 2.
|
||||
size_t closePos = mappedFullName.find_first_of(']');
|
||||
if (closePos < pos || closePos == std::string::npos)
|
||||
return false;
|
||||
// Append '[index]'.
|
||||
originalName += mappedFullName.substr(pos, closePos - pos + 1);
|
||||
if (closePos + 1 == mappedFullName.size())
|
||||
{
|
||||
*originalFullName = originalName;
|
||||
*leafVar = this;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In the form of 'a[0].b', so after ']', '.' is expected.
|
||||
if (mappedFullName[closePos + 1] != '.')
|
||||
return false;
|
||||
remaining = mappedFullName.substr(closePos + 2); // Skip "]."
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 1.
|
||||
remaining = mappedFullName.substr(pos + 1); // Skip "."
|
||||
}
|
||||
for (size_t ii = 0; ii < this->fields.size(); ++ii)
|
||||
{
|
||||
const ShaderVariable *fieldVar = NULL;
|
||||
std::string originalFieldName;
|
||||
bool found = fields[ii].findInfoByMappedName(
|
||||
remaining, &fieldVar, &originalFieldName);
|
||||
if (found)
|
||||
{
|
||||
*originalFullName = originalName + "." + originalFieldName;
|
||||
*leafVar = fieldVar;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ShaderVariable::isSameVariableAtLinkTime(
|
||||
const ShaderVariable &other, bool matchPrecision) const
|
||||
{
|
||||
if (type != other.type)
|
||||
return false;
|
||||
if (matchPrecision && precision != other.precision)
|
||||
return false;
|
||||
if (name != other.name)
|
||||
return false;
|
||||
ASSERT(mappedName == other.mappedName);
|
||||
if (arraySize != other.arraySize)
|
||||
return false;
|
||||
if (fields.size() != other.fields.size())
|
||||
return false;
|
||||
for (size_t ii = 0; ii < fields.size(); ++ii)
|
||||
{
|
||||
if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii],
|
||||
matchPrecision))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (structName != other.structName)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Uniform::Uniform()
|
||||
{}
|
||||
|
||||
@ -69,6 +191,16 @@ Uniform &Uniform::operator=(const Uniform &other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Uniform::operator==(const Uniform &other) const
|
||||
{
|
||||
return ShaderVariable::operator==(other);
|
||||
}
|
||||
|
||||
bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
|
||||
{
|
||||
return ShaderVariable::isSameVariableAtLinkTime(other, true);
|
||||
}
|
||||
|
||||
Attribute::Attribute()
|
||||
: location(-1)
|
||||
{}
|
||||
@ -88,6 +220,12 @@ Attribute &Attribute::operator=(const Attribute &other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Attribute::operator==(const Attribute &other) const
|
||||
{
|
||||
return (ShaderVariable::operator==(other) &&
|
||||
location == other.location);
|
||||
}
|
||||
|
||||
InterfaceBlockField::InterfaceBlockField()
|
||||
: isRowMajorLayout(false)
|
||||
{}
|
||||
@ -107,6 +245,19 @@ InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &o
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool InterfaceBlockField::operator==(const InterfaceBlockField &other) const
|
||||
{
|
||||
return (ShaderVariable::operator==(other) &&
|
||||
isRowMajorLayout == other.isRowMajorLayout);
|
||||
}
|
||||
|
||||
bool InterfaceBlockField::isSameInterfaceBlockFieldAtLinkTime(
|
||||
const InterfaceBlockField &other) const
|
||||
{
|
||||
return (ShaderVariable::isSameVariableAtLinkTime(other, true) &&
|
||||
isRowMajorLayout == other.isRowMajorLayout);
|
||||
}
|
||||
|
||||
Varying::Varying()
|
||||
: interpolation(INTERPOLATION_SMOOTH),
|
||||
isInvariant(false)
|
||||
@ -129,6 +280,20 @@ Varying &Varying::operator=(const Varying &other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Varying::operator==(const Varying &other) const
|
||||
{
|
||||
return (ShaderVariable::operator==(other) &&
|
||||
interpolation == other.interpolation &&
|
||||
isInvariant == other.isInvariant);
|
||||
}
|
||||
|
||||
bool Varying::isSameVaryingAtLinkTime(const Varying &other) const
|
||||
{
|
||||
return (ShaderVariable::isSameVariableAtLinkTime(other, false) &&
|
||||
interpolation == other.interpolation &&
|
||||
isInvariant == other.isInvariant);
|
||||
}
|
||||
|
||||
InterfaceBlock::InterfaceBlock()
|
||||
: arraySize(0),
|
||||
layout(BLOCKLAYOUT_PACKED),
|
||||
|
@ -31,6 +31,7 @@
|
||||
//
|
||||
|
||||
#include <assert.h>
|
||||
#include <set>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/translator/InfoSink.h"
|
||||
@ -299,19 +300,21 @@ class TSymbolTableLevel
|
||||
tLevel level;
|
||||
};
|
||||
|
||||
enum ESymbolLevel
|
||||
{
|
||||
COMMON_BUILTINS = 0,
|
||||
ESSL1_BUILTINS = 1,
|
||||
ESSL3_BUILTINS = 2,
|
||||
LAST_BUILTIN_LEVEL = ESSL3_BUILTINS,
|
||||
GLOBAL_LEVEL = 3
|
||||
};
|
||||
// Define ESymbolLevel as int rather than an enum since level can go
|
||||
// above GLOBAL_LEVEL and cause atBuiltInLevel() to fail if the
|
||||
// compiler optimizes the >= of the last element to ==.
|
||||
typedef int ESymbolLevel;
|
||||
const int COMMON_BUILTINS = 0;
|
||||
const int ESSL1_BUILTINS = 1;
|
||||
const int ESSL3_BUILTINS = 2;
|
||||
const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS;
|
||||
const int GLOBAL_LEVEL = 3;
|
||||
|
||||
class TSymbolTable
|
||||
{
|
||||
public:
|
||||
TSymbolTable()
|
||||
: mGlobalInvariant(false)
|
||||
{
|
||||
// The symbol table cannot be used until push() is called, but
|
||||
// the lack of an initial call to push() can be used to detect
|
||||
@ -408,6 +411,25 @@ class TSymbolTable
|
||||
// for the specified TBasicType
|
||||
TPrecision getDefaultPrecision(TBasicType type) const;
|
||||
|
||||
// This records invariant varyings declared through
|
||||
// "invariant varying_name;".
|
||||
void addInvariantVarying(const TString &originalName)
|
||||
{
|
||||
mInvariantVaryings.insert(originalName);
|
||||
}
|
||||
// If this returns false, the varying could still be invariant
|
||||
// if it is set as invariant during the varying variable
|
||||
// declaration - this piece of information is stored in the
|
||||
// variable's type, not here.
|
||||
bool isVaryingInvariant(const TString &originalName) const
|
||||
{
|
||||
return (mGlobalInvariant ||
|
||||
mInvariantVaryings.count(originalName) > 0);
|
||||
}
|
||||
|
||||
void setGlobalInvariant() { mGlobalInvariant = true; }
|
||||
bool getGlobalInvariant() const { return mGlobalInvariant; }
|
||||
|
||||
static int nextUniqueId()
|
||||
{
|
||||
return ++uniqueIdCounter;
|
||||
@ -423,6 +445,9 @@ class TSymbolTable
|
||||
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
|
||||
std::vector< PrecisionStackLevel *> precisionStack;
|
||||
|
||||
std::set<TString> mInvariantVaryings;
|
||||
bool mGlobalInvariant;
|
||||
|
||||
static int uniqueIdCounter;
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,8 @@ TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
|
||||
void TranslatorESSL::translate(TIntermNode* root) {
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
|
||||
writePragma();
|
||||
|
||||
// Write built-in extension behaviors.
|
||||
writeExtensionBehavior();
|
||||
|
||||
@ -37,8 +39,13 @@ void TranslatorESSL::writeExtensionBehavior() {
|
||||
for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
|
||||
iter != extensionBehavior.end(); ++iter) {
|
||||
if (iter->second != EBhUndefined) {
|
||||
sink << "#extension " << iter->first << " : "
|
||||
<< getBehaviorString(iter->second) << "\n";
|
||||
if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") {
|
||||
sink << "#extension GL_NV_draw_buffers : "
|
||||
<< getBehaviorString(iter->second) << "\n";
|
||||
} else {
|
||||
sink << "#extension " << iter->first << " : "
|
||||
<< getBehaviorString(iter->second) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,18 +9,6 @@
|
||||
#include "compiler/translator/OutputGLSL.h"
|
||||
#include "compiler/translator/VersionGLSL.h"
|
||||
|
||||
static void writeVersion(sh::GLenum type, TIntermNode* root,
|
||||
TInfoSinkBase& sink) {
|
||||
TVersionGLSL versionGLSL(type);
|
||||
root->traverse(&versionGLSL);
|
||||
int version = versionGLSL.getVersion();
|
||||
// We need to write version directive only if it is greater than 110.
|
||||
// If there is no version directive in the shader, 110 is implied.
|
||||
if (version > 110) {
|
||||
sink << "#version " << version << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec)
|
||||
: TCompiler(type, spec, SH_GLSL_OUTPUT) {
|
||||
}
|
||||
@ -29,7 +17,9 @@ void TranslatorGLSL::translate(TIntermNode* root) {
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
|
||||
// Write GLSL version.
|
||||
writeVersion(getShaderType(), root, sink);
|
||||
writeVersion(root);
|
||||
|
||||
writePragma();
|
||||
|
||||
// Write extension behaviour as needed
|
||||
writeExtensionBehavior();
|
||||
@ -46,6 +36,20 @@ void TranslatorGLSL::translate(TIntermNode* root) {
|
||||
root->traverse(&outputGLSL);
|
||||
}
|
||||
|
||||
void TranslatorGLSL::writeVersion(TIntermNode *root)
|
||||
{
|
||||
TVersionGLSL versionGLSL(getShaderType(), getPragma());
|
||||
root->traverse(&versionGLSL);
|
||||
int version = versionGLSL.getVersion();
|
||||
// We need to write version directive only if it is greater than 110.
|
||||
// If there is no version directive in the shader, 110 is implied.
|
||||
if (version > 110)
|
||||
{
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
sink << "#version " << version << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void TranslatorGLSL::writeExtensionBehavior() {
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
|
||||
|
@ -9,14 +9,16 @@
|
||||
|
||||
#include "compiler/translator/Compiler.h"
|
||||
|
||||
class TranslatorGLSL : public TCompiler {
|
||||
public:
|
||||
class TranslatorGLSL : public TCompiler
|
||||
{
|
||||
public:
|
||||
TranslatorGLSL(sh::GLenum type, ShShaderSpec spec);
|
||||
|
||||
protected:
|
||||
virtual void translate(TIntermNode* root);
|
||||
protected:
|
||||
virtual void translate(TIntermNode *root);
|
||||
|
||||
private:
|
||||
private:
|
||||
void writeVersion(TIntermNode *root);
|
||||
void writeExtensionBehavior();
|
||||
};
|
||||
|
||||
|
@ -94,6 +94,7 @@ const char *GetOperatorString(TOperator op)
|
||||
case EOpLogicalXor: return "^^";
|
||||
case EOpLogicalAnd: return "&&";
|
||||
case EOpNegative: return "-";
|
||||
case EOpPositive: return "+";
|
||||
case EOpVectorLogicalNot: return "not";
|
||||
case EOpLogicalNot: return "!";
|
||||
case EOpPostIncrement: return "++";
|
||||
|
@ -5,6 +5,7 @@
|
||||
//
|
||||
|
||||
#include "angle_gl.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
#include "compiler/translator/VariableInfo.h"
|
||||
#include "compiler/translator/util.h"
|
||||
#include "common/utilities.h"
|
||||
@ -131,7 +132,8 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
|
||||
std::vector<sh::Uniform> *uniforms,
|
||||
std::vector<sh::Varying> *varyings,
|
||||
std::vector<sh::InterfaceBlock> *interfaceBlocks,
|
||||
ShHashFunction64 hashFunction)
|
||||
ShHashFunction64 hashFunction,
|
||||
const TSymbolTable &symbolTable)
|
||||
: mAttribs(attribs),
|
||||
mOutputVariables(outputVariables),
|
||||
mUniforms(uniforms),
|
||||
@ -140,7 +142,10 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
|
||||
mPointCoordAdded(false),
|
||||
mFrontFacingAdded(false),
|
||||
mFragCoordAdded(false),
|
||||
mHashFunction(hashFunction)
|
||||
mPositionAdded(false),
|
||||
mPointSizeAdded(false),
|
||||
mHashFunction(hashFunction),
|
||||
mSymbolTable(symbolTable)
|
||||
{
|
||||
}
|
||||
|
||||
@ -200,12 +205,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
|
||||
if (!mFragCoordAdded)
|
||||
{
|
||||
Varying info;
|
||||
info.name = "gl_FragCoord";
|
||||
info.mappedName = "gl_FragCoord";
|
||||
const char kName[] = "gl_FragCoord";
|
||||
info.name = kName;
|
||||
info.mappedName = kName;
|
||||
info.type = GL_FLOAT_VEC4;
|
||||
info.arraySize = 0;
|
||||
info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter.
|
||||
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
|
||||
info.staticUse = true;
|
||||
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
|
||||
mVaryings->push_back(info);
|
||||
mFragCoordAdded = true;
|
||||
}
|
||||
@ -214,12 +221,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
|
||||
if (!mFrontFacingAdded)
|
||||
{
|
||||
Varying info;
|
||||
info.name = "gl_FrontFacing";
|
||||
info.mappedName = "gl_FrontFacing";
|
||||
const char kName[] = "gl_FrontFacing";
|
||||
info.name = kName;
|
||||
info.mappedName = kName;
|
||||
info.type = GL_BOOL;
|
||||
info.arraySize = 0;
|
||||
info.precision = GL_NONE;
|
||||
info.staticUse = true;
|
||||
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
|
||||
mVaryings->push_back(info);
|
||||
mFrontFacingAdded = true;
|
||||
}
|
||||
@ -228,16 +237,50 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
|
||||
if (!mPointCoordAdded)
|
||||
{
|
||||
Varying info;
|
||||
info.name = "gl_PointCoord";
|
||||
info.mappedName = "gl_PointCoord";
|
||||
const char kName[] = "gl_PointCoord";
|
||||
info.name = kName;
|
||||
info.mappedName = kName;
|
||||
info.type = GL_FLOAT_VEC2;
|
||||
info.arraySize = 0;
|
||||
info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter.
|
||||
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
|
||||
info.staticUse = true;
|
||||
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
|
||||
mVaryings->push_back(info);
|
||||
mPointCoordAdded = true;
|
||||
}
|
||||
return;
|
||||
case EvqPosition:
|
||||
if (!mPositionAdded)
|
||||
{
|
||||
Varying info;
|
||||
const char kName[] = "gl_Position";
|
||||
info.name = kName;
|
||||
info.mappedName = kName;
|
||||
info.type = GL_FLOAT_VEC4;
|
||||
info.arraySize = 0;
|
||||
info.precision = GL_HIGH_FLOAT; // Defined by spec.
|
||||
info.staticUse = true;
|
||||
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
|
||||
mVaryings->push_back(info);
|
||||
mPositionAdded = true;
|
||||
}
|
||||
return;
|
||||
case EvqPointSize:
|
||||
if (!mPointSizeAdded)
|
||||
{
|
||||
Varying info;
|
||||
const char kName[] = "gl_PointSize";
|
||||
info.name = kName;
|
||||
info.mappedName = kName;
|
||||
info.type = GL_FLOAT;
|
||||
info.arraySize = 0;
|
||||
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
|
||||
info.staticUse = true;
|
||||
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
|
||||
mVaryings->push_back(info);
|
||||
mPointSizeAdded = true;
|
||||
}
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -251,8 +294,10 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
|
||||
class NameHashingTraverser : public GetVariableTraverser
|
||||
{
|
||||
public:
|
||||
NameHashingTraverser(ShHashFunction64 hashFunction)
|
||||
: mHashFunction(hashFunction)
|
||||
NameHashingTraverser(ShHashFunction64 hashFunction,
|
||||
const TSymbolTable &symbolTable)
|
||||
: GetVariableTraverser(symbolTable),
|
||||
mHashFunction(hashFunction)
|
||||
{}
|
||||
|
||||
private:
|
||||
@ -312,7 +357,7 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable,
|
||||
const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
|
||||
const TType &fieldType = *field.type();
|
||||
|
||||
GetVariableTraverser traverser;
|
||||
GetVariableTraverser traverser(mSymbolTable);
|
||||
traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
|
||||
|
||||
interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
|
||||
@ -325,7 +370,7 @@ template <typename VarT>
|
||||
void CollectVariables::visitVariable(const TIntermSymbol *variable,
|
||||
std::vector<VarT> *infoList) const
|
||||
{
|
||||
NameHashingTraverser traverser(mHashFunction);
|
||||
NameHashingTraverser traverser(mHashFunction, mSymbolTable);
|
||||
traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
|
||||
}
|
||||
|
||||
@ -421,9 +466,8 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename VarT>
|
||||
void ExpandVariables(const std::vector<VarT> &compact,
|
||||
std::vector<ShaderVariable> *expanded)
|
||||
void ExpandUniforms(const std::vector<Uniform> &compact,
|
||||
std::vector<ShaderVariable> *expanded)
|
||||
{
|
||||
for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
|
||||
{
|
||||
@ -432,7 +476,4 @@ void ExpandVariables(const std::vector<VarT> &compact,
|
||||
}
|
||||
}
|
||||
|
||||
template void ExpandVariables(const std::vector<Uniform> &, std::vector<ShaderVariable> *);
|
||||
template void ExpandVariables(const std::vector<Varying> &, std::vector<ShaderVariable> *);
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
class TSymbolTable;
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
@ -23,7 +25,8 @@ class CollectVariables : public TIntermTraverser
|
||||
std::vector<Uniform> *uniforms,
|
||||
std::vector<Varying> *varyings,
|
||||
std::vector<InterfaceBlock> *interfaceBlocks,
|
||||
ShHashFunction64 hashFunction);
|
||||
ShHashFunction64 hashFunction,
|
||||
const TSymbolTable &symbolTable);
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol *symbol);
|
||||
virtual bool visitAggregate(Visit, TIntermAggregate *node);
|
||||
@ -48,13 +51,17 @@ class CollectVariables : public TIntermTraverser
|
||||
bool mFrontFacingAdded;
|
||||
bool mFragCoordAdded;
|
||||
|
||||
bool mPositionAdded;
|
||||
bool mPointSizeAdded;
|
||||
|
||||
ShHashFunction64 mHashFunction;
|
||||
|
||||
const TSymbolTable &mSymbolTable;
|
||||
};
|
||||
|
||||
// Expand struct variables to flattened lists of split variables
|
||||
template <typename VarT>
|
||||
void ExpandVariables(const std::vector<VarT> &compact,
|
||||
std::vector<ShaderVariable> *expanded);
|
||||
// Expand struct uniforms to flattened lists of split variables
|
||||
void ExpandUniforms(const std::vector<Uniform> &compact,
|
||||
std::vector<ShaderVariable> *expanded);
|
||||
|
||||
}
|
||||
|
||||
|
@ -26,18 +26,12 @@ static const int GLSL_VERSION_120 = 120;
|
||||
// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
|
||||
// are built-in types, entire structures or arrays... are all l-values."
|
||||
//
|
||||
// TODO(alokp): The following two cases of invariant decalaration get lost
|
||||
// during parsing - they do not get carried over to the intermediate tree.
|
||||
// Handle these cases:
|
||||
// 1. When a pragma is used to force all output variables to be invariant:
|
||||
// - #pragma STDGL invariant(all)
|
||||
// 2. When a previously decalared or built-in variable is marked invariant:
|
||||
// - invariant gl_Position;
|
||||
// - varying vec3 color; invariant color;
|
||||
//
|
||||
TVersionGLSL::TVersionGLSL(sh::GLenum type)
|
||||
: mVersion(GLSL_VERSION_110)
|
||||
TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma)
|
||||
{
|
||||
if (pragma.stdgl.invariantAll)
|
||||
mVersion = GLSL_VERSION_120;
|
||||
else
|
||||
mVersion = GLSL_VERSION_110;
|
||||
}
|
||||
|
||||
void TVersionGLSL::visitSymbol(TIntermSymbol *node)
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
#include "compiler/translator/Pragma.h"
|
||||
|
||||
// Traverses the intermediate tree to return the minimum GLSL version
|
||||
// required to legally access all built-in features used in the shader.
|
||||
// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
|
||||
@ -27,7 +29,7 @@
|
||||
class TVersionGLSL : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
TVersionGLSL(sh::GLenum type);
|
||||
TVersionGLSL(sh::GLenum type, const TPragma &pragma);
|
||||
|
||||
// Returns 120 if the following is used the shader:
|
||||
// - "invariant",
|
||||
|
@ -354,6 +354,15 @@ function_call
|
||||
// Treat it like a built-in unary operator.
|
||||
//
|
||||
$$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1);
|
||||
const TType& returnType = fnCandidate->getReturnType();
|
||||
if (returnType.getBasicType() == EbtBool) {
|
||||
// Bool types should not have precision, so we'll override any precision
|
||||
// that might have been set by addUnaryMath.
|
||||
$$->setType(returnType);
|
||||
} else {
|
||||
// addUnaryMath has set the precision of the node based on the operand.
|
||||
$$->setTypePreservePrecision(returnType);
|
||||
}
|
||||
if ($$ == 0) {
|
||||
std::stringstream extraInfoStream;
|
||||
extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
|
||||
@ -362,20 +371,29 @@ function_call
|
||||
YYERROR;
|
||||
}
|
||||
} else {
|
||||
$$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
|
||||
TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
|
||||
aggregate->setType(fnCandidate->getReturnType());
|
||||
aggregate->setPrecisionFromChildren();
|
||||
$$ = aggregate;
|
||||
}
|
||||
} else {
|
||||
// This is a real function call
|
||||
|
||||
$$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
|
||||
$$->setType(fnCandidate->getReturnType());
|
||||
TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
|
||||
aggregate->setType(fnCandidate->getReturnType());
|
||||
|
||||
// this is how we know whether the given function is a builtIn function or a user defined function
|
||||
// if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
|
||||
// if builtIn == true, it's definitely a builtIn function with EOpNull
|
||||
if (!builtIn)
|
||||
$$->getAsAggregate()->setUserDefined();
|
||||
$$->getAsAggregate()->setName(fnCandidate->getMangledName());
|
||||
aggregate->setUserDefined();
|
||||
aggregate->setName(fnCandidate->getMangledName());
|
||||
|
||||
// This needs to happen after the name is set
|
||||
if (builtIn)
|
||||
aggregate->setBuiltInFunctionPrecision();
|
||||
|
||||
$$ = aggregate;
|
||||
|
||||
TQualifier qual;
|
||||
for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
|
||||
@ -388,7 +406,6 @@ function_call
|
||||
}
|
||||
}
|
||||
}
|
||||
$$->setType(fnCandidate->getReturnType());
|
||||
} else {
|
||||
// error message was put out by PaFindFunction()
|
||||
// Put on a dummy node for error recovery
|
||||
@ -500,6 +517,7 @@ unary_expression
|
||||
const char* errorOp = "";
|
||||
switch($1.op) {
|
||||
case EOpNegative: errorOp = "-"; break;
|
||||
case EOpPositive: errorOp = "+"; break;
|
||||
case EOpLogicalNot: errorOp = "!"; break;
|
||||
default: break;
|
||||
}
|
||||
@ -514,7 +532,7 @@ unary_expression
|
||||
// Grammar Note: No traditional style type casts.
|
||||
|
||||
unary_operator
|
||||
: PLUS { $$.op = EOpNull; }
|
||||
: PLUS { $$.op = EOpPositive; }
|
||||
| DASH { $$.op = EOpNegative; }
|
||||
| BANG { $$.op = EOpLogicalNot; }
|
||||
;
|
||||
@ -762,7 +780,7 @@ declaration
|
||||
|
||||
TIntermAggregate *prototype = new TIntermAggregate;
|
||||
prototype->setType(function.getReturnType());
|
||||
prototype->setName(function.getName());
|
||||
prototype->setName(function.getMangledName());
|
||||
|
||||
for (size_t i = 0; i < function.getParamCount(); i++)
|
||||
{
|
||||
|
@ -62,7 +62,9 @@ TString TType::getCompleteString() const
|
||||
TStringStream stream;
|
||||
|
||||
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
|
||||
stream << getQualifierString() << " " << getPrecisionString() << " ";
|
||||
stream << getQualifierString() << " ";
|
||||
if (precision != EbpUndefined)
|
||||
stream << getPrecisionString() << " ";
|
||||
if (array)
|
||||
stream << "array[" << getArraySize() << "] of ";
|
||||
if (isMatrix())
|
||||
@ -221,6 +223,7 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpNegative: out << "Negate value"; break;
|
||||
case EOpPositive: out << "Positive sign"; break;
|
||||
case EOpVectorLogicalNot:
|
||||
case EOpLogicalNot: out << "Negate conditional"; break;
|
||||
|
||||
@ -292,6 +295,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
case EOpFunction: out << "Function Definition: " << node->getName(); break;
|
||||
case EOpFunctionCall: out << "Function Call: " << node->getName(); break;
|
||||
case EOpParameters: out << "Function Parameters: "; break;
|
||||
case EOpPrototype: out << "Function Prototype: " << node->getName(); break;
|
||||
|
||||
case EOpConstructFloat: out << "Construct float"; break;
|
||||
case EOpConstructVec2: out << "Construct vec2"; break;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <limits>
|
||||
|
||||
#include "compiler/preprocessor/numeric_lex.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
#include "common/utilities.h"
|
||||
|
||||
bool atof_clamp(const char *str, float *value)
|
||||
@ -281,8 +282,47 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
|
||||
}
|
||||
}
|
||||
|
||||
GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
|
||||
: mSymbolTable(symbolTable)
|
||||
{
|
||||
}
|
||||
|
||||
template void GetVariableTraverser::setTypeSpecificInfo(
|
||||
const TType &type, const TString& name, InterfaceBlockField *variable);
|
||||
template void GetVariableTraverser::setTypeSpecificInfo(
|
||||
const TType &type, const TString& name, ShaderVariable *variable);
|
||||
template void GetVariableTraverser::setTypeSpecificInfo(
|
||||
const TType &type, const TString& name, Uniform *variable);
|
||||
|
||||
template<>
|
||||
void GetVariableTraverser::setTypeSpecificInfo(
|
||||
const TType &type, const TString& name, Varying *variable)
|
||||
{
|
||||
ASSERT(variable);
|
||||
switch (type.getQualifier())
|
||||
{
|
||||
case EvqInvariantVaryingIn:
|
||||
case EvqInvariantVaryingOut:
|
||||
variable->isInvariant = true;
|
||||
break;
|
||||
case EvqVaryingIn:
|
||||
case EvqVaryingOut:
|
||||
if (mSymbolTable.isVaryingInvariant(name))
|
||||
{
|
||||
variable->isInvariant = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
variable->interpolation = GetInterpolationType(type.getQualifier());
|
||||
}
|
||||
|
||||
template <typename VarT>
|
||||
void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
|
||||
void GetVariableTraverser::traverse(const TType &type,
|
||||
const TString &name,
|
||||
std::vector<VarT> *output)
|
||||
{
|
||||
const TStructure *structure = type.getStruct();
|
||||
|
||||
@ -309,15 +349,16 @@ void GetVariableTraverser::traverse(const TType &type, const TString &name, std:
|
||||
traverse(*field->type(), field->name(), &variable.fields);
|
||||
}
|
||||
}
|
||||
|
||||
setTypeSpecificInfo(type, name, &variable);
|
||||
visitVariable(&variable);
|
||||
|
||||
ASSERT(output);
|
||||
output->push_back(variable);
|
||||
}
|
||||
|
||||
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
|
||||
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<ShaderVariable> *);
|
||||
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> *);
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ extern bool atof_clamp(const char *str, float *value);
|
||||
// Return false if overflow happens.
|
||||
extern bool atoi_clamp(const char *str, int *value);
|
||||
|
||||
class TSymbolTable;
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
@ -38,7 +40,7 @@ TString ArrayString(const TType &type);
|
||||
class GetVariableTraverser
|
||||
{
|
||||
public:
|
||||
GetVariableTraverser() {}
|
||||
GetVariableTraverser(const TSymbolTable &symbolTable);
|
||||
|
||||
template <typename VarT>
|
||||
void traverse(const TType &type, const TString &name, std::vector<VarT> *output);
|
||||
@ -48,6 +50,14 @@ class GetVariableTraverser
|
||||
virtual void visitVariable(ShaderVariable *newVar) {}
|
||||
|
||||
private:
|
||||
// Helper function called by traverse() to fill specific fields
|
||||
// for attributes/varyings/uniforms.
|
||||
template <typename VarT>
|
||||
void setTypeSpecificInfo(
|
||||
const TType &type, const TString &name, VarT *variable) {}
|
||||
|
||||
const TSymbolTable &mSymbolTable;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
|
||||
};
|
||||
|
||||
|
40
src/3rdparty/angle/src/libEGL/AttributeMap.cpp
vendored
Normal file
40
src/3rdparty/angle/src/libEGL/AttributeMap.cpp
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// 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 "libEGL/AttributeMap.h"
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
||||
AttributeMap::AttributeMap()
|
||||
{
|
||||
}
|
||||
|
||||
AttributeMap::AttributeMap(const EGLint *attributes)
|
||||
{
|
||||
for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2)
|
||||
{
|
||||
insert(curAttrib[0], curAttrib[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void AttributeMap::insert(EGLint key, EGLint value)
|
||||
{
|
||||
mAttributes[key] = value;
|
||||
}
|
||||
|
||||
bool AttributeMap::contains(EGLint key) const
|
||||
{
|
||||
return (mAttributes.find(key) != mAttributes.end());
|
||||
}
|
||||
|
||||
EGLint AttributeMap::get(EGLint key, EGLint defaultValue) const
|
||||
{
|
||||
std::map<EGLint, EGLint>::const_iterator iter = mAttributes.find(key);
|
||||
return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue;
|
||||
}
|
||||
|
||||
}
|
33
src/3rdparty/angle/src/libEGL/AttributeMap.h
vendored
Normal file
33
src/3rdparty/angle/src/libEGL/AttributeMap.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef LIBEGL_ATTRIBUTEMAP_H_
|
||||
#define LIBEGL_ATTRIBUTEMAP_H_
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
||||
class AttributeMap
|
||||
{
|
||||
public:
|
||||
AttributeMap();
|
||||
explicit AttributeMap(const EGLint *attributes);
|
||||
|
||||
virtual void insert(EGLint key, EGLint value);
|
||||
virtual bool contains(EGLint key) const;
|
||||
virtual EGLint get(EGLint key, EGLint defaultValue) const;
|
||||
|
||||
private:
|
||||
std::map<EGLint, EGLint> mAttributes;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBEGL_ATTRIBUTEMAP_H_
|
169
src/3rdparty/angle/src/libEGL/Display.cpp
vendored
169
src/3rdparty/angle/src/libEGL/Display.cpp
vendored
@ -35,32 +35,36 @@ static DisplayMap *GetDisplayMap()
|
||||
return &displays;
|
||||
}
|
||||
|
||||
egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, EGLint displayType)
|
||||
egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap)
|
||||
{
|
||||
Display *display = NULL;
|
||||
|
||||
DisplayMap *displays = GetDisplayMap();
|
||||
DisplayMap::const_iterator iter = displays->find(displayId);
|
||||
if (iter != displays->end())
|
||||
{
|
||||
return iter->second;
|
||||
display = iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
display = new egl::Display(displayId);
|
||||
displays->insert(std::make_pair(displayId, display));
|
||||
}
|
||||
|
||||
// FIXME: Check if displayId is a valid display device context
|
||||
|
||||
egl::Display *display = new egl::Display(displayId, displayType);
|
||||
displays->insert(std::make_pair(displayId, display));
|
||||
// Apply new attributes if the display is not initialized yet.
|
||||
if (!display->isInitialized())
|
||||
{
|
||||
display->setAttributes(attribMap);
|
||||
}
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
Display::Display(EGLNativeDisplayType displayId, EGLint displayType)
|
||||
Display::Display(EGLNativeDisplayType displayId)
|
||||
: mDisplayId(displayId),
|
||||
mRequestedDisplayType(displayType),
|
||||
mAttributeMap(),
|
||||
mRenderer(NULL)
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (mDisplayId)
|
||||
mDisplayId->AddRef();
|
||||
#endif
|
||||
}
|
||||
|
||||
Display::~Display()
|
||||
@ -73,28 +77,29 @@ Display::~Display()
|
||||
{
|
||||
displays->erase(iter);
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (mDisplayId)
|
||||
mDisplayId->Release();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Display::initialize()
|
||||
void Display::setAttributes(const AttributeMap &attribMap)
|
||||
{
|
||||
mAttributeMap = attribMap;
|
||||
}
|
||||
|
||||
Error Display::initialize()
|
||||
{
|
||||
if (isInitialized())
|
||||
{
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
mRenderer = glCreateRenderer(this, mDisplayId, mRequestedDisplayType);
|
||||
mRenderer = glCreateRenderer(this, mDisplayId, mAttributeMap);
|
||||
|
||||
if (!mRenderer)
|
||||
{
|
||||
terminate();
|
||||
return error(EGL_NOT_INITIALIZED, false);
|
||||
return Error(EGL_NOT_INITIALIZED);
|
||||
}
|
||||
|
||||
//TODO(jmadill): should be part of caps?
|
||||
EGLint minSwapInterval = mRenderer->getMinSwapInterval();
|
||||
EGLint maxSwapInterval = mRenderer->getMaxSwapInterval();
|
||||
EGLint maxTextureSize = mRenderer->getRendererCaps().max2DTextureSize;
|
||||
@ -125,13 +130,13 @@ bool Display::initialize()
|
||||
if (!isInitialized())
|
||||
{
|
||||
terminate();
|
||||
return false;
|
||||
return Error(EGL_NOT_INITIALIZED);
|
||||
}
|
||||
|
||||
initDisplayExtensionString();
|
||||
initVendorString();
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
void Display::terminate()
|
||||
@ -148,6 +153,8 @@ void Display::terminate()
|
||||
|
||||
glDestroyRenderer(mRenderer);
|
||||
mRenderer = NULL;
|
||||
|
||||
mConfigSet.mSet.clear();
|
||||
}
|
||||
|
||||
bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
|
||||
@ -202,7 +209,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
|
||||
|
||||
|
||||
|
||||
EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
|
||||
Error Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface)
|
||||
{
|
||||
const Config *configuration = mConfigSet.get(config);
|
||||
EGLint postSubBufferSupported = EGL_FALSE;
|
||||
@ -223,9 +230,9 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
|
||||
case EGL_BACK_BUFFER:
|
||||
break;
|
||||
case EGL_SINGLE_BUFFER:
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported
|
||||
return Error(EGL_BAD_MATCH); // Rendering directly to front buffer not supported
|
||||
default:
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
break;
|
||||
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
|
||||
@ -241,11 +248,11 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
|
||||
fixedSize = attribList[1];
|
||||
break;
|
||||
case EGL_VG_COLORSPACE:
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
case EGL_VG_ALPHA_FORMAT:
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
default:
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
|
||||
attribList += 2;
|
||||
@ -254,7 +261,7 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
|
||||
|
||||
if (width < 0 || height < 0)
|
||||
{
|
||||
return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
if (!fixedSize)
|
||||
@ -265,29 +272,33 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
|
||||
|
||||
if (hasExistingWindowSurface(window))
|
||||
{
|
||||
return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ALLOC);
|
||||
}
|
||||
|
||||
if (mRenderer->testDeviceLost(false))
|
||||
{
|
||||
if (!restoreLostDevice())
|
||||
return EGL_NO_SURFACE;
|
||||
Error error = restoreLostDevice();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
Surface *surface = new Surface(this, configuration, window, fixedSize, width, height, postSubBufferSupported);
|
||||
|
||||
if (!surface->initialize())
|
||||
Error error = surface->initialize();
|
||||
if (error.isError())
|
||||
{
|
||||
delete surface;
|
||||
return EGL_NO_SURFACE;
|
||||
SafeDelete(surface);
|
||||
return error;
|
||||
}
|
||||
|
||||
mSurfaceSet.insert(surface);
|
||||
|
||||
return success(surface);
|
||||
*outSurface = surface;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList)
|
||||
Error Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface)
|
||||
{
|
||||
EGLint width = 0, height = 0;
|
||||
EGLenum textureFormat = EGL_NO_TEXTURE;
|
||||
@ -319,7 +330,7 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
|
||||
textureFormat = attribList[1];
|
||||
break;
|
||||
default:
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
break;
|
||||
case EGL_TEXTURE_TARGET:
|
||||
@ -330,19 +341,19 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
|
||||
textureTarget = attribList[1];
|
||||
break;
|
||||
default:
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
break;
|
||||
case EGL_MIPMAP_TEXTURE:
|
||||
if (attribList[1] != EGL_FALSE)
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
break;
|
||||
case EGL_VG_COLORSPACE:
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
case EGL_VG_ALPHA_FORMAT:
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
default:
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
|
||||
attribList += 2;
|
||||
@ -351,86 +362,98 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
|
||||
|
||||
if (width < 0 || height < 0)
|
||||
{
|
||||
return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
|
||||
if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getRendererExtensions().textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
|
||||
{
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
}
|
||||
|
||||
if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
|
||||
(textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
|
||||
{
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
}
|
||||
|
||||
if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
|
||||
{
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
}
|
||||
|
||||
if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
|
||||
(textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
|
||||
{
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
|
||||
if (mRenderer->testDeviceLost(false))
|
||||
{
|
||||
if (!restoreLostDevice())
|
||||
return EGL_NO_SURFACE;
|
||||
Error error = restoreLostDevice();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget);
|
||||
|
||||
if (!surface->initialize())
|
||||
Error error = surface->initialize();
|
||||
if (error.isError())
|
||||
{
|
||||
delete surface;
|
||||
return EGL_NO_SURFACE;
|
||||
SafeDelete(surface);
|
||||
return error;
|
||||
}
|
||||
|
||||
mSurfaceSet.insert(surface);
|
||||
|
||||
return success(surface);
|
||||
*outSurface = surface;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
EGLContext Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
|
||||
Error Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
|
||||
bool robustAccess, EGLContext *outContext)
|
||||
{
|
||||
if (!mRenderer)
|
||||
{
|
||||
return EGL_NO_CONTEXT;
|
||||
*outContext = EGL_NO_CONTEXT;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
else if (mRenderer->testDeviceLost(false)) // Lost device
|
||||
{
|
||||
if (!restoreLostDevice())
|
||||
Error error = restoreLostDevice();
|
||||
if (error.isError())
|
||||
{
|
||||
return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO(jmadill): shader model is not cross-platform
|
||||
if (clientVersion > 2 && mRenderer->getMajorShaderModel() < 4)
|
||||
{
|
||||
return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
|
||||
return Error(EGL_BAD_CONFIG);
|
||||
}
|
||||
|
||||
gl::Context *context = glCreateContext(clientVersion, shareContext, mRenderer, notifyResets, robustAccess);
|
||||
mContextSet.insert(context);
|
||||
|
||||
return success(context);
|
||||
*outContext = context;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
bool Display::restoreLostDevice()
|
||||
Error Display::restoreLostDevice()
|
||||
{
|
||||
for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++)
|
||||
{
|
||||
if ((*ctx)->isResetNotificationEnabled())
|
||||
return false; // If reset notifications have been requested, application must delete all contexts first
|
||||
{
|
||||
// If reset notifications have been requested, application must delete all contexts first
|
||||
return Error(EGL_CONTEXT_LOST);
|
||||
}
|
||||
}
|
||||
|
||||
// Release surface resources to make the Reset() succeed
|
||||
@ -441,16 +464,20 @@ bool Display::restoreLostDevice()
|
||||
|
||||
if (!mRenderer->resetDevice())
|
||||
{
|
||||
return error(EGL_BAD_ALLOC, false);
|
||||
return Error(EGL_BAD_ALLOC);
|
||||
}
|
||||
|
||||
// Restore any surfaces that may have been lost
|
||||
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
|
||||
{
|
||||
(*surface)->resetSwapChain();
|
||||
Error error = (*surface)->resetSwapChain();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@ -472,7 +499,6 @@ void Display::notifyDeviceLost()
|
||||
{
|
||||
(*context)->markContextLost();
|
||||
}
|
||||
egl::error(EGL_CONTEXT_LOST);
|
||||
}
|
||||
|
||||
void Display::recreateSwapChains()
|
||||
@ -604,10 +630,11 @@ void Display::initVendorString()
|
||||
|
||||
LUID adapterLuid = {0};
|
||||
|
||||
//TODO(jmadill): LUID is not cross-platform
|
||||
if (mRenderer && mRenderer->getLUID(&adapterLuid))
|
||||
{
|
||||
char adapterLuidString[64];
|
||||
snprintf(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
|
||||
sprintf_s(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
|
||||
|
||||
mVendorString += adapterLuidString;
|
||||
}
|
||||
|
22
src/3rdparty/angle/src/libEGL/Display.h
vendored
22
src/3rdparty/angle/src/libEGL/Display.h
vendored
@ -14,7 +14,9 @@
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "libEGL/Error.h"
|
||||
#include "libEGL/Config.h"
|
||||
#include "libEGL/AttributeMap.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -30,10 +32,10 @@ class Display
|
||||
public:
|
||||
~Display();
|
||||
|
||||
bool initialize();
|
||||
Error initialize();
|
||||
void terminate();
|
||||
|
||||
static egl::Display *getDisplay(EGLNativeDisplayType displayId, EGLint displayType);
|
||||
static egl::Display *getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap);
|
||||
|
||||
static const char *getExtensionString(egl::Display *display);
|
||||
|
||||
@ -43,9 +45,10 @@ class Display
|
||||
bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
|
||||
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
|
||||
|
||||
EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
|
||||
EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
|
||||
EGLContext createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
|
||||
Error createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface);
|
||||
Error createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface);
|
||||
Error createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
|
||||
bool robustAccess, EGLContext *outContext);
|
||||
|
||||
void destroySurface(egl::Surface *surface);
|
||||
void destroyContext(gl::Context *context);
|
||||
@ -64,18 +67,19 @@ class Display
|
||||
|
||||
const char *getExtensionString() const;
|
||||
const char *getVendorString() const;
|
||||
|
||||
EGLNativeDisplayType getDisplayId() const { return mDisplayId; }
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Display);
|
||||
|
||||
Display(EGLNativeDisplayType displayId, EGLint displayType);
|
||||
Display(EGLNativeDisplayType displayId);
|
||||
|
||||
bool restoreLostDevice();
|
||||
void setAttributes(const AttributeMap &attribMap);
|
||||
|
||||
Error restoreLostDevice();
|
||||
|
||||
EGLNativeDisplayType mDisplayId;
|
||||
EGLint mRequestedDisplayType;
|
||||
AttributeMap mAttributeMap;
|
||||
|
||||
typedef std::set<Surface*> SurfaceSet;
|
||||
SurfaceSet mSurfaceSet;
|
||||
|
48
src/3rdparty/angle/src/libEGL/Error.cpp
vendored
Normal file
48
src/3rdparty/angle/src/libEGL/Error.cpp
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Error.cpp: Implements the egl::Error class which encapsulates an EGL error
|
||||
// and optional error message.
|
||||
|
||||
#include "libEGL/Error.h"
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
||||
Error::Error(EGLint errorCode)
|
||||
: mCode(errorCode),
|
||||
mMessage()
|
||||
{
|
||||
}
|
||||
|
||||
Error::Error(EGLint 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;
|
||||
}
|
||||
|
||||
}
|
39
src/3rdparty/angle/src/libEGL/Error.h
vendored
Normal file
39
src/3rdparty/angle/src/libEGL/Error.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Error.h: Defines the egl::Error class which encapsulates an EGL error
|
||||
// and optional error message.
|
||||
|
||||
#ifndef LIBEGL_ERROR_H_
|
||||
#define LIBEGL_ERROR_H_
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
||||
class Error
|
||||
{
|
||||
public:
|
||||
explicit Error(EGLint errorCode);
|
||||
Error(EGLint errorCode, const char *msg, ...);
|
||||
Error(const Error &other);
|
||||
Error &operator=(const Error &other);
|
||||
|
||||
EGLint getCode() const { return mCode; }
|
||||
bool isError() const { return (mCode != EGL_SUCCESS); }
|
||||
|
||||
const std::string &getMessage() const { return mMessage; }
|
||||
|
||||
private:
|
||||
EGLint mCode;
|
||||
std::string mMessage;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBEGL_ERROR_H_
|
339
src/3rdparty/angle/src/libEGL/Surface.cpp
vendored
339
src/3rdparty/angle/src/libEGL/Surface.cpp
vendored
@ -22,23 +22,19 @@
|
||||
#include "libEGL/main.h"
|
||||
#include "libEGL/Display.h"
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
# include "wrl.h"
|
||||
# include "windows.graphics.display.h"
|
||||
# include "windows.ui.core.h"
|
||||
using namespace ABI::Windows::Graphics::Display;
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace ABI::Windows::UI::Core;
|
||||
using namespace Microsoft::WRL;
|
||||
#endif
|
||||
#include "common/NativeWindow.h"
|
||||
|
||||
//TODO(jmadill): phase this out
|
||||
#include "libGLESv2/renderer/d3d/RendererD3D.h"
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
||||
Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
|
||||
: mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
|
||||
: mDisplay(display), mConfig(config), mNativeWindow(window, display->getDisplayId()), mPostSubBufferSupported(postSubBufferSupported)
|
||||
{
|
||||
mRenderer = mDisplay->getRenderer();
|
||||
//TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
|
||||
mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
|
||||
mSwapChain = NULL;
|
||||
mShareHandle = NULL;
|
||||
mTexture = NULL;
|
||||
@ -51,27 +47,19 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win
|
||||
mSwapInterval = -1;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mFixedWidth = mWidth;
|
||||
mFixedHeight = mHeight;
|
||||
setSwapInterval(1);
|
||||
mFixedSize = fixedSize;
|
||||
mSwapFlags = rx::SWAP_NORMAL;
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (mWindow)
|
||||
mWindow->AddRef();
|
||||
mScaleFactor = 1.0;
|
||||
mSizeToken.value = 0;
|
||||
mDpiToken.value = 0;
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
mOrientationToken.value = 0;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
subclassWindow();
|
||||
}
|
||||
|
||||
Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
|
||||
: mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
|
||||
: mDisplay(display), mNativeWindow(NULL, NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
|
||||
{
|
||||
mRenderer = mDisplay->getRenderer();
|
||||
//TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
|
||||
mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
|
||||
mSwapChain = NULL;
|
||||
mWindowSubclassed = false;
|
||||
mTexture = NULL;
|
||||
@ -85,90 +73,33 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL
|
||||
setSwapInterval(1);
|
||||
// This constructor is for offscreen surfaces, which are always fixed-size.
|
||||
mFixedSize = EGL_TRUE;
|
||||
mSwapFlags = rx::SWAP_NORMAL;
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
mScaleFactor = 1.0;
|
||||
mSizeToken.value = 0;
|
||||
mDpiToken.value = 0;
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
mOrientationToken.value = 0;
|
||||
# endif
|
||||
#endif
|
||||
mFixedWidth = mWidth;
|
||||
mFixedHeight = mHeight;
|
||||
}
|
||||
|
||||
Surface::~Surface()
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (mSizeToken.value) {
|
||||
ComPtr<ICoreWindow> coreWindow;
|
||||
HRESULT hr = mWindow->QueryInterface(coreWindow.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = coreWindow->remove_SizeChanged(mSizeToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
if (mDpiToken.value) {
|
||||
ComPtr<IDisplayInformation> displayInformation;
|
||||
HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = displayInformation->remove_DpiChanged(mDpiToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
if (mOrientationToken.value) {
|
||||
ComPtr<IDisplayInformation> displayInformation;
|
||||
HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = displayInformation->remove_OrientationChanged(mOrientationToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
unsubclassWindow();
|
||||
release();
|
||||
}
|
||||
|
||||
bool Surface::initialize()
|
||||
Error Surface::initialize()
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!mFixedSize) {
|
||||
HRESULT hr;
|
||||
ComPtr<IDisplayInformation> displayInformation;
|
||||
hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
onDpiChanged(displayInformation.Get(), 0);
|
||||
hr = displayInformation->add_DpiChanged(Callback<ITypedEventHandler<DisplayInformation *, IInspectable *>>(this, &Surface::onDpiChanged).Get(),
|
||||
&mDpiToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
onOrientationChanged(displayInformation.Get(), 0);
|
||||
hr = displayInformation->add_OrientationChanged(Callback<ITypedEventHandler<DisplayInformation *, IInspectable *>>(this, &Surface::onOrientationChanged).Get(),
|
||||
&mOrientationToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
# endif
|
||||
|
||||
ComPtr<ICoreWindow> coreWindow;
|
||||
hr = mWindow->QueryInterface(coreWindow.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
Rect rect;
|
||||
hr = coreWindow->get_Bounds(&rect);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
mWidth = rect.Width * mScaleFactor;
|
||||
mHeight = rect.Height * mScaleFactor;
|
||||
hr = coreWindow->add_SizeChanged(Callback<ITypedEventHandler<CoreWindow *, WindowSizeChangedEventArgs *>>(this, &Surface::onSizeChanged).Get(),
|
||||
&mSizeToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
if (mNativeWindow.getNativeWindow())
|
||||
{
|
||||
if (!mNativeWindow.initialize())
|
||||
{
|
||||
return Error(EGL_BAD_SURFACE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!resetSwapChain())
|
||||
return false;
|
||||
Error error = resetSwapChain();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
void Surface::release()
|
||||
@ -181,85 +112,80 @@ void Surface::release()
|
||||
mTexture->releaseTexImage();
|
||||
mTexture = NULL;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (mWindow)
|
||||
mWindow->Release();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Surface::resetSwapChain()
|
||||
Error Surface::resetSwapChain()
|
||||
{
|
||||
ASSERT(!mSwapChain);
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!mFixedSize)
|
||||
{
|
||||
RECT windowRect;
|
||||
if (!GetClientRect(getWindowHandle(), &windowRect))
|
||||
if (!mNativeWindow.getClientRect(&windowRect))
|
||||
{
|
||||
ASSERT(false);
|
||||
|
||||
ERR("Could not retrieve the window dimensions");
|
||||
return error(EGL_BAD_SURFACE, false);
|
||||
return Error(EGL_BAD_SURFACE, "Could not retrieve the window dimensions");
|
||||
}
|
||||
|
||||
width = windowRect.right - windowRect.left;
|
||||
height = windowRect.bottom - windowRect.top;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// non-window surface - size is determined at creation
|
||||
width = mWidth;
|
||||
height = mHeight;
|
||||
}
|
||||
|
||||
mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle,
|
||||
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle,
|
||||
mConfig->mRenderTargetFormat,
|
||||
mConfig->mDepthStencilFormat);
|
||||
if (!mSwapChain)
|
||||
{
|
||||
return error(EGL_BAD_ALLOC, false);
|
||||
return Error(EGL_BAD_ALLOC);
|
||||
}
|
||||
|
||||
if (!resetSwapChain(width, height))
|
||||
Error error = resetSwapChain(width, height);
|
||||
if (error.isError())
|
||||
{
|
||||
delete mSwapChain;
|
||||
mSwapChain = NULL;
|
||||
return false;
|
||||
SafeDelete(mSwapChain);
|
||||
return error;
|
||||
}
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
|
||||
Error Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
|
||||
{
|
||||
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
|
||||
ASSERT(mSwapChain);
|
||||
|
||||
EGLint status = mSwapChain->resize(std::max(1, backbufferWidth), std::max(1, backbufferHeight));
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
backbufferWidth = std::max(1, backbufferWidth);
|
||||
backbufferHeight = std::max(1, backbufferHeight);
|
||||
#endif
|
||||
EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
|
||||
|
||||
if (status == EGL_CONTEXT_LOST)
|
||||
{
|
||||
mDisplay->notifyDeviceLost();
|
||||
return false;
|
||||
return Error(status);
|
||||
}
|
||||
else if (status != EGL_SUCCESS)
|
||||
{
|
||||
return error(status, false);
|
||||
return Error(status);
|
||||
}
|
||||
|
||||
mWidth = backbufferWidth;
|
||||
mHeight = backbufferHeight;
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
|
||||
Error Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
|
||||
{
|
||||
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
|
||||
ASSERT(mSwapChain);
|
||||
@ -269,69 +195,71 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
|
||||
if (status == EGL_CONTEXT_LOST)
|
||||
{
|
||||
mRenderer->notifyDeviceLost();
|
||||
return false;
|
||||
return Error(status);
|
||||
}
|
||||
else if (status != EGL_SUCCESS)
|
||||
{
|
||||
return error(status, false);
|
||||
return Error(status);
|
||||
}
|
||||
|
||||
mWidth = backbufferWidth;
|
||||
mHeight = backbufferHeight;
|
||||
mSwapIntervalDirty = false;
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
{
|
||||
if (!mSwapChain)
|
||||
{
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
if (x + width > mWidth)
|
||||
if (x + width > abs(mWidth))
|
||||
{
|
||||
width = mWidth - x;
|
||||
width = abs(mWidth) - x;
|
||||
}
|
||||
|
||||
if (y + height > mHeight)
|
||||
if (y + height > abs(mHeight))
|
||||
{
|
||||
height = mHeight - y;
|
||||
height = abs(mHeight) - y;
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
EGLint status = mSwapChain->swapRect(x, y, width, height, mSwapFlags);
|
||||
ASSERT(width > 0);
|
||||
ASSERT(height > 0);
|
||||
|
||||
EGLint status = mSwapChain->swapRect(x, y, width, height);
|
||||
|
||||
if (status == EGL_CONTEXT_LOST)
|
||||
{
|
||||
mRenderer->notifyDeviceLost();
|
||||
return false;
|
||||
return Error(status);
|
||||
}
|
||||
else if (status != EGL_SUCCESS)
|
||||
{
|
||||
return error(status, false);
|
||||
return Error(status);
|
||||
}
|
||||
|
||||
checkForOutOfDateSwapChain();
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
EGLNativeWindowType Surface::getWindowHandle()
|
||||
{
|
||||
return mWindow;
|
||||
return mNativeWindow.getNativeWindow();
|
||||
}
|
||||
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
|
||||
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
|
||||
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (message == WM_SIZE)
|
||||
@ -349,45 +277,50 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
|
||||
|
||||
void Surface::subclassWindow()
|
||||
{
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!mWindow)
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
HWND window = mNativeWindow.getNativeWindow();
|
||||
if (!window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD processId;
|
||||
DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
|
||||
DWORD threadId = GetWindowThreadProcessId(window, &processId);
|
||||
if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetLastError(0);
|
||||
LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
|
||||
LONG_PTR oldWndProc = SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
|
||||
if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
|
||||
{
|
||||
mWindowSubclassed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
|
||||
SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
|
||||
SetProp(window, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
|
||||
SetProp(window, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
|
||||
mWindowSubclassed = true;
|
||||
#else
|
||||
mWindowSubclassed = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Surface::unsubclassWindow()
|
||||
{
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
if(!mWindowSubclassed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
HWND window = mNativeWindow.getNativeWindow();
|
||||
if (!window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// un-subclass
|
||||
LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc));
|
||||
LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(window, kParentWndProc));
|
||||
|
||||
// Check the windowproc is still SurfaceWindowProc.
|
||||
// If this assert fails, then it is likely the application has subclassed the
|
||||
@ -396,29 +329,28 @@ void Surface::unsubclassWindow()
|
||||
// EGL context, or to unsubclass before destroying the EGL context.
|
||||
if(parentWndFunc)
|
||||
{
|
||||
LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
|
||||
LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc);
|
||||
UNUSED_ASSERTION_VARIABLE(prevWndFunc);
|
||||
ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
|
||||
}
|
||||
|
||||
RemoveProp(mWindow, kSurfaceProperty);
|
||||
RemoveProp(mWindow, kParentWndProc);
|
||||
mWindowSubclassed = false;
|
||||
RemoveProp(window, kSurfaceProperty);
|
||||
RemoveProp(window, kParentWndProc);
|
||||
#endif
|
||||
mWindowSubclassed = false;
|
||||
}
|
||||
|
||||
bool Surface::checkForOutOfDateSwapChain()
|
||||
{
|
||||
RECT client;
|
||||
int clientWidth = getWidth();
|
||||
int clientHeight = getHeight();
|
||||
bool sizeDirty = false;
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!mFixedSize && !IsIconic(getWindowHandle()))
|
||||
if (!mFixedSize && !mNativeWindow.isIconic())
|
||||
{
|
||||
RECT client;
|
||||
// The window is automatically resized to 150x22 when it's minimized, but the swapchain shouldn't be resized
|
||||
// because that's not a useful size to render to.
|
||||
if (!GetClientRect(getWindowHandle(), &client))
|
||||
if (!mNativeWindow.getClientRect(&client))
|
||||
{
|
||||
ASSERT(false);
|
||||
return false;
|
||||
@ -429,7 +361,13 @@ bool Surface::checkForOutOfDateSwapChain()
|
||||
clientHeight = client.bottom - client.top;
|
||||
sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mFixedSize && (mWidth != mFixedWidth || mHeight != mFixedHeight))
|
||||
{
|
||||
clientWidth = mFixedWidth;
|
||||
clientHeight = mFixedHeight;
|
||||
sizeDirty = true;
|
||||
}
|
||||
|
||||
bool wasDirty = (mSwapIntervalDirty || sizeDirty);
|
||||
|
||||
@ -455,17 +393,17 @@ bool Surface::checkForOutOfDateSwapChain()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Surface::swap()
|
||||
Error Surface::swap()
|
||||
{
|
||||
return swapRect(0, 0, mWidth, mHeight);
|
||||
return swapRect(0, 0, abs(mWidth), abs(mHeight));
|
||||
}
|
||||
|
||||
bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
{
|
||||
if (!mPostSubBufferSupported)
|
||||
{
|
||||
// Spec is not clear about how this should be handled.
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
return swapRect(x, y, width, height);
|
||||
@ -550,77 +488,18 @@ EGLint Surface::isFixedSize() const
|
||||
return mFixedSize;
|
||||
}
|
||||
|
||||
void Surface::setFixedWidth(EGLint width)
|
||||
{
|
||||
mFixedWidth = width;
|
||||
}
|
||||
|
||||
void Surface::setFixedHeight(EGLint height)
|
||||
{
|
||||
mFixedHeight = height;
|
||||
}
|
||||
|
||||
EGLenum Surface::getFormat() const
|
||||
{
|
||||
return mConfig->mRenderTargetFormat;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
|
||||
HRESULT Surface::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args)
|
||||
{
|
||||
HRESULT hr;
|
||||
Size size;
|
||||
hr = args->get_Size(&size);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
resizeSwapChain(std::floor(size.Width * mScaleFactor + 0.5),
|
||||
std::floor(size.Height * mScaleFactor + 0.5));
|
||||
|
||||
if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
|
||||
{
|
||||
glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Surface::onDpiChanged(IDisplayInformation *displayInformation, IInspectable *)
|
||||
{
|
||||
HRESULT hr;
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
ComPtr<IDisplayInformation2> displayInformation2;
|
||||
hr = displayInformation->QueryInterface(displayInformation2.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
# else
|
||||
ResolutionScale resolutionScale;
|
||||
hr = displayInformation->get_ResolutionScale(&resolutionScale);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
mScaleFactor = double(resolutionScale) / 100.0;
|
||||
# endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
HRESULT Surface::onOrientationChanged(IDisplayInformation *displayInformation, IInspectable *)
|
||||
{
|
||||
HRESULT hr;
|
||||
DisplayOrientations orientation;
|
||||
hr = displayInformation->get_CurrentOrientation(&orientation);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
switch (orientation) {
|
||||
default:
|
||||
case DisplayOrientations_Portrait:
|
||||
mSwapFlags = rx::SWAP_NORMAL;
|
||||
break;
|
||||
case DisplayOrientations_Landscape:
|
||||
mSwapFlags = rx::SWAP_ROTATE_90;
|
||||
break;
|
||||
case DisplayOrientations_LandscapeFlipped:
|
||||
mSwapFlags = rx::SWAP_ROTATE_270;
|
||||
break;
|
||||
case DisplayOrientations_PortraitFlipped:
|
||||
mSwapFlags = rx::SWAP_ROTATE_180;
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
60
src/3rdparty/angle/src/libEGL/Surface.h
vendored
60
src/3rdparty/angle/src/libEGL/Surface.h
vendored
@ -11,23 +11,12 @@
|
||||
#ifndef LIBEGL_SURFACE_H_
|
||||
#define LIBEGL_SURFACE_H_
|
||||
|
||||
#include "libEGL/Error.h"
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
#include <EventToken.h>
|
||||
namespace ABI { namespace Windows {
|
||||
namespace UI { namespace Core {
|
||||
struct ICoreWindow;
|
||||
struct IWindowSizeChangedEventArgs;
|
||||
} }
|
||||
namespace Graphics { namespace Display {
|
||||
struct IDisplayInformation;
|
||||
} }
|
||||
} }
|
||||
struct IInspectable;
|
||||
#endif
|
||||
#include "common/NativeWindow.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -35,8 +24,8 @@ class Texture2D;
|
||||
}
|
||||
namespace rx
|
||||
{
|
||||
class Renderer;
|
||||
class SwapChain;
|
||||
class RendererD3D; //TODO(jmadill): remove this
|
||||
}
|
||||
|
||||
namespace egl
|
||||
@ -52,13 +41,13 @@ class Surface
|
||||
|
||||
virtual ~Surface();
|
||||
|
||||
bool initialize();
|
||||
Error initialize();
|
||||
void release();
|
||||
bool resetSwapChain();
|
||||
Error resetSwapChain();
|
||||
|
||||
EGLNativeWindowType getWindowHandle();
|
||||
bool swap();
|
||||
bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
Error swap();
|
||||
Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
|
||||
virtual EGLint isPostSubBufferSupported() const;
|
||||
|
||||
@ -81,35 +70,31 @@ class Surface
|
||||
virtual gl::Texture2D *getBoundTexture() const;
|
||||
|
||||
EGLint isFixedSize() const;
|
||||
void setFixedWidth(EGLint width);
|
||||
void setFixedHeight(EGLint height);
|
||||
|
||||
private:
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Surface);
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
|
||||
HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
Display *const mDisplay;
|
||||
rx::Renderer *mRenderer;
|
||||
rx::RendererD3D *mRenderer;
|
||||
|
||||
HANDLE mShareHandle;
|
||||
rx::SwapChain *mSwapChain;
|
||||
|
||||
void subclassWindow();
|
||||
void unsubclassWindow();
|
||||
bool resizeSwapChain(int backbufferWidth, int backbufferHeight);
|
||||
bool resetSwapChain(int backbufferWidth, int backbufferHeight);
|
||||
bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
Error resizeSwapChain(int backbufferWidth, int backbufferHeight);
|
||||
Error resetSwapChain(int backbufferWidth, int backbufferHeight);
|
||||
Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
|
||||
const EGLNativeWindowType mWindow; // Window that the surface is created for.
|
||||
rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for.
|
||||
bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
|
||||
const egl::Config *mConfig; // EGL config surface was created with
|
||||
EGLint mHeight; // Height of surface
|
||||
EGLint mWidth; // Width of surface
|
||||
EGLint mFixedHeight; // Pending height of the surface
|
||||
EGLint mFixedWidth; // Pending width of the surface
|
||||
// EGLint horizontalResolution; // Horizontal dot pitch
|
||||
// EGLint verticalResolution; // Vertical dot pitch
|
||||
// EGLBoolean largestPBuffer; // If true, create largest pbuffer possible
|
||||
@ -126,18 +111,9 @@ private:
|
||||
EGLint mSwapInterval;
|
||||
EGLint mPostSubBufferSupported;
|
||||
EGLint mFixedSize;
|
||||
EGLint mSwapFlags;
|
||||
|
||||
bool mSwapIntervalDirty;
|
||||
gl::Texture2D *mTexture;
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
double mScaleFactor;
|
||||
EventRegistrationToken mSizeToken;
|
||||
EventRegistrationToken mDpiToken;
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
EventRegistrationToken mOrientationToken;
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
|
469
src/3rdparty/angle/src/libEGL/libEGL.cpp
vendored
469
src/3rdparty/angle/src/libEGL/libEGL.cpp
vendored
@ -13,7 +13,6 @@
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/version.h"
|
||||
#include "common/platform.h"
|
||||
#include "libGLESv2/Context.h"
|
||||
#include "libGLESv2/Texture.h"
|
||||
#include "libGLESv2/main.h"
|
||||
@ -26,16 +25,20 @@
|
||||
#include "libEGL/Display.h"
|
||||
#include "libEGL/Surface.h"
|
||||
|
||||
#include "common/NativeWindow.h"
|
||||
|
||||
bool validateDisplay(egl::Display *display)
|
||||
{
|
||||
if (display == EGL_NO_DISPLAY)
|
||||
{
|
||||
return egl::error(EGL_BAD_DISPLAY, false);
|
||||
recordError(egl::Error(EGL_BAD_DISPLAY));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!display->isInitialized())
|
||||
{
|
||||
return egl::error(EGL_NOT_INITIALIZED, false);
|
||||
recordError(egl::Error(EGL_NOT_INITIALIZED));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -50,7 +53,8 @@ bool validateConfig(egl::Display *display, EGLConfig config)
|
||||
|
||||
if (!display->isValidConfig(config))
|
||||
{
|
||||
return egl::error(EGL_BAD_CONFIG, false);
|
||||
recordError(egl::Error(EGL_BAD_CONFIG));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -65,7 +69,8 @@ bool validateContext(egl::Display *display, gl::Context *context)
|
||||
|
||||
if (!display->isValidContext(context))
|
||||
{
|
||||
return egl::error(EGL_BAD_CONTEXT, false);
|
||||
recordError(egl::Error(EGL_BAD_CONTEXT));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -80,7 +85,8 @@ bool validateSurface(egl::Display *display, egl::Surface *surface)
|
||||
|
||||
if (!display->isValidSurface(surface))
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, false);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -93,12 +99,7 @@ EGLint __stdcall eglGetError(void)
|
||||
EVENT("()");
|
||||
|
||||
EGLint error = egl::getCurrentError();
|
||||
|
||||
if (error != EGL_SUCCESS)
|
||||
{
|
||||
egl::setCurrentError(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -106,7 +107,7 @@ EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
|
||||
{
|
||||
EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
|
||||
|
||||
return egl::Display::getDisplay(display_id, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
|
||||
return egl::Display::getDisplay(display_id, egl::AttributeMap());
|
||||
}
|
||||
|
||||
EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
|
||||
@ -120,19 +121,26 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
|
||||
break;
|
||||
|
||||
default:
|
||||
return egl::error(EGL_BAD_CONFIG, EGL_NO_DISPLAY);
|
||||
recordError(egl::Error(EGL_BAD_CONFIG));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
EGLNativeDisplayType displayId = static_cast<EGLNativeDisplayType>(native_display);
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
// Validate the display device context
|
||||
if (WindowFromDC(displayId) == NULL)
|
||||
{
|
||||
return egl::success(EGL_NO_DISPLAY);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
EGLint requestedDisplayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
|
||||
EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
|
||||
bool majorVersionSpecified = false;
|
||||
bool minorVersionSpecified = false;
|
||||
bool requestedWARP = false;
|
||||
|
||||
if (attrib_list)
|
||||
{
|
||||
for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2)
|
||||
@ -140,7 +148,69 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
|
||||
switch (curAttrib[0])
|
||||
{
|
||||
case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
|
||||
requestedDisplayType = curAttrib[1];
|
||||
switch (curAttrib[1])
|
||||
{
|
||||
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
|
||||
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
|
||||
if (!egl::Display::supportsPlatformD3D())
|
||||
{
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
|
||||
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
|
||||
if (!egl::Display::supportsPlatformOpenGL())
|
||||
{
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
platformType = curAttrib[1];
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE:
|
||||
if (curAttrib[1] != EGL_DONT_CARE)
|
||||
{
|
||||
majorVersionSpecified = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE:
|
||||
if (curAttrib[1] != EGL_DONT_CARE)
|
||||
{
|
||||
minorVersionSpecified = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_USE_WARP_ANGLE:
|
||||
if (!egl::Display::supportsPlatformD3D())
|
||||
{
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
switch (curAttrib[1])
|
||||
{
|
||||
case EGL_FALSE:
|
||||
case EGL_TRUE:
|
||||
break;
|
||||
|
||||
default:
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
requestedWARP = (curAttrib[1] == EGL_TRUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -149,33 +219,20 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
|
||||
}
|
||||
}
|
||||
|
||||
switch (requestedDisplayType)
|
||||
if (!majorVersionSpecified && minorVersionSpecified)
|
||||
{
|
||||
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
|
||||
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
|
||||
case EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE:
|
||||
if (!egl::Display::supportsPlatformD3D())
|
||||
{
|
||||
return egl::success(EGL_NO_DISPLAY);
|
||||
}
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
|
||||
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
|
||||
if (!egl::Display::supportsPlatformOpenGL())
|
||||
{
|
||||
return egl::success(EGL_NO_DISPLAY);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return egl::success(EGL_NO_DISPLAY);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
return egl::Display::getDisplay(displayId, requestedDisplayType);
|
||||
if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE && requestedWARP)
|
||||
{
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return egl::Display::getDisplay(displayId, egl::AttributeMap(attrib_list));
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
|
||||
@ -185,20 +242,24 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
|
||||
|
||||
if (dpy == EGL_NO_DISPLAY)
|
||||
{
|
||||
return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_DISPLAY));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
egl::Display *display = static_cast<egl::Display*>(dpy);
|
||||
|
||||
if (!display->initialize())
|
||||
egl::Error error = display->initialize();
|
||||
if (error.isError())
|
||||
{
|
||||
return egl::error(EGL_NOT_INITIALIZED, EGL_FALSE);
|
||||
recordError(error);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (major) *major = 1;
|
||||
if (minor) *minor = 4;
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
|
||||
@ -207,14 +268,16 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
|
||||
|
||||
if (dpy == EGL_NO_DISPLAY)
|
||||
{
|
||||
return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_DISPLAY));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
egl::Display *display = static_cast<egl::Display*>(dpy);
|
||||
|
||||
display->terminate();
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
|
||||
@ -227,19 +290,28 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *result;
|
||||
switch (name)
|
||||
{
|
||||
case EGL_CLIENT_APIS:
|
||||
return egl::success("OpenGL_ES");
|
||||
result = "OpenGL_ES";
|
||||
break;
|
||||
case EGL_EXTENSIONS:
|
||||
return egl::success(egl::Display::getExtensionString(display));
|
||||
result = egl::Display::getExtensionString(display);
|
||||
break;
|
||||
case EGL_VENDOR:
|
||||
return egl::success(display->getVendorString());
|
||||
result = display->getVendorString();
|
||||
break;
|
||||
case EGL_VERSION:
|
||||
return egl::success("1.4 (ANGLE " ANGLE_VERSION_STRING ")");
|
||||
result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")";
|
||||
break;
|
||||
default:
|
||||
return egl::error(EGL_BAD_PARAMETER, (const char*)NULL);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return result;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
|
||||
@ -257,17 +329,20 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co
|
||||
|
||||
if (!num_config)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
const EGLint attribList[] = {EGL_NONE};
|
||||
|
||||
if (!display->getConfigs(configs, attribList, config_size, num_config))
|
||||
{
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
|
||||
@ -285,7 +360,8 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
|
||||
|
||||
if (!num_config)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
const EGLint attribList[] = {EGL_NONE};
|
||||
@ -297,7 +373,8 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
|
||||
|
||||
display->getConfigs(configs, attrib_list, config_size, num_config);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
|
||||
@ -314,10 +391,12 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint
|
||||
|
||||
if (!display->getConfigAttrib(config, attribute, value))
|
||||
{
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
|
||||
@ -332,16 +411,21 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
HWND window = (HWND)win;
|
||||
|
||||
if (!IsWindow(window))
|
||||
if (!rx::IsValidEGLNativeWindowType(win))
|
||||
{
|
||||
return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
|
||||
recordError(egl::Error(EGL_BAD_NATIVE_WINDOW));
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return display->createWindowSurface(win, config, attrib_list);
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
egl::Error error = display->createWindowSurface(win, config, attrib_list, &surface);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
|
||||
@ -356,7 +440,15 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
return display->createOffscreenSurface(config, NULL, attrib_list);
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
egl::Error error = display->createOffscreenSurface(config, NULL, attrib_list, &surface);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
|
||||
@ -373,7 +465,8 @@ EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EG
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(EGL_NO_SURFACE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
|
||||
@ -390,12 +483,14 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
display->destroySurface((egl::Surface*)surface);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
|
||||
@ -413,7 +508,8 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
switch (attribute)
|
||||
@ -473,10 +569,12 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
|
||||
*value = eglSurface->isFixedSize();
|
||||
break;
|
||||
default:
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
|
||||
@ -498,7 +596,8 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
rx::SwapChain *swapchain = eglSurface->getSwapChain();
|
||||
@ -522,7 +621,8 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
|
||||
|
||||
if (renderer->getMajorShaderModel() < 4)
|
||||
{
|
||||
return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_CONTEXT));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
*value = static_cast<rx::Renderer11*>(renderer)->getDevice();
|
||||
@ -530,10 +630,12 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglBindAPI(EGLenum api)
|
||||
@ -544,16 +646,19 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api)
|
||||
{
|
||||
case EGL_OPENGL_API:
|
||||
case EGL_OPENVG_API:
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE; // Not supported by this implementation
|
||||
case EGL_OPENGL_ES_API:
|
||||
break;
|
||||
default:
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
egl::setCurrentAPI(api);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLenum __stdcall eglQueryAPI(void)
|
||||
@ -562,7 +667,8 @@ EGLenum __stdcall eglQueryAPI(void)
|
||||
|
||||
EGLenum API = egl::getCurrentAPI();
|
||||
|
||||
return egl::success(API);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return API;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglWaitClient(void)
|
||||
@ -571,7 +677,8 @@ EGLBoolean __stdcall eglWaitClient(void)
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(0);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglReleaseThread(void)
|
||||
@ -580,7 +687,8 @@ EGLBoolean __stdcall eglReleaseThread(void)
|
||||
|
||||
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
|
||||
@ -598,10 +706,19 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu
|
||||
|
||||
if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list);
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
egl::Error error = display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list, &surface);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
|
||||
@ -617,9 +734,30 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
switch (attribute)
|
||||
{
|
||||
case EGL_WIDTH:
|
||||
if (!eglSurface->isFixedSize() || !value) {
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
eglSurface->setFixedWidth(value);
|
||||
return EGL_TRUE;
|
||||
case EGL_HEIGHT:
|
||||
if (!eglSurface->isFixedSize() || !value) {
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
eglSurface->setFixedHeight(value);
|
||||
return EGL_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
|
||||
@ -636,30 +774,36 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint
|
||||
|
||||
if (buffer != EGL_BACK_BUFFER)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (eglSurface->getBoundTexture())
|
||||
{
|
||||
return egl::error(EGL_BAD_ACCESS, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_ACCESS));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (!glBindTexImage(eglSurface))
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
|
||||
@ -676,17 +820,20 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
|
||||
|
||||
if (buffer != EGL_BACK_BUFFER)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
gl::Texture2D *texture = eglSurface->getBoundTexture();
|
||||
@ -696,7 +843,8 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
|
||||
texture->releaseTexImage();
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
|
||||
@ -714,12 +862,14 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
|
||||
|
||||
if (draw_surface == NULL)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
draw_surface->setSwapInterval(interval);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
|
||||
@ -744,27 +894,38 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
|
||||
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
|
||||
if (attribute[1] == EGL_TRUE)
|
||||
{
|
||||
return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented
|
||||
recordError(egl::Error(EGL_BAD_CONFIG)); // Unimplemented
|
||||
return EGL_NO_CONTEXT;
|
||||
// robust_access = true;
|
||||
}
|
||||
else if (attribute[1] != EGL_FALSE)
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
|
||||
{
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
break;
|
||||
case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
|
||||
if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT)
|
||||
{
|
||||
reset_notification = true;
|
||||
}
|
||||
else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT)
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
|
||||
{
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (client_version != 2 && client_version != 3)
|
||||
{
|
||||
return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
|
||||
recordError(egl::Error(EGL_BAD_CONFIG));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
egl::Display *display = static_cast<egl::Display*>(dpy);
|
||||
@ -775,18 +936,21 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
|
||||
|
||||
if (sharedGLContext->isResetNotificationEnabled() != reset_notification)
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
if (sharedGLContext->getClientVersion() != client_version)
|
||||
{
|
||||
return egl::error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
|
||||
recordError(egl::Error(EGL_BAD_CONTEXT));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
// Can not share contexts between displays
|
||||
if (sharedGLContext->getRenderer() != display->getRenderer())
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -795,7 +959,16 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
return display->createContext(config, client_version, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
egl::Error error = display->createContext(config, client_version, static_cast<gl::Context*>(share_context),
|
||||
reset_notification, robust_access, &context);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
|
||||
@ -812,12 +985,14 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
|
||||
|
||||
if (ctx == EGL_NO_CONTEXT)
|
||||
{
|
||||
return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_CONTEXT));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
display->destroyContext(context);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
|
||||
@ -832,7 +1007,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
|
||||
bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE);
|
||||
if (noContext != noSurface)
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
|
||||
@ -850,7 +1026,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
|
||||
|
||||
if (renderer->isDeviceLost())
|
||||
{
|
||||
return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_CONTEXT_LOST));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -871,7 +1048,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
|
||||
|
||||
glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLContext __stdcall eglGetCurrentContext(void)
|
||||
@ -880,7 +1058,8 @@ EGLContext __stdcall eglGetCurrentContext(void)
|
||||
|
||||
EGLContext context = glGetCurrentContext();
|
||||
|
||||
return egl::success(context);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return context;
|
||||
}
|
||||
|
||||
EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
|
||||
@ -889,17 +1068,18 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
|
||||
|
||||
if (readdraw == EGL_READ)
|
||||
{
|
||||
EGLSurface read = egl::getCurrentReadSurface();
|
||||
return egl::success(read);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return egl::getCurrentReadSurface();
|
||||
}
|
||||
else if (readdraw == EGL_DRAW)
|
||||
{
|
||||
EGLSurface draw = egl::getCurrentDrawSurface();
|
||||
return egl::success(draw);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return egl::getCurrentDrawSurface();
|
||||
}
|
||||
else
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -909,7 +1089,8 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void)
|
||||
|
||||
EGLDisplay dpy = egl::getCurrentDisplay();
|
||||
|
||||
return egl::success(dpy);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return dpy;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
|
||||
@ -927,7 +1108,8 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(0);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglWaitGL(void)
|
||||
@ -936,7 +1118,8 @@ EGLBoolean __stdcall eglWaitGL(void)
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(0);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglWaitNative(EGLint engine)
|
||||
@ -945,7 +1128,8 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine)
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(0);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
|
||||
@ -962,20 +1146,25 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
|
||||
|
||||
if (display->getRenderer()->isDeviceLost())
|
||||
{
|
||||
return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_CONTEXT_LOST));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (eglSurface->swap())
|
||||
egl::Error error = eglSurface->swap();
|
||||
if (error.isError())
|
||||
{
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(error);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return EGL_FALSE;
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
|
||||
@ -992,12 +1181,14 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ
|
||||
|
||||
if (display->getRenderer()->isDeviceLost())
|
||||
{
|
||||
return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_CONTEXT_LOST));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(0);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
@ -1006,7 +1197,8 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
|
||||
|
||||
if (x < 0 || y < 0 || width < 0 || height < 0)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
egl::Display *display = static_cast<egl::Display*>(dpy);
|
||||
@ -1019,20 +1211,25 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
|
||||
|
||||
if (display->getRenderer()->isDeviceLost())
|
||||
{
|
||||
return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_CONTEXT_LOST));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (eglSurface->postSubBuffer(x, y, width, height))
|
||||
egl::Error error = eglSurface->postSubBuffer(x, y, width, height);
|
||||
if (error.isError())
|
||||
{
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(error);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return EGL_FALSE;
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
__eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
|
||||
|
40
src/3rdparty/angle/src/libEGL/main.cpp
vendored
40
src/3rdparty/angle/src/libEGL/main.cpp
vendored
@ -11,9 +11,6 @@
|
||||
#include "common/debug.h"
|
||||
#include "common/tls.h"
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
__declspec(thread)
|
||||
#endif
|
||||
static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
|
||||
|
||||
namespace egl
|
||||
@ -21,12 +18,6 @@ namespace egl
|
||||
|
||||
Current *AllocateCurrent()
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (currentTLS == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
currentTLS = CreateTLSIndex();
|
||||
}
|
||||
#endif
|
||||
ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
|
||||
if (currentTLS == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
@ -51,12 +42,6 @@ Current *AllocateCurrent()
|
||||
|
||||
void DeallocateCurrent()
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (currentTLS == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
|
||||
SafeDelete(current);
|
||||
SetTLSValue(currentTLS, NULL);
|
||||
@ -72,7 +57,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_TRACE)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
|
||||
|
||||
if (debug)
|
||||
@ -87,15 +72,15 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain
|
||||
return DisableThreadLibraryCalls(instance);
|
||||
#endif
|
||||
|
||||
currentTLS = CreateTLSIndex();
|
||||
if (currentTLS == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
gl::InitializeDebugAnnotations();
|
||||
#endif
|
||||
}
|
||||
// Fall through to initialize index
|
||||
case DLL_THREAD_ATTACH:
|
||||
@ -105,15 +90,17 @@ 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:
|
||||
{
|
||||
egl::DeallocateCurrent();
|
||||
DestroyTLSIndex(currentTLS);
|
||||
|
||||
#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
gl::UninitializeDebugAnnotations();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -143,11 +130,11 @@ Current *GetCurrentData()
|
||||
#endif
|
||||
}
|
||||
|
||||
void setCurrentError(EGLint error)
|
||||
void recordError(const Error &error)
|
||||
{
|
||||
Current *current = GetCurrentData();
|
||||
|
||||
current->error = error;
|
||||
current->error = error.getCode();
|
||||
}
|
||||
|
||||
EGLint getCurrentError()
|
||||
@ -213,9 +200,4 @@ EGLSurface getCurrentReadSurface()
|
||||
return current->readSurface;
|
||||
}
|
||||
|
||||
void error(EGLint errorCode)
|
||||
{
|
||||
egl::setCurrentError(errorCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
22
src/3rdparty/angle/src/libEGL/main.h
vendored
22
src/3rdparty/angle/src/libEGL/main.h
vendored
@ -9,6 +9,8 @@
|
||||
#ifndef LIBEGL_MAIN_H_
|
||||
#define LIBEGL_MAIN_H_
|
||||
|
||||
#include "libEGL/Error.h"
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
@ -23,7 +25,7 @@ struct Current
|
||||
EGLSurface readSurface;
|
||||
};
|
||||
|
||||
void setCurrentError(EGLint error);
|
||||
void recordError(const Error &error);
|
||||
EGLint getCurrentError();
|
||||
|
||||
void setCurrentAPI(EGLenum API);
|
||||
@ -38,24 +40,6 @@ EGLSurface getCurrentDrawSurface();
|
||||
void setCurrentReadSurface(EGLSurface surface);
|
||||
EGLSurface getCurrentReadSurface();
|
||||
|
||||
void error(EGLint errorCode);
|
||||
|
||||
template<class T>
|
||||
const T &error(EGLint errorCode, const T &returnValue)
|
||||
{
|
||||
error(errorCode);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T &success(const T &returnValue)
|
||||
{
|
||||
egl::setCurrentError(EGL_SUCCESS);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBEGL_MAIN_H_
|
||||
|
12
src/3rdparty/angle/src/libGLESv2/BinaryStream.h
vendored
12
src/3rdparty/angle/src/libGLESv2/BinaryStream.h
vendored
@ -15,6 +15,7 @@
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -26,7 +27,7 @@ class BinaryInputStream
|
||||
{
|
||||
mError = false;
|
||||
mOffset = 0;
|
||||
mData = static_cast<const char*>(data);
|
||||
mData = static_cast<const uint8_t*>(data);
|
||||
mLength = length;
|
||||
}
|
||||
|
||||
@ -85,7 +86,7 @@ class BinaryInputStream
|
||||
return;
|
||||
}
|
||||
|
||||
v->assign(mData + mOffset, length);
|
||||
v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
|
||||
mOffset += length;
|
||||
}
|
||||
|
||||
@ -115,11 +116,16 @@ class BinaryInputStream
|
||||
return mOffset == mLength;
|
||||
}
|
||||
|
||||
const uint8_t *data()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(BinaryInputStream);
|
||||
bool mError;
|
||||
size_t mOffset;
|
||||
const char *mData;
|
||||
const uint8_t *mData;
|
||||
size_t mLength;
|
||||
|
||||
template <typename T>
|
||||
|
1
src/3rdparty/angle/src/libGLESv2/Buffer.h
vendored
1
src/3rdparty/angle/src/libGLESv2/Buffer.h
vendored
@ -19,7 +19,6 @@
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class Renderer;
|
||||
class BufferImpl;
|
||||
};
|
||||
|
||||
|
865
src/3rdparty/angle/src/libGLESv2/Context.cpp
vendored
865
src/3rdparty/angle/src/libGLESv2/Context.cpp
vendored
File diff suppressed because it is too large
Load Diff
62
src/3rdparty/angle/src/libGLESv2/Context.h
vendored
62
src/3rdparty/angle/src/libGLESv2/Context.h
vendored
@ -13,12 +13,12 @@
|
||||
#include "common/angleutils.h"
|
||||
#include "common/RefCountObject.h"
|
||||
#include "libGLESv2/Caps.h"
|
||||
#include "libGLESv2/Constants.h"
|
||||
#include "libGLESv2/Data.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 "libGLESv2/angletypes.h"
|
||||
|
||||
#include "angle_gl.h"
|
||||
|
||||
@ -50,11 +50,6 @@ class Texture3D;
|
||||
class Texture2DArray;
|
||||
class Framebuffer;
|
||||
class Renderbuffer;
|
||||
class RenderbufferStorage;
|
||||
class Colorbuffer;
|
||||
class Depthbuffer;
|
||||
class Stencilbuffer;
|
||||
class DepthStencilbuffer;
|
||||
class FenceNV;
|
||||
class FenceSync;
|
||||
class Query;
|
||||
@ -68,7 +63,7 @@ class TransformFeedback;
|
||||
class Context
|
||||
{
|
||||
public:
|
||||
Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
|
||||
Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
|
||||
|
||||
virtual ~Context();
|
||||
|
||||
@ -86,7 +81,7 @@ class Context
|
||||
GLuint createRenderbuffer();
|
||||
GLuint createSampler();
|
||||
GLuint createTransformFeedback();
|
||||
GLsync createFenceSync(GLenum condition);
|
||||
GLsync createFenceSync();
|
||||
|
||||
void deleteBuffer(GLuint buffer);
|
||||
void deleteShader(GLuint shader);
|
||||
@ -115,7 +110,7 @@ class Context
|
||||
|
||||
void bindArrayBuffer(GLuint buffer);
|
||||
void bindElementArrayBuffer(GLuint buffer);
|
||||
void bindTexture(GLenum target, GLuint texture);
|
||||
void bindTexture(GLenum target, GLuint handle);
|
||||
void bindReadFramebuffer(GLuint framebuffer);
|
||||
void bindDrawFramebuffer(GLuint framebuffer);
|
||||
void bindRenderbuffer(GLuint renderbuffer);
|
||||
@ -130,8 +125,8 @@ class Context
|
||||
void bindPixelPackBuffer(GLuint buffer);
|
||||
void bindPixelUnpackBuffer(GLuint buffer);
|
||||
void useProgram(GLuint program);
|
||||
void linkProgram(GLuint program);
|
||||
void setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
|
||||
Error linkProgram(GLuint program);
|
||||
Error setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
|
||||
void bindTransformFeedback(GLuint transformFeedback);
|
||||
|
||||
Error beginQuery(GLenum target, GLuint query);
|
||||
@ -139,8 +134,6 @@ class Context
|
||||
|
||||
void setFramebufferZero(Framebuffer *framebuffer);
|
||||
|
||||
void setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
|
||||
|
||||
void setVertexAttribDivisor(GLuint index, GLuint divisor);
|
||||
|
||||
void samplerParameteri(GLuint sampler, GLenum pname, GLint param);
|
||||
@ -183,17 +176,17 @@ class Context
|
||||
bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
|
||||
|
||||
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);
|
||||
Error clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values);
|
||||
Error clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values);
|
||||
Error clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values);
|
||||
Error clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||
|
||||
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
|
||||
Error sync(bool block); // flush/finish
|
||||
|
||||
void recordError(const Error &error);
|
||||
|
||||
@ -215,32 +208,21 @@ class Context
|
||||
|
||||
void getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type);
|
||||
|
||||
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
||||
GLbitfield mask, GLenum filter);
|
||||
Error blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
||||
GLbitfield mask, GLenum filter);
|
||||
|
||||
rx::Renderer *getRenderer() { return mRenderer; }
|
||||
|
||||
State &getState() { return mState; }
|
||||
const State &getState() const { return mState; }
|
||||
|
||||
Data getData() const;
|
||||
|
||||
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;
|
||||
|
||||
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();
|
||||
|
||||
void detachBuffer(GLuint buffer);
|
||||
void detachTexture(GLuint texture);
|
||||
void detachFramebuffer(GLuint framebuffer);
|
||||
@ -249,18 +231,9 @@ class Context
|
||||
void detachTransformFeedback(GLuint transformFeedback);
|
||||
void detachSampler(GLuint sampler);
|
||||
|
||||
Error generateSwizzles(ProgramBinary *programBinary, SamplerType type);
|
||||
Error generateSwizzles(ProgramBinary *programBinary);
|
||||
|
||||
Texture *getIncompleteTexture(GLenum type);
|
||||
|
||||
bool skipDraw(GLenum drawMode);
|
||||
|
||||
void initRendererString();
|
||||
void initExtensionStrings();
|
||||
|
||||
size_t getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray);
|
||||
|
||||
void initCaps(GLuint clientVersion);
|
||||
|
||||
// Caps to use for validation
|
||||
@ -273,7 +246,6 @@ class Context
|
||||
|
||||
int mClientVersion;
|
||||
|
||||
typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
|
||||
TextureMap mZeroTextures;
|
||||
TextureMap mIncompleteTextures;
|
||||
|
||||
|
51
src/3rdparty/angle/src/libGLESv2/Data.cpp
vendored
Normal file
51
src/3rdparty/angle/src/libGLESv2/Data.cpp
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// Data.cpp: Container class for all GL relevant state, caps and objects
|
||||
|
||||
#include "libGLESv2/Data.h"
|
||||
#include "libGLESv2/ResourceManager.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
Data::Data(GLint clientVersionIn, const State &stateIn, const Caps &capsIn,
|
||||
const TextureCapsMap &textureCapsIn, const Extensions &extensionsIn,
|
||||
const ResourceManager *resourceManagerIn)
|
||||
: clientVersion(clientVersionIn),
|
||||
state(&stateIn),
|
||||
caps(&capsIn),
|
||||
textureCaps(&textureCapsIn),
|
||||
extensions(&extensionsIn),
|
||||
resourceManager(resourceManagerIn)
|
||||
{}
|
||||
|
||||
Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Data::Data(const Data &other)
|
||||
: clientVersion(other.clientVersion),
|
||||
state(other.state),
|
||||
caps(other.caps),
|
||||
textureCaps(other.textureCaps),
|
||||
extensions(other.extensions),
|
||||
resourceManager(other.resourceManager)
|
||||
{
|
||||
}
|
||||
|
||||
Data &Data::operator=(const Data &other)
|
||||
{
|
||||
clientVersion = other.clientVersion;
|
||||
state = other.state;
|
||||
caps = other.caps;
|
||||
textureCaps = other.textureCaps;
|
||||
extensions = other.extensions;
|
||||
resourceManager = other.resourceManager;
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
38
src/3rdparty/angle/src/libGLESv2/Data.h
vendored
Normal file
38
src/3rdparty/angle/src/libGLESv2/Data.h
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// Data.h: Container class for all GL relevant state, caps and objects
|
||||
|
||||
#ifndef LIBGLESV2_DATA_H_
|
||||
#define LIBGLESV2_DATA_H_
|
||||
|
||||
#include "libGLESv2/State.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
struct Data
|
||||
{
|
||||
public:
|
||||
Data(GLint clientVersion, const State &state, const Caps &caps,
|
||||
const TextureCapsMap &textureCaps, const Extensions &extensions,
|
||||
const ResourceManager *resourceManager);
|
||||
~Data();
|
||||
|
||||
Data(const Data &other);
|
||||
Data &operator=(const Data &other);
|
||||
|
||||
GLint clientVersion;
|
||||
const State *state;
|
||||
const Caps *caps;
|
||||
const TextureCapsMap *textureCaps;
|
||||
const Extensions *extensions;
|
||||
const ResourceManager *resourceManager;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBGLESV2_DATA_H_
|
176
src/3rdparty/angle/src/libGLESv2/Fence.cpp
vendored
176
src/3rdparty/angle/src/libGLESv2/Fence.cpp
vendored
@ -4,191 +4,113 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension.
|
||||
|
||||
// Important note on accurate timers in Windows:
|
||||
//
|
||||
// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call
|
||||
// as timeGetTime on laptops and "jumping" during certain hardware events.
|
||||
//
|
||||
// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc"
|
||||
// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc
|
||||
//
|
||||
// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer
|
||||
// from buggy implementations.
|
||||
// Fence.cpp: Implements the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence
|
||||
// extension and GLES3 sync objects.
|
||||
|
||||
#include "libGLESv2/Fence.h"
|
||||
#include "libGLESv2/renderer/FenceImpl.h"
|
||||
#include "libGLESv2/renderer/Renderer.h"
|
||||
#include "libGLESv2/main.h"
|
||||
#include "common/utilities.h"
|
||||
|
||||
#include "angle_gl.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
FenceNV::FenceNV(rx::Renderer *renderer)
|
||||
FenceNV::FenceNV(rx::FenceNVImpl *impl)
|
||||
: mFence(impl),
|
||||
mIsSet(false),
|
||||
mStatus(GL_FALSE),
|
||||
mCondition(GL_NONE)
|
||||
{
|
||||
mFence = renderer->createFence();
|
||||
}
|
||||
|
||||
FenceNV::~FenceNV()
|
||||
{
|
||||
delete mFence;
|
||||
SafeDelete(mFence);
|
||||
}
|
||||
|
||||
GLboolean FenceNV::isFence() const
|
||||
{
|
||||
// GL_NV_fence spec:
|
||||
// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
|
||||
return (mFence->isSet() ? GL_TRUE : GL_FALSE);
|
||||
return (mIsSet ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
void FenceNV::setFence(GLenum condition)
|
||||
Error FenceNV::setFence(GLenum condition)
|
||||
{
|
||||
mFence->set();
|
||||
Error error = mFence->set();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
mCondition = condition;
|
||||
mStatus = GL_FALSE;
|
||||
mIsSet = true;
|
||||
|
||||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
GLboolean FenceNV::testFence()
|
||||
Error FenceNV::testFence(GLboolean *outResult)
|
||||
{
|
||||
// Flush the command buffer by default
|
||||
bool result = mFence->test(true);
|
||||
|
||||
mStatus = (result ? GL_TRUE : GL_FALSE);
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
void FenceNV::finishFence()
|
||||
{
|
||||
ASSERT(mFence->isSet());
|
||||
|
||||
while (!mFence->test(true))
|
||||
Error error = mFence->test(true, &mStatus);
|
||||
if (error.isError())
|
||||
{
|
||||
Sleep(0);
|
||||
return error;
|
||||
}
|
||||
|
||||
*outResult = mStatus;
|
||||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
GLint FenceNV::getFencei(GLenum pname)
|
||||
Error FenceNV::finishFence()
|
||||
{
|
||||
ASSERT(mFence->isSet());
|
||||
ASSERT(mIsSet);
|
||||
|
||||
switch (pname)
|
||||
{
|
||||
case GL_FENCE_STATUS_NV:
|
||||
{
|
||||
// GL_NV_fence spec:
|
||||
// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
|
||||
// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
|
||||
if (mStatus == GL_TRUE)
|
||||
{
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
mStatus = (mFence->test(false) ? GL_TRUE : GL_FALSE);
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
case GL_FENCE_CONDITION_NV:
|
||||
return mCondition;
|
||||
|
||||
default: UNREACHABLE(); return 0;
|
||||
}
|
||||
return mFence->finishFence(&mStatus);
|
||||
}
|
||||
|
||||
FenceSync::FenceSync(rx::Renderer *renderer, GLuint id)
|
||||
: RefCountObject(id)
|
||||
FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id)
|
||||
: RefCountObject(id),
|
||||
mFence(impl),
|
||||
mCondition(GL_NONE)
|
||||
{
|
||||
mFence = renderer->createFence();
|
||||
|
||||
LARGE_INTEGER counterFreqency = { 0 };
|
||||
BOOL success = QueryPerformanceFrequency(&counterFreqency);
|
||||
UNUSED_ASSERTION_VARIABLE(success);
|
||||
ASSERT(success);
|
||||
|
||||
mCounterFrequency = counterFreqency.QuadPart;
|
||||
}
|
||||
|
||||
FenceSync::~FenceSync()
|
||||
{
|
||||
delete mFence;
|
||||
SafeDelete(mFence);
|
||||
}
|
||||
|
||||
void FenceSync::set(GLenum condition)
|
||||
Error FenceSync::set(GLenum condition)
|
||||
{
|
||||
Error error = mFence->set();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
mCondition = condition;
|
||||
mFence->set();
|
||||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)
|
||||
Error FenceSync::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult)
|
||||
{
|
||||
ASSERT(mFence->isSet());
|
||||
|
||||
bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0);
|
||||
|
||||
if (mFence->test(flushCommandBuffer))
|
||||
{
|
||||
return GL_ALREADY_SIGNALED;
|
||||
}
|
||||
|
||||
if (mFence->hasError())
|
||||
{
|
||||
return GL_WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
{
|
||||
return GL_TIMEOUT_EXPIRED;
|
||||
}
|
||||
|
||||
LARGE_INTEGER currentCounter = { 0 };
|
||||
BOOL success = QueryPerformanceCounter(¤tCounter);
|
||||
UNUSED_ASSERTION_VARIABLE(success);
|
||||
ASSERT(success);
|
||||
|
||||
LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll);
|
||||
LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds;
|
||||
|
||||
while (currentCounter.QuadPart < endCounter && !mFence->test(flushCommandBuffer))
|
||||
{
|
||||
Sleep(0);
|
||||
BOOL success = QueryPerformanceCounter(¤tCounter);
|
||||
UNUSED_ASSERTION_VARIABLE(success);
|
||||
ASSERT(success);
|
||||
}
|
||||
|
||||
if (mFence->hasError())
|
||||
{
|
||||
return GL_WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (currentCounter.QuadPart >= endCounter)
|
||||
{
|
||||
return GL_TIMEOUT_EXPIRED;
|
||||
}
|
||||
|
||||
return GL_CONDITION_SATISFIED;
|
||||
ASSERT(mCondition != GL_NONE);
|
||||
return mFence->clientWait(flags, timeout, outResult);
|
||||
}
|
||||
|
||||
void FenceSync::serverWait()
|
||||
Error FenceSync::serverWait(GLbitfield flags, GLuint64 timeout)
|
||||
{
|
||||
// Because our API is currently designed to be called from a single thread, we don't need to do
|
||||
// extra work for a server-side fence. GPU commands issued after the fence is created will always
|
||||
// be processed after the fence is signaled.
|
||||
return mFence->serverWait(flags, timeout);
|
||||
}
|
||||
|
||||
GLenum FenceSync::getStatus() const
|
||||
Error FenceSync::getStatus(GLint *outResult) const
|
||||
{
|
||||
if (mFence->test(false))
|
||||
{
|
||||
// The spec does not specify any way to report errors during the status test (e.g. device lost)
|
||||
// so we report the fence is unblocked in case of error or signaled.
|
||||
return GL_SIGNALED;
|
||||
}
|
||||
|
||||
return GL_UNSIGNALED;
|
||||
return mFence->getStatus(outResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
35
src/3rdparty/angle/src/libGLESv2/Fence.h
vendored
35
src/3rdparty/angle/src/libGLESv2/Fence.h
vendored
@ -4,18 +4,21 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Fence.h: Defines the gl::Fence class, which supports the GL_NV_fence extension.
|
||||
// Fence.h: Defines the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence
|
||||
// extension and GLES3 sync objects.
|
||||
|
||||
#ifndef LIBGLESV2_FENCE_H_
|
||||
#define LIBGLESV2_FENCE_H_
|
||||
|
||||
#include "libGLESv2/Error.h"
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "common/RefCountObject.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class Renderer;
|
||||
class FenceImpl;
|
||||
class FenceNVImpl;
|
||||
class FenceSyncImpl;
|
||||
}
|
||||
|
||||
namespace gl
|
||||
@ -24,14 +27,13 @@ namespace gl
|
||||
class FenceNV
|
||||
{
|
||||
public:
|
||||
explicit FenceNV(rx::Renderer *renderer);
|
||||
explicit FenceNV(rx::FenceNVImpl *impl);
|
||||
virtual ~FenceNV();
|
||||
|
||||
GLboolean isFence() const;
|
||||
void setFence(GLenum condition);
|
||||
GLboolean testFence();
|
||||
void finishFence();
|
||||
GLint getFencei(GLenum pname);
|
||||
Error setFence(GLenum condition);
|
||||
Error testFence(GLboolean *outResult);
|
||||
Error finishFence();
|
||||
|
||||
GLboolean getStatus() const { return mStatus; }
|
||||
GLuint getCondition() const { return mCondition; }
|
||||
@ -39,7 +41,9 @@ class FenceNV
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(FenceNV);
|
||||
|
||||
rx::FenceImpl *mFence;
|
||||
rx::FenceNVImpl *mFence;
|
||||
|
||||
bool mIsSet;
|
||||
|
||||
GLboolean mStatus;
|
||||
GLenum mCondition;
|
||||
@ -48,21 +52,20 @@ class FenceNV
|
||||
class FenceSync : public RefCountObject
|
||||
{
|
||||
public:
|
||||
explicit FenceSync(rx::Renderer *renderer, GLuint id);
|
||||
explicit FenceSync(rx::FenceSyncImpl *impl, GLuint id);
|
||||
virtual ~FenceSync();
|
||||
|
||||
void set(GLenum condition);
|
||||
GLenum clientWait(GLbitfield flags, GLuint64 timeout);
|
||||
void serverWait();
|
||||
GLenum getStatus() const;
|
||||
Error set(GLenum condition);
|
||||
Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult);
|
||||
Error serverWait(GLbitfield flags, GLuint64 timeout);
|
||||
Error getStatus(GLint *outResult) const;
|
||||
|
||||
GLuint getCondition() const { return mCondition; }
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(FenceSync);
|
||||
|
||||
rx::FenceImpl *mFence;
|
||||
LONGLONG mCounterFrequency;
|
||||
rx::FenceSyncImpl *mFence;
|
||||
|
||||
GLenum mCondition;
|
||||
};
|
||||
|
277
src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
vendored
277
src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
vendored
@ -16,13 +16,18 @@
|
||||
#include "libGLESv2/FramebufferAttachment.h"
|
||||
#include "libGLESv2/renderer/Renderer.h"
|
||||
#include "libGLESv2/renderer/RenderTarget.h"
|
||||
#include "libGLESv2/renderer/RenderbufferImpl.h"
|
||||
#include "libGLESv2/renderer/Workarounds.h"
|
||||
#include "libGLESv2/renderer/d3d/TextureD3D.h"
|
||||
#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
|
||||
|
||||
#include "common/utilities.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
|
||||
// TODO: Move these functions, and the D3D-specific header inclusions above,
|
||||
// to FramebufferD3D.
|
||||
gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT)
|
||||
{
|
||||
if (attachment->isTexture())
|
||||
{
|
||||
@ -31,14 +36,16 @@ RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
|
||||
TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
|
||||
const gl::ImageIndex *index = attachment->getTextureImageIndex();
|
||||
ASSERT(index);
|
||||
return textureD3D->getRenderTarget(*index);
|
||||
return textureD3D->getRenderTarget(*index, outRT);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
|
||||
ASSERT(renderbuffer);
|
||||
RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
|
||||
*outRT = renderbufferD3D->getRenderTarget();
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
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.
|
||||
@ -56,9 +63,8 @@ unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
|
||||
|
||||
gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
|
||||
ASSERT(renderbuffer);
|
||||
|
||||
// TODO: cast to RenderbufferD3D
|
||||
return renderbuffer->getStorage()->getSerial();
|
||||
RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
|
||||
return renderbufferD3D->getRenderTargetSerial();
|
||||
}
|
||||
|
||||
}
|
||||
@ -66,9 +72,8 @@ unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
|
||||
namespace gl
|
||||
{
|
||||
|
||||
Framebuffer::Framebuffer(rx::Renderer *renderer, GLuint id)
|
||||
: mRenderer(renderer),
|
||||
mId(id),
|
||||
Framebuffer::Framebuffer(GLuint id)
|
||||
: mId(id),
|
||||
mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
|
||||
mDepthbuffer(NULL),
|
||||
mStencilbuffer(NULL)
|
||||
@ -91,124 +96,6 @@ Framebuffer::~Framebuffer()
|
||||
SafeDelete(mStencilbuffer);
|
||||
}
|
||||
|
||||
FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const
|
||||
{
|
||||
if (handle == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gl::Context *context = gl::getContext();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GL_NONE:
|
||||
return NULL;
|
||||
|
||||
case GL_RENDERBUFFER:
|
||||
return new RenderbufferAttachment(binding, context->getRenderbuffer(handle));
|
||||
|
||||
case GL_TEXTURE_2D:
|
||||
{
|
||||
Texture *texture = context->getTexture(handle);
|
||||
if (texture && texture->getTarget() == GL_TEXTURE_2D)
|
||||
{
|
||||
return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
{
|
||||
Texture *texture = context->getTexture(handle);
|
||||
if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
|
||||
{
|
||||
return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
case GL_TEXTURE_3D:
|
||||
{
|
||||
Texture *texture = context->getTexture(handle);
|
||||
if (texture && texture->getTarget() == GL_TEXTURE_3D)
|
||||
{
|
||||
return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
{
|
||||
Texture *texture = context->getTexture(handle);
|
||||
if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
|
||||
{
|
||||
return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
|
||||
{
|
||||
ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
|
||||
SafeDelete(mColorbuffers[colorAttachment]);
|
||||
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(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
|
||||
}
|
||||
|
||||
void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
|
||||
{
|
||||
SafeDelete(mStencilbuffer);
|
||||
mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
|
||||
}
|
||||
|
||||
void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
|
||||
{
|
||||
FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
|
||||
|
||||
SafeDelete(mDepthbuffer);
|
||||
SafeDelete(mStencilbuffer);
|
||||
|
||||
// ensure this is a legitimate depth+stencil format
|
||||
if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0)
|
||||
{
|
||||
mDepthbuffer = attachment;
|
||||
|
||||
// Make a new attachment object to ensure we do not double-delete
|
||||
// See angle issue 686
|
||||
mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::detachTexture(GLuint textureId)
|
||||
{
|
||||
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
|
||||
@ -382,14 +269,13 @@ bool Framebuffer::usingExtendedDrawBuffers() const
|
||||
return false;
|
||||
}
|
||||
|
||||
GLenum Framebuffer::completeness() const
|
||||
GLenum Framebuffer::completeness(const gl::Data &data) const
|
||||
{
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
unsigned int colorbufferSize = 0;
|
||||
int samples = -1;
|
||||
bool missingAttachment = true;
|
||||
GLuint clientVersion = mRenderer->getCurrentClientVersion();
|
||||
|
||||
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
|
||||
{
|
||||
@ -403,8 +289,7 @@ GLenum Framebuffer::completeness() const
|
||||
}
|
||||
|
||||
GLenum internalformat = colorbuffer->getInternalFormat();
|
||||
// TODO(geofflang): use context's texture caps
|
||||
const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
|
||||
const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
|
||||
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
|
||||
if (colorbuffer->isTexture())
|
||||
{
|
||||
@ -443,7 +328,7 @@ GLenum Framebuffer::completeness() const
|
||||
|
||||
// in GLES 2.0, all color attachments attachments must have the same number of bitplanes
|
||||
// in GLES 3.0, there is no such restriction
|
||||
if (clientVersion < 3)
|
||||
if (data.clientVersion < 3)
|
||||
{
|
||||
if (formatInfo.pixelBytes != colorbufferSize)
|
||||
{
|
||||
@ -483,14 +368,12 @@ GLenum Framebuffer::completeness() const
|
||||
}
|
||||
|
||||
GLenum internalformat = mDepthbuffer->getInternalFormat();
|
||||
// TODO(geofflang): use context's texture caps
|
||||
const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
|
||||
const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
|
||||
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
|
||||
if (mDepthbuffer->isTexture())
|
||||
{
|
||||
// depth texture attachments require OES/ANGLE_depth_texture
|
||||
// TODO(geofflang): use context's extensions
|
||||
if (!mRenderer->getRendererExtensions().depthTextures)
|
||||
if (!data.extensions->depthTextures)
|
||||
{
|
||||
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
|
||||
}
|
||||
@ -538,15 +421,13 @@ GLenum Framebuffer::completeness() const
|
||||
}
|
||||
|
||||
GLenum internalformat = mStencilbuffer->getInternalFormat();
|
||||
// TODO(geofflang): use context's texture caps
|
||||
const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
|
||||
const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
|
||||
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
|
||||
if (mStencilbuffer->isTexture())
|
||||
{
|
||||
// texture stencil attachments come along as part
|
||||
// of OES_packed_depth_stencil + OES/ANGLE_depth_texture
|
||||
// TODO(geofflang): use context's extensions
|
||||
if (!mRenderer->getRendererExtensions().depthTextures)
|
||||
if (!data.extensions->depthTextures)
|
||||
{
|
||||
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
|
||||
}
|
||||
@ -602,42 +483,44 @@ GLenum Framebuffer::completeness() const
|
||||
return GL_FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
|
||||
Error Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
|
||||
{
|
||||
GLuint maxDimension = caps.maxRenderbufferSize;
|
||||
invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
|
||||
return invalidateSub(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)
|
||||
Error Framebuffer::invalidateSub(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);
|
||||
FramebufferAttachment *attachment = (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer()
|
||||
: getAttachment(attachmentTarget);
|
||||
|
||||
if (attachment)
|
||||
{
|
||||
rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
|
||||
if (renderTarget)
|
||||
rx::RenderTarget *renderTarget = NULL;
|
||||
Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
|
||||
if (error.isError())
|
||||
{
|
||||
renderTarget->invalidate(x, y, width, height);
|
||||
return error;
|
||||
}
|
||||
|
||||
renderTarget->invalidate(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
|
||||
: Framebuffer(renderer, 0)
|
||||
DefaultFramebuffer::DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil)
|
||||
: Framebuffer(0)
|
||||
{
|
||||
Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer);
|
||||
Renderbuffer *colorRenderbuffer = new Renderbuffer(colorbuffer, 0);
|
||||
mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
|
||||
|
||||
Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
|
||||
Renderbuffer *depthStencilBuffer = new Renderbuffer(depthStencil, 0);
|
||||
|
||||
// Make a new attachment objects to ensure we do not double-delete
|
||||
// See angle issue 686
|
||||
@ -648,9 +531,9 @@ DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colo
|
||||
mReadBufferState = GL_BACK;
|
||||
}
|
||||
|
||||
int Framebuffer::getSamples() const
|
||||
int Framebuffer::getSamples(const gl::Data &data) const
|
||||
{
|
||||
if (completeness() == GL_FRAMEBUFFER_COMPLETE)
|
||||
if (completeness(data) == GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
// for a complete framebuffer, all attachments must have the same sample count
|
||||
// in this case return the first nonzero sample size
|
||||
@ -675,7 +558,7 @@ bool Framebuffer::hasValidDepthStencil() const
|
||||
mDepthbuffer->id() == mStencilbuffer->id());
|
||||
}
|
||||
|
||||
ColorbufferInfo Framebuffer::getColorbuffersForRender() const
|
||||
ColorbufferInfo Framebuffer::getColorbuffersForRender(const rx::Workarounds &workarounds) const
|
||||
{
|
||||
ColorbufferInfo colorbuffersForRender;
|
||||
|
||||
@ -689,18 +572,78 @@ ColorbufferInfo Framebuffer::getColorbuffersForRender() const
|
||||
ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
|
||||
colorbuffersForRender.push_back(colorbuffer);
|
||||
}
|
||||
#if (ANGLE_MRT_PERF_WORKAROUND == ANGLE_WORKAROUND_DISABLED)
|
||||
else
|
||||
else if (!workarounds.mrtPerfWorkaround)
|
||||
{
|
||||
colorbuffersForRender.push_back(NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return colorbuffersForRender;
|
||||
}
|
||||
|
||||
GLenum DefaultFramebuffer::completeness() const
|
||||
void Framebuffer::setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex)
|
||||
{
|
||||
setAttachment(attachment, new TextureAttachment(attachment, texture, imageIndex));
|
||||
}
|
||||
|
||||
void Framebuffer::setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer)
|
||||
{
|
||||
setAttachment(attachment, new RenderbufferAttachment(attachment, renderbuffer));
|
||||
}
|
||||
|
||||
void Framebuffer::setNULLAttachment(GLenum attachment)
|
||||
{
|
||||
setAttachment(attachment, NULL);
|
||||
}
|
||||
|
||||
void Framebuffer::setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj)
|
||||
{
|
||||
if (attachment >= GL_COLOR_ATTACHMENT0 && attachment < (GL_COLOR_ATTACHMENT0 + IMPLEMENTATION_MAX_DRAW_BUFFERS))
|
||||
{
|
||||
size_t colorAttachment = attachment - GL_COLOR_ATTACHMENT0;
|
||||
SafeDelete(mColorbuffers[colorAttachment]);
|
||||
mColorbuffers[colorAttachment] = attachmentObj;
|
||||
}
|
||||
else if (attachment == GL_DEPTH_ATTACHMENT)
|
||||
{
|
||||
SafeDelete(mDepthbuffer);
|
||||
mDepthbuffer = attachmentObj;
|
||||
}
|
||||
else if (attachment == GL_STENCIL_ATTACHMENT)
|
||||
{
|
||||
SafeDelete(mStencilbuffer);
|
||||
mStencilbuffer = attachmentObj;
|
||||
}
|
||||
else if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
|
||||
{
|
||||
SafeDelete(mDepthbuffer);
|
||||
SafeDelete(mStencilbuffer);
|
||||
|
||||
// ensure this is a legitimate depth+stencil format
|
||||
if (attachmentObj && attachmentObj->getDepthSize() > 0 && attachmentObj->getStencilSize() > 0)
|
||||
{
|
||||
mDepthbuffer = attachmentObj;
|
||||
|
||||
// Make a new attachment object to ensure we do not double-delete
|
||||
// See angle issue 686
|
||||
if (attachmentObj->isTexture())
|
||||
{
|
||||
mStencilbuffer = new TextureAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getTexture(),
|
||||
*attachmentObj->getTextureImageIndex());
|
||||
}
|
||||
else
|
||||
{
|
||||
mStencilbuffer = new RenderbufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getRenderbuffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
GLenum DefaultFramebuffer::completeness(const gl::Data &) const
|
||||
{
|
||||
// The default framebuffer *must* always be complete, though it may not be
|
||||
// subject to the same rules as application FBOs. ie, it could have 0x0 size.
|
||||
|
50
src/3rdparty/angle/src/libGLESv2/Framebuffer.h
vendored
50
src/3rdparty/angle/src/libGLESv2/Framebuffer.h
vendored
@ -10,41 +10,44 @@
|
||||
#ifndef LIBGLESV2_FRAMEBUFFER_H_
|
||||
#define LIBGLESV2_FRAMEBUFFER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "libGLESv2/Error.h"
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "common/RefCountObject.h"
|
||||
#include "constants.h"
|
||||
#include "Constants.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class Renderer;
|
||||
class RenderbufferImpl;
|
||||
struct Workarounds;
|
||||
}
|
||||
|
||||
namespace gl
|
||||
{
|
||||
class FramebufferAttachment;
|
||||
class Colorbuffer;
|
||||
class Depthbuffer;
|
||||
class Stencilbuffer;
|
||||
class DepthStencilbuffer;
|
||||
class Texture;
|
||||
class Renderbuffer;
|
||||
struct ImageIndex;
|
||||
struct Caps;
|
||||
struct Extensions;
|
||||
class TextureCapsMap;
|
||||
struct Data;
|
||||
|
||||
typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
|
||||
|
||||
class Framebuffer
|
||||
{
|
||||
public:
|
||||
Framebuffer(rx::Renderer *renderer, GLuint id);
|
||||
|
||||
Framebuffer(GLuint id);
|
||||
virtual ~Framebuffer();
|
||||
|
||||
GLuint id() const { return mId; }
|
||||
|
||||
void setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer);
|
||||
void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer);
|
||||
void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer);
|
||||
void setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer);
|
||||
void setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex);
|
||||
void setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer);
|
||||
void setNULLAttachment(GLenum attachment);
|
||||
|
||||
void detachTexture(GLuint texture);
|
||||
void detachRenderbuffer(GLuint renderbuffer);
|
||||
@ -66,24 +69,21 @@ class Framebuffer
|
||||
bool isEnabledColorAttachment(unsigned int colorAttachment) const;
|
||||
bool hasEnabledColorAttachment() const;
|
||||
bool hasStencil() const;
|
||||
int getSamples() const;
|
||||
int getSamples(const gl::Data &data) const;
|
||||
bool usingExtendedDrawBuffers() const;
|
||||
|
||||
virtual GLenum completeness() const;
|
||||
virtual GLenum completeness(const gl::Data &data) 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);
|
||||
Error invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
|
||||
Error invalidateSub(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;
|
||||
ColorbufferInfo getColorbuffersForRender(const rx::Workarounds &workarounds) const;
|
||||
|
||||
protected:
|
||||
rx::Renderer *mRenderer;
|
||||
|
||||
GLuint mId;
|
||||
|
||||
FramebufferAttachment *mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS];
|
||||
@ -96,15 +96,15 @@ class Framebuffer
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Framebuffer);
|
||||
|
||||
FramebufferAttachment *createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const;
|
||||
void setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj);
|
||||
};
|
||||
|
||||
class DefaultFramebuffer : public Framebuffer
|
||||
{
|
||||
public:
|
||||
DefaultFramebuffer(rx::Renderer *Renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
|
||||
DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil);
|
||||
|
||||
virtual GLenum completeness() const;
|
||||
GLenum completeness(const gl::Data &data) const override;
|
||||
virtual FramebufferAttachment *getAttachment(GLenum attachment) const;
|
||||
|
||||
private:
|
||||
@ -118,7 +118,7 @@ namespace rx
|
||||
class RenderTarget;
|
||||
|
||||
// TODO: place this in FramebufferD3D.h
|
||||
RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
|
||||
gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT);
|
||||
unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment);
|
||||
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ GLenum RenderbufferAttachment::getActualFormat() const
|
||||
|
||||
GLsizei RenderbufferAttachment::getSamples() const
|
||||
{
|
||||
return mRenderbuffer->getStorage()->getSamples();
|
||||
return mRenderbuffer->getSamples();
|
||||
}
|
||||
|
||||
GLuint RenderbufferAttachment::id() const
|
||||
|
@ -16,13 +16,6 @@
|
||||
|
||||
#include "angle_gl.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class Renderer;
|
||||
class RenderTarget;
|
||||
class TextureStorage;
|
||||
}
|
||||
|
||||
namespace gl
|
||||
{
|
||||
class Renderbuffer;
|
||||
|
91
src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
vendored
91
src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
vendored
@ -48,10 +48,101 @@ ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex)
|
||||
return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex);
|
||||
}
|
||||
|
||||
ImageIndex ImageIndex::MakeInvalid()
|
||||
{
|
||||
return ImageIndex(GL_NONE, -1, -1);
|
||||
}
|
||||
|
||||
ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
|
||||
: type(typeIn),
|
||||
mipIndex(mipIndexIn),
|
||||
layerIndex(layerIndexIn)
|
||||
{}
|
||||
|
||||
ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip)
|
||||
{
|
||||
return ImageIndexIterator(GL_TEXTURE_2D, rx::Range<GLint>(minMip, maxMip),
|
||||
rx::Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), NULL);
|
||||
}
|
||||
|
||||
ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip)
|
||||
{
|
||||
return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, rx::Range<GLint>(minMip, maxMip), rx::Range<GLint>(0, 6), NULL);
|
||||
}
|
||||
|
||||
ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip,
|
||||
GLint minLayer, GLint maxLayer)
|
||||
{
|
||||
return ImageIndexIterator(GL_TEXTURE_3D, rx::Range<GLint>(minMip, maxMip), rx::Range<GLint>(minLayer, maxLayer), NULL);
|
||||
}
|
||||
|
||||
ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip,
|
||||
const GLsizei *layerCounts)
|
||||
{
|
||||
return ImageIndexIterator(GL_TEXTURE_2D_ARRAY, rx::Range<GLint>(minMip, maxMip),
|
||||
rx::Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts);
|
||||
}
|
||||
|
||||
ImageIndexIterator::ImageIndexIterator(GLenum type, const rx::Range<GLint> &mipRange,
|
||||
const rx::Range<GLint> &layerRange, const GLsizei *layerCounts)
|
||||
: mType(type),
|
||||
mMipRange(mipRange),
|
||||
mLayerRange(layerRange),
|
||||
mLayerCounts(layerCounts),
|
||||
mCurrentMip(mipRange.start),
|
||||
mCurrentLayer(layerRange.start)
|
||||
{}
|
||||
|
||||
GLint ImageIndexIterator::maxLayer() const
|
||||
{
|
||||
return (mLayerCounts ? static_cast<GLint>(mLayerCounts[mCurrentMip]) : mLayerRange.end);
|
||||
}
|
||||
|
||||
ImageIndex ImageIndexIterator::next()
|
||||
{
|
||||
ASSERT(hasNext());
|
||||
|
||||
ImageIndex value = current();
|
||||
|
||||
// Iterate layers in the inner loop for now. We can add switchable
|
||||
// layer or mip iteration if we need it.
|
||||
|
||||
if (mCurrentLayer != ImageIndex::ENTIRE_LEVEL)
|
||||
{
|
||||
if (mCurrentLayer < maxLayer()-1)
|
||||
{
|
||||
mCurrentLayer++;
|
||||
}
|
||||
else if (mCurrentMip < mMipRange.end-1)
|
||||
{
|
||||
mCurrentMip++;
|
||||
mCurrentLayer = mLayerRange.start;
|
||||
}
|
||||
}
|
||||
else if (mCurrentMip < mMipRange.end-1)
|
||||
{
|
||||
mCurrentMip++;
|
||||
mCurrentLayer = mLayerRange.start;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
ImageIndex ImageIndexIterator::current() const
|
||||
{
|
||||
ImageIndex value(mType, mCurrentMip, mCurrentLayer);
|
||||
|
||||
if (mType == GL_TEXTURE_CUBE_MAP)
|
||||
{
|
||||
value.type = TextureCubeMap::layerIndexToTarget(mCurrentLayer);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool ImageIndexIterator::hasNext() const
|
||||
{
|
||||
return (mCurrentMip < mMipRange.end || mCurrentLayer < maxLayer());
|
||||
}
|
||||
|
||||
}
|
||||
|
29
src/3rdparty/angle/src/libGLESv2/ImageIndex.h
vendored
29
src/3rdparty/angle/src/libGLESv2/ImageIndex.h
vendored
@ -10,6 +10,7 @@
|
||||
#define LIBGLESV2_IMAGE_INDEX_H_
|
||||
|
||||
#include "angle_gl.h"
|
||||
#include "common/mathutil.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -20,6 +21,7 @@ struct ImageIndex
|
||||
GLint mipIndex;
|
||||
GLint layerIndex;
|
||||
|
||||
ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
|
||||
ImageIndex(const ImageIndex &other);
|
||||
ImageIndex &operator=(const ImageIndex &other);
|
||||
|
||||
@ -29,11 +31,36 @@ struct ImageIndex
|
||||
static ImageIndex MakeCube(GLenum target, GLint mipIndex);
|
||||
static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex);
|
||||
static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
|
||||
static ImageIndex MakeInvalid();
|
||||
|
||||
static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1);
|
||||
};
|
||||
|
||||
class ImageIndexIterator
|
||||
{
|
||||
public:
|
||||
static ImageIndexIterator Make2D(GLint minMip, GLint maxMip);
|
||||
static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip);
|
||||
static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer);
|
||||
static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts);
|
||||
|
||||
ImageIndex next();
|
||||
ImageIndex current() const;
|
||||
bool hasNext() const;
|
||||
|
||||
private:
|
||||
ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
|
||||
|
||||
ImageIndexIterator(GLenum type, const rx::Range<GLint> &mipRange,
|
||||
const rx::Range<GLint> &layerRange, const GLsizei *layerCounts);
|
||||
|
||||
GLint maxLayer() const;
|
||||
|
||||
GLenum mType;
|
||||
rx::Range<GLint> mMipRange;
|
||||
rx::Range<GLint> mLayerRange;
|
||||
const GLsizei *mLayerCounts;
|
||||
GLint mCurrentMip;
|
||||
GLint mCurrentLayer;
|
||||
};
|
||||
|
||||
}
|
||||
|
24
src/3rdparty/angle/src/libGLESv2/Program.cpp
vendored
24
src/3rdparty/angle/src/libGLESv2/Program.cpp
vendored
@ -244,7 +244,7 @@ void Program::bindAttributeLocation(GLuint index, const char *name)
|
||||
// Links the HLSL code of the vertex and pixel shader by matching up their varyings,
|
||||
// compiling them into binaries, determining the attribute mappings, and collecting
|
||||
// a list of uniforms
|
||||
bool Program::link(const Caps &caps)
|
||||
Error Program::link(const Data &data)
|
||||
{
|
||||
unlink(false);
|
||||
|
||||
@ -252,10 +252,15 @@ bool Program::link(const Caps &caps)
|
||||
resetUniformBlockBindings();
|
||||
|
||||
mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
|
||||
mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
|
||||
mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps);
|
||||
LinkResult result = mProgramBinary->link(data, mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
|
||||
mTransformFeedbackVaryings, mTransformFeedbackBufferMode);
|
||||
if (result.error.isError())
|
||||
{
|
||||
return result.error;
|
||||
}
|
||||
|
||||
return mLinked;
|
||||
mLinked = result.linkSuccess;
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
int AttributeBindings::getAttributeBinding(const std::string &name) const
|
||||
@ -303,21 +308,22 @@ ProgramBinary* Program::getProgramBinary() const
|
||||
return mProgramBinary.get();
|
||||
}
|
||||
|
||||
bool Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
|
||||
Error Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
|
||||
{
|
||||
unlink(false);
|
||||
|
||||
mInfoLog.reset();
|
||||
|
||||
mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
|
||||
mLinked = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
|
||||
|
||||
if (!mLinked)
|
||||
LinkResult result = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
|
||||
if (result.error.isError())
|
||||
{
|
||||
mProgramBinary.set(NULL);
|
||||
return result.error;
|
||||
}
|
||||
|
||||
return mLinked;
|
||||
mLinked = result.linkSuccess;
|
||||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
void Program::release()
|
||||
|
5
src/3rdparty/angle/src/libGLESv2/Program.h
vendored
5
src/3rdparty/angle/src/libGLESv2/Program.h
vendored
@ -29,6 +29,7 @@ class Renderer;
|
||||
namespace gl
|
||||
{
|
||||
struct Caps;
|
||||
struct Data;
|
||||
class ResourceManager;
|
||||
class Shader;
|
||||
|
||||
@ -77,9 +78,9 @@ class Program
|
||||
|
||||
void bindAttributeLocation(GLuint index, const char *name);
|
||||
|
||||
bool link(const Caps &caps);
|
||||
Error link(const Data &data);
|
||||
bool isLinked();
|
||||
bool setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
|
||||
Error setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
|
||||
ProgramBinary *getProgramBinary() const;
|
||||
|
||||
int getInfoLogLength() const;
|
||||
|
2098
src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
vendored
2098
src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
vendored
File diff suppressed because it is too large
Load Diff
133
src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
vendored
133
src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
vendored
@ -24,11 +24,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// TODO(jmadill): place this in workarounds library
|
||||
#define ANGLE_WORKAROUND_ENABLED 1
|
||||
#define ANGLE_WORKAROUND_DISABLED 2
|
||||
#define ANGLE_MRT_PERF_WORKAROUND ANGLE_WORKAROUND_ENABLED
|
||||
|
||||
namespace sh
|
||||
{
|
||||
class HLSLBlockEncoder;
|
||||
@ -44,7 +39,6 @@ class HLSLBlockEncoder;
|
||||
namespace rx
|
||||
{
|
||||
class ShaderExecutable;
|
||||
class Renderer;
|
||||
struct TranslatedAttribute;
|
||||
class UniformStorage;
|
||||
class ProgramImpl;
|
||||
@ -58,6 +52,7 @@ class InfoLog;
|
||||
class AttributeBindings;
|
||||
class Buffer;
|
||||
class Framebuffer;
|
||||
struct Data;
|
||||
|
||||
// Struct used for correlating uniforms/elements of uniform arrays to handles
|
||||
struct VariableLocation
|
||||
@ -91,6 +86,14 @@ struct LinkedVarying
|
||||
unsigned int semanticIndexCount;
|
||||
};
|
||||
|
||||
struct LinkResult
|
||||
{
|
||||
bool linkSuccess;
|
||||
Error error;
|
||||
|
||||
LinkResult(bool linkSuccess, const Error &error);
|
||||
};
|
||||
|
||||
// This is the result of linking a program. It is the state that would be passed to ProgramBinary.
|
||||
class ProgramBinary : public RefCountObject
|
||||
{
|
||||
@ -101,11 +104,6 @@ class ProgramBinary : public RefCountObject
|
||||
rx::ProgramImpl *getImplementation() { return mProgram; }
|
||||
const rx::ProgramImpl *getImplementation() const { return mProgram; }
|
||||
|
||||
rx::ShaderExecutable *getPixelExecutableForFramebuffer(const Framebuffer *fbo);
|
||||
rx::ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout);
|
||||
rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]);
|
||||
rx::ShaderExecutable *getGeometryExecutable() const;
|
||||
|
||||
GLuint getAttributeLocation(const char *name);
|
||||
int getSemanticIndex(int attributeIndex);
|
||||
|
||||
@ -113,8 +111,6 @@ class ProgramBinary : public RefCountObject
|
||||
GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
|
||||
GLint getUsedSamplerRange(SamplerType type);
|
||||
bool usesPointSize() const;
|
||||
bool usesPointSpriteEmulation() const;
|
||||
bool usesGeometryShader() const;
|
||||
|
||||
GLint getUniformLocation(std::string name);
|
||||
GLuint getUniformIndex(std::string name);
|
||||
@ -145,18 +141,17 @@ class ProgramBinary : public RefCountObject
|
||||
void getUniformiv(GLint location, GLint *params);
|
||||
void getUniformuiv(GLint location, GLuint *params);
|
||||
|
||||
void dirtyAllUniforms();
|
||||
|
||||
Error applyUniforms();
|
||||
Error applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps);
|
||||
|
||||
bool load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
|
||||
bool save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
|
||||
LinkResult load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
|
||||
Error save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
|
||||
GLint getLength();
|
||||
|
||||
bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
|
||||
const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps);
|
||||
void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
|
||||
LinkResult link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings,
|
||||
Shader *fragmentShader, Shader *vertexShader,
|
||||
const std::vector<std::string> &transformFeedbackVaryings,
|
||||
GLenum transformFeedbackBufferMode);
|
||||
|
||||
void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
|
||||
GLint getActiveAttributeCount() const;
|
||||
@ -188,30 +183,23 @@ class ProgramBinary : public RefCountObject
|
||||
void updateSamplerMapping();
|
||||
|
||||
unsigned int getSerial() const;
|
||||
int getShaderVersion() const;
|
||||
|
||||
void initAttributesByLayout();
|
||||
void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const;
|
||||
|
||||
const std::vector<LinkedUniform*> &getUniforms() const { return mUniforms; }
|
||||
|
||||
static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader);
|
||||
static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
|
||||
static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
|
||||
|
||||
struct Sampler
|
||||
{
|
||||
Sampler();
|
||||
|
||||
bool active;
|
||||
GLint logicalTextureUnit;
|
||||
GLenum textureType;
|
||||
};
|
||||
|
||||
void reset();
|
||||
|
||||
bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader);
|
||||
bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
|
||||
bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
|
||||
const sh::InterfaceBlock &fragmentInterfaceBlock);
|
||||
|
||||
static bool linkValidateVariablesBase(InfoLog &infoLog,
|
||||
const std::string &variableName,
|
||||
@ -219,102 +207,21 @@ class ProgramBinary : public RefCountObject
|
||||
const sh::ShaderVariable &fragmentVariable,
|
||||
bool validatePrecision);
|
||||
|
||||
static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
|
||||
static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
|
||||
static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
|
||||
bool linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
|
||||
void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister);
|
||||
void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder);
|
||||
bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps);
|
||||
bool indexUniforms(InfoLog &infoLog, const Caps &caps);
|
||||
static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
|
||||
std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
|
||||
bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock);
|
||||
bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
|
||||
bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
|
||||
const std::vector<std::string> &transformFeedbackVaryingNames,
|
||||
GLenum transformFeedbackBufferMode,
|
||||
std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
|
||||
const Caps &caps) const;
|
||||
template <typename VarT>
|
||||
void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
|
||||
sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
|
||||
bool inRowMajorLayout);
|
||||
bool defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps);
|
||||
bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps);
|
||||
void defineOutputVariables(Shader *fragmentShader);
|
||||
|
||||
template <typename T>
|
||||
void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
|
||||
|
||||
template <int cols, int rows>
|
||||
void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
|
||||
|
||||
template <typename T>
|
||||
void getUniformv(GLint location, T *params, GLenum uniformType);
|
||||
|
||||
class VertexExecutable
|
||||
{
|
||||
public:
|
||||
VertexExecutable(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS],
|
||||
const GLenum signature[MAX_VERTEX_ATTRIBS],
|
||||
rx::ShaderExecutable *shaderExecutable);
|
||||
~VertexExecutable();
|
||||
|
||||
bool matchesSignature(const GLenum convertedLayout[MAX_VERTEX_ATTRIBS]) const;
|
||||
|
||||
const VertexFormat *inputs() const { return mInputs; }
|
||||
const GLenum *signature() const { return mSignature; }
|
||||
rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
|
||||
|
||||
private:
|
||||
VertexFormat mInputs[MAX_VERTEX_ATTRIBS];
|
||||
GLenum mSignature[MAX_VERTEX_ATTRIBS];
|
||||
rx::ShaderExecutable *mShaderExecutable;
|
||||
};
|
||||
|
||||
class PixelExecutable
|
||||
{
|
||||
public:
|
||||
PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable);
|
||||
~PixelExecutable();
|
||||
|
||||
bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
|
||||
|
||||
const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
|
||||
rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
|
||||
|
||||
private:
|
||||
std::vector<GLenum> mOutputSignature;
|
||||
rx::ShaderExecutable *mShaderExecutable;
|
||||
};
|
||||
|
||||
rx::ProgramImpl *mProgram;
|
||||
|
||||
std::vector<VertexExecutable *> mVertexExecutables;
|
||||
std::vector<PixelExecutable *> mPixelExecutables;
|
||||
|
||||
rx::ShaderExecutable *mGeometryExecutable;
|
||||
|
||||
sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
|
||||
sh::Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS];
|
||||
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
|
||||
int mAttributesByLayout[MAX_VERTEX_ATTRIBS];
|
||||
|
||||
GLenum mTransformFeedbackBufferMode;
|
||||
std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings;
|
||||
|
||||
std::vector<Sampler> mSamplersPS;
|
||||
std::vector<Sampler> mSamplersVS;
|
||||
GLuint mUsedVertexSamplerRange;
|
||||
GLuint mUsedPixelSamplerRange;
|
||||
bool mUsesPointSize;
|
||||
int mShaderVersion;
|
||||
bool mDirtySamplerMapping;
|
||||
|
||||
std::vector<LinkedUniform*> mUniforms;
|
||||
std::vector<UniformBlock*> mUniformBlocks;
|
||||
std::vector<VariableLocation> mUniformIndex;
|
||||
std::map<int, VariableLocation> mOutputVariables;
|
||||
|
||||
bool mValidated;
|
||||
|
235
src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
vendored
235
src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
vendored
@ -4,77 +4,86 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Renderbuffer.cpp: the gl::Renderbuffer class and its derived classes
|
||||
// Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
|
||||
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
|
||||
// Renderbuffer.cpp: Implements the renderer-agnostic gl::Renderbuffer class,
|
||||
// GL renderbuffer objects and related functionality.
|
||||
// [OpenGL ES 2.0.24] section 4.4.3 page 108.
|
||||
|
||||
#include "libGLESv2/Renderbuffer.h"
|
||||
#include "libGLESv2/Texture.h"
|
||||
#include "libGLESv2/formatutils.h"
|
||||
#include "libGLESv2/FramebufferAttachment.h"
|
||||
#include "libGLESv2/renderer/Renderer.h"
|
||||
#include "libGLESv2/renderer/d3d/RendererD3D.h"
|
||||
#include "libGLESv2/renderer/RenderTarget.h"
|
||||
#include "libGLESv2/renderer/RenderbufferImpl.h"
|
||||
|
||||
#include "common/utilities.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
unsigned int RenderbufferStorage::mCurrentSerial = 1;
|
||||
|
||||
Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *newStorage)
|
||||
Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id)
|
||||
: RefCountObject(id),
|
||||
mStorage(newStorage)
|
||||
mRenderbuffer(impl)
|
||||
{
|
||||
ASSERT(mStorage);
|
||||
ASSERT(mRenderbuffer);
|
||||
|
||||
mWidth = mRenderbuffer->getWidth();
|
||||
mHeight = mRenderbuffer->getHeight();
|
||||
mInternalFormat = mRenderbuffer->getInternalFormat();
|
||||
mActualFormat = mRenderbuffer->getActualFormat();
|
||||
mSamples = mRenderbuffer->getSamples();
|
||||
}
|
||||
|
||||
Renderbuffer::~Renderbuffer()
|
||||
{
|
||||
SafeDelete(mStorage);
|
||||
SafeDelete(mRenderbuffer);
|
||||
}
|
||||
|
||||
void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
|
||||
Error Renderbuffer::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
|
||||
{
|
||||
ASSERT(newStorage);
|
||||
Error error = mRenderbuffer->setStorage(width, height, internalformat, samples);
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
SafeDelete(mStorage);
|
||||
mStorage = newStorage;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mInternalFormat = internalformat;
|
||||
mSamples = samples;
|
||||
mActualFormat = mRenderbuffer->getActualFormat();
|
||||
|
||||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
RenderbufferStorage *Renderbuffer::getStorage()
|
||||
rx::RenderbufferImpl *Renderbuffer::getImplementation()
|
||||
{
|
||||
ASSERT(mStorage);
|
||||
return mStorage;
|
||||
ASSERT(mRenderbuffer);
|
||||
return mRenderbuffer;
|
||||
}
|
||||
|
||||
GLsizei Renderbuffer::getWidth() const
|
||||
{
|
||||
ASSERT(mStorage);
|
||||
return mStorage->getWidth();
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
GLsizei Renderbuffer::getHeight() const
|
||||
{
|
||||
ASSERT(mStorage);
|
||||
return mStorage->getHeight();
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
GLenum Renderbuffer::getInternalFormat() const
|
||||
{
|
||||
ASSERT(mStorage);
|
||||
return mStorage->getInternalFormat();
|
||||
return mInternalFormat;
|
||||
}
|
||||
|
||||
GLenum Renderbuffer::getActualFormat() const
|
||||
{
|
||||
ASSERT(mStorage);
|
||||
return mStorage->getActualFormat();
|
||||
return mActualFormat;
|
||||
}
|
||||
|
||||
GLsizei Renderbuffer::getSamples() const
|
||||
{
|
||||
ASSERT(mStorage);
|
||||
return mStorage->getSamples();
|
||||
return mSamples;
|
||||
}
|
||||
|
||||
GLuint Renderbuffer::getRedSize() const
|
||||
@ -107,176 +116,4 @@ GLuint Renderbuffer::getStencilSize() const
|
||||
return GetInternalFormatInfo(getActualFormat()).stencilBits;
|
||||
}
|
||||
|
||||
RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerials(1))
|
||||
{
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mInternalFormat = GL_RGBA4;
|
||||
mActualFormat = GL_RGBA8_OES;
|
||||
mSamples = 0;
|
||||
}
|
||||
|
||||
RenderbufferStorage::~RenderbufferStorage()
|
||||
{
|
||||
}
|
||||
|
||||
rx::RenderTarget *RenderbufferStorage::getRenderTarget()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GLsizei RenderbufferStorage::getWidth() const
|
||||
{
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
GLsizei RenderbufferStorage::getHeight() const
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
GLenum RenderbufferStorage::getInternalFormat() const
|
||||
{
|
||||
return mInternalFormat;
|
||||
}
|
||||
|
||||
GLenum RenderbufferStorage::getActualFormat() const
|
||||
{
|
||||
return mActualFormat;
|
||||
}
|
||||
|
||||
GLsizei RenderbufferStorage::getSamples() const
|
||||
{
|
||||
return mSamples;
|
||||
}
|
||||
|
||||
unsigned int RenderbufferStorage::getSerial() const
|
||||
{
|
||||
return mSerial;
|
||||
}
|
||||
|
||||
unsigned int RenderbufferStorage::issueSerials(unsigned int count)
|
||||
{
|
||||
unsigned int firstSerial = mCurrentSerial;
|
||||
mCurrentSerial += count;
|
||||
return firstSerial;
|
||||
}
|
||||
|
||||
bool RenderbufferStorage::isTexture() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int RenderbufferStorage::getTextureSerial() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
Colorbuffer::Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain)
|
||||
{
|
||||
mRenderTarget = renderer->createRenderTarget(swapChain, false);
|
||||
|
||||
if (mRenderTarget)
|
||||
{
|
||||
mWidth = mRenderTarget->getWidth();
|
||||
mHeight = mRenderTarget->getHeight();
|
||||
mInternalFormat = mRenderTarget->getInternalFormat();
|
||||
mActualFormat = mRenderTarget->getActualFormat();
|
||||
mSamples = mRenderTarget->getSamples();
|
||||
}
|
||||
}
|
||||
|
||||
Colorbuffer::Colorbuffer(rx::Renderer *renderer, int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
|
||||
{
|
||||
mRenderTarget = renderer->createRenderTarget(width, height, format, samples);
|
||||
|
||||
if (mRenderTarget)
|
||||
{
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mInternalFormat = format;
|
||||
mActualFormat = mRenderTarget->getActualFormat();
|
||||
mSamples = mRenderTarget->getSamples();
|
||||
}
|
||||
}
|
||||
|
||||
Colorbuffer::~Colorbuffer()
|
||||
{
|
||||
if (mRenderTarget)
|
||||
{
|
||||
delete mRenderTarget;
|
||||
}
|
||||
}
|
||||
|
||||
rx::RenderTarget *Colorbuffer::getRenderTarget()
|
||||
{
|
||||
return mRenderTarget;
|
||||
}
|
||||
|
||||
DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain)
|
||||
{
|
||||
mDepthStencil = renderer->createRenderTarget(swapChain, true);
|
||||
if (mDepthStencil)
|
||||
{
|
||||
mWidth = mDepthStencil->getWidth();
|
||||
mHeight = mDepthStencil->getHeight();
|
||||
mInternalFormat = mDepthStencil->getInternalFormat();
|
||||
mSamples = mDepthStencil->getSamples();
|
||||
mActualFormat = mDepthStencil->getActualFormat();
|
||||
}
|
||||
}
|
||||
|
||||
DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples)
|
||||
{
|
||||
|
||||
mDepthStencil = renderer->createRenderTarget(width, height, GL_DEPTH24_STENCIL8_OES, samples);
|
||||
|
||||
mWidth = mDepthStencil->getWidth();
|
||||
mHeight = mDepthStencil->getHeight();
|
||||
mInternalFormat = GL_DEPTH24_STENCIL8_OES;
|
||||
mActualFormat = mDepthStencil->getActualFormat();
|
||||
mSamples = mDepthStencil->getSamples();
|
||||
}
|
||||
|
||||
DepthStencilbuffer::~DepthStencilbuffer()
|
||||
{
|
||||
if (mDepthStencil)
|
||||
{
|
||||
delete mDepthStencil;
|
||||
}
|
||||
}
|
||||
|
||||
rx::RenderTarget *DepthStencilbuffer::getRenderTarget()
|
||||
{
|
||||
return mDepthStencil;
|
||||
}
|
||||
|
||||
Depthbuffer::Depthbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples)
|
||||
{
|
||||
if (mDepthStencil)
|
||||
{
|
||||
mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
|
||||
// will expect one of the valid renderbuffer formats for use in
|
||||
// glRenderbufferStorage
|
||||
}
|
||||
}
|
||||
|
||||
Depthbuffer::~Depthbuffer()
|
||||
{
|
||||
}
|
||||
|
||||
Stencilbuffer::Stencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples)
|
||||
{
|
||||
if (mDepthStencil)
|
||||
{
|
||||
mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
|
||||
// will expect one of the valid renderbuffer formats for use in
|
||||
// glRenderbufferStorage
|
||||
}
|
||||
}
|
||||
|
||||
Stencilbuffer::~Stencilbuffer()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
113
src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
vendored
113
src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
vendored
@ -4,30 +4,27 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Renderbuffer.h: Defines the wrapper class gl::Renderbuffer, as well as the
|
||||
// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
|
||||
// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
|
||||
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
|
||||
// Renderbuffer.h: Defines the renderer-agnostic container class gl::Renderbuffer.
|
||||
// Implements GL renderbuffer objects and related functionality.
|
||||
// [OpenGL ES 2.0.24] section 4.4.3 page 108.
|
||||
|
||||
#ifndef LIBGLESV2_RENDERBUFFER_H_
|
||||
#define LIBGLESV2_RENDERBUFFER_H_
|
||||
|
||||
#include "angle_gl.h"
|
||||
|
||||
#include "libGLESv2/Error.h"
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "common/RefCountObject.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class Renderer;
|
||||
class SwapChain;
|
||||
class RenderTarget;
|
||||
class TextureStorage;
|
||||
class RenderbufferImpl;
|
||||
}
|
||||
|
||||
namespace gl
|
||||
{
|
||||
class RenderbufferStorage;
|
||||
class FramebufferAttachment;
|
||||
|
||||
// A GL renderbuffer object is usually used as a depth or stencil buffer attachment
|
||||
@ -38,11 +35,12 @@ class FramebufferAttachment;
|
||||
class Renderbuffer : public RefCountObject
|
||||
{
|
||||
public:
|
||||
Renderbuffer(GLuint id, RenderbufferStorage *newStorage);
|
||||
Renderbuffer(rx::RenderbufferImpl *impl, GLuint id);
|
||||
virtual ~Renderbuffer();
|
||||
|
||||
void setStorage(RenderbufferStorage *newStorage);
|
||||
RenderbufferStorage *getStorage();
|
||||
Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
|
||||
|
||||
rx::RenderbufferImpl *getImplementation();
|
||||
|
||||
GLsizei getWidth() const;
|
||||
GLsizei getHeight() const;
|
||||
@ -57,102 +55,15 @@ class Renderbuffer : public RefCountObject
|
||||
GLuint getStencilSize() const;
|
||||
|
||||
private:
|
||||
RenderbufferStorage *mStorage;
|
||||
};
|
||||
DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
|
||||
|
||||
// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
|
||||
// is called. The specific concrete type depends on whether the internal format is
|
||||
// colour depth, stencil or packed depth/stencil.
|
||||
class RenderbufferStorage
|
||||
{
|
||||
public:
|
||||
RenderbufferStorage();
|
||||
rx::RenderbufferImpl *mRenderbuffer;
|
||||
|
||||
virtual ~RenderbufferStorage() = 0;
|
||||
|
||||
virtual rx::RenderTarget *getRenderTarget();
|
||||
|
||||
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 bool isTexture() const;
|
||||
virtual unsigned int getTextureSerial() const;
|
||||
|
||||
static unsigned int issueSerials(unsigned int count);
|
||||
|
||||
protected:
|
||||
GLsizei mWidth;
|
||||
GLsizei mHeight;
|
||||
GLenum mInternalFormat;
|
||||
GLenum mActualFormat;
|
||||
GLsizei mSamples;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
|
||||
|
||||
const unsigned int mSerial;
|
||||
|
||||
static unsigned int mCurrentSerial;
|
||||
};
|
||||
|
||||
class Colorbuffer : public RenderbufferStorage
|
||||
{
|
||||
public:
|
||||
Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain);
|
||||
Colorbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples);
|
||||
|
||||
virtual ~Colorbuffer();
|
||||
|
||||
virtual rx::RenderTarget *getRenderTarget();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
|
||||
|
||||
rx::RenderTarget *mRenderTarget;
|
||||
};
|
||||
|
||||
class DepthStencilbuffer : public RenderbufferStorage
|
||||
{
|
||||
public:
|
||||
DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain);
|
||||
DepthStencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
|
||||
|
||||
~DepthStencilbuffer();
|
||||
|
||||
virtual rx::RenderTarget *getRenderTarget();
|
||||
|
||||
protected:
|
||||
rx::RenderTarget *mDepthStencil;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer);
|
||||
};
|
||||
|
||||
class Depthbuffer : public DepthStencilbuffer
|
||||
{
|
||||
public:
|
||||
Depthbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
|
||||
|
||||
virtual ~Depthbuffer();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
|
||||
};
|
||||
|
||||
class Stencilbuffer : public DepthStencilbuffer
|
||||
{
|
||||
public:
|
||||
Stencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
|
||||
|
||||
virtual ~Stencilbuffer();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Stencilbuffer);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -21,9 +21,9 @@
|
||||
namespace gl
|
||||
{
|
||||
ResourceManager::ResourceManager(rx::Renderer *renderer)
|
||||
: mRenderer(renderer),
|
||||
mRefCount(1)
|
||||
{
|
||||
mRefCount = 1;
|
||||
mRenderer = renderer;
|
||||
}
|
||||
|
||||
ResourceManager::~ResourceManager()
|
||||
@ -88,13 +88,13 @@ GLuint ResourceManager::createBuffer()
|
||||
}
|
||||
|
||||
// Returns an unused shader/program name
|
||||
GLuint ResourceManager::createShader(GLenum type)
|
||||
GLuint ResourceManager::createShader(const gl::Data &data, GLenum type)
|
||||
{
|
||||
GLuint handle = mProgramShaderHandleAllocator.allocate();
|
||||
|
||||
if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle);
|
||||
mShaderMap[handle] = new Shader(this, mRenderer->createShader(data, type), type, handle);
|
||||
}
|
||||
else UNREACHABLE();
|
||||
|
||||
@ -146,7 +146,7 @@ GLuint ResourceManager::createFenceSync()
|
||||
{
|
||||
GLuint handle = mFenceSyncHandleAllocator.allocate();
|
||||
|
||||
FenceSync *fenceSync = new FenceSync(mRenderer, handle);
|
||||
FenceSync *fenceSync = new FenceSync(mRenderer->createFenceSync(), handle);
|
||||
fenceSync->addRef();
|
||||
mFenceSyncMap[handle] = fenceSync;
|
||||
|
||||
@ -295,9 +295,9 @@ Texture *ResourceManager::getTexture(unsigned int handle)
|
||||
}
|
||||
}
|
||||
|
||||
Program *ResourceManager::getProgram(unsigned int handle)
|
||||
Program *ResourceManager::getProgram(unsigned int handle) const
|
||||
{
|
||||
ProgramMap::iterator program = mProgramMap.find(handle);
|
||||
ProgramMap::const_iterator program = mProgramMap.find(handle);
|
||||
|
||||
if (program == mProgramMap.end())
|
||||
{
|
||||
@ -403,7 +403,7 @@ void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
|
||||
{
|
||||
if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
|
||||
{
|
||||
Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
|
||||
Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer->createRenderbuffer(), renderbuffer);
|
||||
mRenderbufferMap[renderbuffer] = renderbufferObject;
|
||||
renderbufferObject->addRef();
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ class Texture;
|
||||
class Renderbuffer;
|
||||
class Sampler;
|
||||
class FenceSync;
|
||||
struct Data;
|
||||
|
||||
class ResourceManager
|
||||
{
|
||||
@ -43,7 +44,7 @@ class ResourceManager
|
||||
void release();
|
||||
|
||||
GLuint createBuffer();
|
||||
GLuint createShader(GLenum type);
|
||||
GLuint createShader(const gl::Data &data, GLenum type);
|
||||
GLuint createProgram();
|
||||
GLuint createTexture();
|
||||
GLuint createRenderbuffer();
|
||||
@ -60,7 +61,7 @@ class ResourceManager
|
||||
|
||||
Buffer *getBuffer(GLuint handle);
|
||||
Shader *getShader(GLuint handle);
|
||||
Program *getProgram(GLuint handle);
|
||||
Program *getProgram(GLuint handle) const;
|
||||
Texture *getTexture(GLuint handle);
|
||||
Renderbuffer *getRenderbuffer(GLuint handle);
|
||||
Sampler *getSampler(GLuint handle);
|
||||
@ -78,8 +79,8 @@ class ResourceManager
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ResourceManager);
|
||||
|
||||
std::size_t mRefCount;
|
||||
rx::Renderer *mRenderer;
|
||||
std::size_t mRefCount;
|
||||
|
||||
typedef std::unordered_map<GLuint, Buffer*> BufferMap;
|
||||
BufferMap mBufferMap;
|
||||
|
10
src/3rdparty/angle/src/libGLESv2/Shader.cpp
vendored
10
src/3rdparty/angle/src/libGLESv2/Shader.cpp
vendored
@ -118,9 +118,15 @@ void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
|
||||
getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
|
||||
}
|
||||
|
||||
void Shader::compile()
|
||||
void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const
|
||||
{
|
||||
mCompiled = mShader->compile(mSource);
|
||||
std::string debugInfo(mShader->getDebugInfo());
|
||||
getSourceImpl(debugInfo, bufSize, length, buffer);
|
||||
}
|
||||
|
||||
void Shader::compile(const gl::Data &data)
|
||||
{
|
||||
mCompiled = mShader->compile(data, mSource);
|
||||
}
|
||||
|
||||
void Shader::addRef()
|
||||
|
4
src/3rdparty/angle/src/libGLESv2/Shader.h
vendored
4
src/3rdparty/angle/src/libGLESv2/Shader.h
vendored
@ -31,6 +31,7 @@ class ShaderImpl;
|
||||
namespace gl
|
||||
{
|
||||
class ResourceManager;
|
||||
struct Data;
|
||||
|
||||
struct PackedVarying : public sh::Varying
|
||||
{
|
||||
@ -73,8 +74,9 @@ class Shader
|
||||
void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
|
||||
int getTranslatedSourceLength() const;
|
||||
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
|
||||
void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const;
|
||||
|
||||
void compile();
|
||||
void compile(const gl::Data &data);
|
||||
bool isCompiled() const { return mCompiled; }
|
||||
|
||||
void addRef();
|
||||
|
125
src/3rdparty/angle/src/libGLESv2/State.cpp
vendored
125
src/3rdparty/angle/src/libGLESv2/State.cpp
vendored
@ -10,18 +10,20 @@
|
||||
|
||||
#include "libGLESv2/Context.h"
|
||||
#include "libGLESv2/Caps.h"
|
||||
#include "libGLESv2/VertexArray.h"
|
||||
#include "libGLESv2/Query.h"
|
||||
#include "libGLESv2/Framebuffer.h"
|
||||
#include "libGLESv2/FramebufferAttachment.h"
|
||||
#include "libGLESv2/renderer/RenderTarget.h"
|
||||
#include "libGLESv2/Query.h"
|
||||
#include "libGLESv2/VertexArray.h"
|
||||
#include "libGLESv2/formatutils.h"
|
||||
#include "libGLESv2/renderer/RenderTarget.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
State::State()
|
||||
{
|
||||
mMaxDrawBuffers = 0;
|
||||
mMaxCombinedTextureImageUnits = 0;
|
||||
}
|
||||
|
||||
State::~State()
|
||||
@ -31,7 +33,8 @@ State::~State()
|
||||
|
||||
void State::initialize(const Caps& caps, GLuint clientVersion)
|
||||
{
|
||||
mContext = NULL;
|
||||
mMaxDrawBuffers = caps.maxDrawBuffers;
|
||||
mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
|
||||
|
||||
setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
@ -111,11 +114,15 @@ void State::initialize(const Caps& caps, GLuint clientVersion)
|
||||
mActiveSampler = 0;
|
||||
|
||||
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
|
||||
mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
|
||||
for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex)
|
||||
{
|
||||
mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
|
||||
}
|
||||
|
||||
mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
|
||||
mTransformFeedbackBuffers.resize(caps.maxTransformFeedbackSeparateAttributes);
|
||||
|
||||
mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
|
||||
mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
|
||||
if (clientVersion >= 3)
|
||||
@ -153,12 +160,6 @@ void State::reset()
|
||||
mSamplers[samplerIdx].set(NULL);
|
||||
}
|
||||
|
||||
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
|
||||
{
|
||||
mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
|
||||
}
|
||||
|
||||
mArrayBuffer.set(NULL);
|
||||
mRenderbuffer.set(NULL);
|
||||
|
||||
@ -170,15 +171,15 @@ void State::reset()
|
||||
}
|
||||
|
||||
mGenericUniformBuffer.set(NULL);
|
||||
for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
|
||||
mGenericTransformFeedbackBuffer.set(NULL);
|
||||
for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
|
||||
{
|
||||
mUniformBuffers[i].set(NULL);
|
||||
bufItr->set(NULL);
|
||||
}
|
||||
|
||||
mGenericTransformFeedbackBuffer.set(NULL);
|
||||
for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
|
||||
for (BufferVector::iterator bufItr = mTransformFeedbackBuffers.begin(); bufItr != mTransformFeedbackBuffers.end(); ++bufItr)
|
||||
{
|
||||
mTransformFeedbackBuffers[i].set(NULL);
|
||||
bufItr->set(NULL);
|
||||
}
|
||||
|
||||
mCopyReadBuffer.set(NULL);
|
||||
@ -485,7 +486,7 @@ void State::setSampleCoverageParams(GLclampf value, bool invert)
|
||||
mSampleCoverageInvert = invert;
|
||||
}
|
||||
|
||||
void State::getSampleCoverageParams(GLclampf *value, bool *invert)
|
||||
void State::getSampleCoverageParams(GLclampf *value, bool *invert) const
|
||||
{
|
||||
ASSERT(value != NULL && invert != NULL);
|
||||
|
||||
@ -612,14 +613,7 @@ void State::setSamplerTexture(GLenum type, Texture *texture)
|
||||
|
||||
Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
|
||||
{
|
||||
const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler];
|
||||
|
||||
if (binding.id() == 0) // Special case: 0 refers to default textures held by Context
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return binding.get();
|
||||
return mSamplerTextures.at(type)[sampler].get();
|
||||
}
|
||||
|
||||
GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
|
||||
@ -627,7 +621,7 @@ GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
|
||||
return mSamplerTextures.at(type)[sampler].id();
|
||||
}
|
||||
|
||||
void State::detachTexture(GLuint texture)
|
||||
void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
|
||||
{
|
||||
// Textures have a detach method on State rather than a simple
|
||||
// removeBinding, because the zero/null texture objects are managed
|
||||
@ -640,13 +634,15 @@ void State::detachTexture(GLuint texture)
|
||||
|
||||
for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
|
||||
{
|
||||
GLenum textureType = bindingVec->first;
|
||||
TextureBindingVector &textureVector = bindingVec->second;
|
||||
for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
|
||||
{
|
||||
BindingPointer<Texture> &binding = textureVector[textureIdx];
|
||||
if (binding.id() == texture)
|
||||
{
|
||||
binding.set(NULL);
|
||||
// Zero textures are the "default" textures instead of NULL
|
||||
binding.set(zeroTextures.at(textureType).get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -667,6 +663,19 @@ void State::detachTexture(GLuint texture)
|
||||
}
|
||||
}
|
||||
|
||||
void State::initializeZeroTextures(const TextureMap &zeroTextures)
|
||||
{
|
||||
for (TextureMap::const_iterator i = zeroTextures.begin(); i != zeroTextures.end(); i++)
|
||||
{
|
||||
TextureBindingVector &samplerTextureArray = mSamplerTextures[i->first];
|
||||
|
||||
for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
|
||||
{
|
||||
samplerTextureArray[textureUnit].set(i->second.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
|
||||
{
|
||||
mSamplers[textureUnit].set(sampler);
|
||||
@ -947,14 +956,14 @@ void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintpt
|
||||
|
||||
GLuint State::getIndexedUniformBufferId(GLuint index) const
|
||||
{
|
||||
ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
|
||||
ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
|
||||
|
||||
return mUniformBuffers[index].id();
|
||||
}
|
||||
|
||||
Buffer *State::getIndexedUniformBuffer(GLuint index) const
|
||||
{
|
||||
ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
|
||||
ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
|
||||
|
||||
return mUniformBuffers[index].get();
|
||||
}
|
||||
@ -971,25 +980,30 @@ void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffe
|
||||
|
||||
GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
|
||||
{
|
||||
ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
|
||||
ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
|
||||
|
||||
return mTransformFeedbackBuffers[index].id();
|
||||
}
|
||||
|
||||
Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
|
||||
{
|
||||
ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
|
||||
ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
|
||||
|
||||
return mTransformFeedbackBuffers[index].get();
|
||||
}
|
||||
|
||||
GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
|
||||
{
|
||||
ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
|
||||
ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
|
||||
|
||||
return mTransformFeedbackBuffers[index].getOffset();
|
||||
}
|
||||
|
||||
size_t State::getTransformFeedbackBufferIndexRange() const
|
||||
{
|
||||
return mTransformFeedbackBuffers.size();
|
||||
}
|
||||
|
||||
void State::setCopyReadBufferBinding(Buffer *buffer)
|
||||
{
|
||||
mCopyReadBuffer.set(buffer);
|
||||
@ -1033,19 +1047,19 @@ void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
|
||||
|
||||
void State::setVertexAttribf(GLuint index, const GLfloat values[4])
|
||||
{
|
||||
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
|
||||
ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
|
||||
mVertexAttribCurrentValues[index].setFloatValues(values);
|
||||
}
|
||||
|
||||
void State::setVertexAttribu(GLuint index, const GLuint values[4])
|
||||
{
|
||||
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
|
||||
ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
|
||||
mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
|
||||
}
|
||||
|
||||
void State::setVertexAttribi(GLuint index, const GLint values[4])
|
||||
{
|
||||
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
|
||||
ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
|
||||
mVertexAttribCurrentValues[index].setIntValues(values);
|
||||
}
|
||||
|
||||
@ -1062,15 +1076,10 @@ const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
|
||||
|
||||
const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
|
||||
{
|
||||
ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
|
||||
ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
|
||||
return mVertexAttribCurrentValues[attribNum];
|
||||
}
|
||||
|
||||
const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const
|
||||
{
|
||||
return mVertexAttribCurrentValues;
|
||||
}
|
||||
|
||||
const void *State::getVertexAttribPointer(unsigned int attribNum) const
|
||||
{
|
||||
return getVertexArray()->getVertexAttribute(attribNum).pointer;
|
||||
@ -1180,12 +1189,12 @@ void State::getFloatv(GLenum pname, GLfloat *params)
|
||||
}
|
||||
}
|
||||
|
||||
void State::getIntegerv(GLenum pname, GLint *params)
|
||||
void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
|
||||
{
|
||||
if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
|
||||
{
|
||||
unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
|
||||
ASSERT(colorAttachment < mContext->getCaps().maxDrawBuffers);
|
||||
ASSERT(colorAttachment < mMaxDrawBuffers);
|
||||
Framebuffer *framebuffer = mDrawFramebuffer;
|
||||
*params = framebuffer->getDrawBufferState(colorAttachment);
|
||||
return;
|
||||
@ -1238,12 +1247,12 @@ void State::getIntegerv(GLenum pname, GLint *params)
|
||||
case GL_SAMPLES:
|
||||
{
|
||||
gl::Framebuffer *framebuffer = mDrawFramebuffer;
|
||||
if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
|
||||
if (framebuffer->completeness(data) == GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
switch (pname)
|
||||
{
|
||||
case GL_SAMPLE_BUFFERS:
|
||||
if (framebuffer->getSamples() != 0)
|
||||
if (framebuffer->getSamples(data) != 0)
|
||||
{
|
||||
*params = 1;
|
||||
}
|
||||
@ -1253,7 +1262,7 @@ void State::getIntegerv(GLenum pname, GLint *params)
|
||||
}
|
||||
break;
|
||||
case GL_SAMPLES:
|
||||
*params = framebuffer->getSamples();
|
||||
*params = framebuffer->getSamples(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1332,19 +1341,19 @@ void State::getIntegerv(GLenum pname, GLint *params)
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_BINDING_2D:
|
||||
ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
|
||||
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
|
||||
*params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
|
||||
break;
|
||||
case GL_TEXTURE_BINDING_CUBE_MAP:
|
||||
ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
|
||||
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
|
||||
*params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
|
||||
break;
|
||||
case GL_TEXTURE_BINDING_3D:
|
||||
ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits);
|
||||
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
|
||||
*params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
|
||||
break;
|
||||
case GL_TEXTURE_BINDING_2D_ARRAY:
|
||||
ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
|
||||
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
|
||||
*params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
|
||||
break;
|
||||
case GL_UNIFORM_BUFFER_BINDING:
|
||||
@ -1376,13 +1385,13 @@ bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
|
||||
switch (target)
|
||||
{
|
||||
case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
|
||||
if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
|
||||
if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
|
||||
{
|
||||
*data = mTransformFeedbackBuffers[index].id();
|
||||
}
|
||||
break;
|
||||
case GL_UNIFORM_BUFFER_BINDING:
|
||||
if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
|
||||
if (static_cast<size_t>(index) < mUniformBuffers.size())
|
||||
{
|
||||
*data = mUniformBuffers[index].id();
|
||||
}
|
||||
@ -1399,25 +1408,25 @@ bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
|
||||
switch (target)
|
||||
{
|
||||
case GL_TRANSFORM_FEEDBACK_BUFFER_START:
|
||||
if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
|
||||
if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
|
||||
{
|
||||
*data = mTransformFeedbackBuffers[index].getOffset();
|
||||
}
|
||||
break;
|
||||
case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
|
||||
if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
|
||||
if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
|
||||
{
|
||||
*data = mTransformFeedbackBuffers[index].getSize();
|
||||
}
|
||||
break;
|
||||
case GL_UNIFORM_BUFFER_START:
|
||||
if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
|
||||
if (static_cast<size_t>(index) < mUniformBuffers.size())
|
||||
{
|
||||
*data = mUniformBuffers[index].getOffset();
|
||||
}
|
||||
break;
|
||||
case GL_UNIFORM_BUFFER_SIZE:
|
||||
if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
|
||||
if (static_cast<size_t>(index) < mUniformBuffers.size())
|
||||
{
|
||||
*data = mUniformBuffers[index].getSize();
|
||||
}
|
||||
@ -1433,9 +1442,9 @@ bool State::hasMappedBuffer(GLenum target) const
|
||||
{
|
||||
if (target == GL_ARRAY_BUFFER)
|
||||
{
|
||||
for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
|
||||
for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
|
||||
{
|
||||
const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
|
||||
const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(attribIndex));
|
||||
gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
|
||||
if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
|
||||
{
|
||||
|
26
src/3rdparty/angle/src/libGLESv2/State.h
vendored
26
src/3rdparty/angle/src/libGLESv2/State.h
vendored
@ -25,6 +25,9 @@ class Query;
|
||||
class VertexArray;
|
||||
class Context;
|
||||
struct Caps;
|
||||
struct Data;
|
||||
|
||||
typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
|
||||
|
||||
class State
|
||||
{
|
||||
@ -35,8 +38,6 @@ class State
|
||||
void initialize(const Caps& caps, GLuint clientVersion);
|
||||
void reset();
|
||||
|
||||
void setContext(Context *context) { mContext = context; }
|
||||
|
||||
// State chunk getters
|
||||
const RasterizerState &getRasterizerState() const;
|
||||
const BlendState &getBlendState() const;
|
||||
@ -100,7 +101,7 @@ class State
|
||||
bool isSampleCoverageEnabled() const;
|
||||
void setSampleCoverage(bool enabled);
|
||||
void setSampleCoverageParams(GLclampf value, bool invert);
|
||||
void getSampleCoverageParams(GLclampf *value, bool *invert);
|
||||
void getSampleCoverageParams(GLclampf *value, bool *invert) const;
|
||||
|
||||
// Scissor test state toggle & query
|
||||
bool isScissorTestEnabled() const;
|
||||
@ -133,7 +134,8 @@ class State
|
||||
void setSamplerTexture(GLenum type, Texture *texture);
|
||||
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
|
||||
GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const;
|
||||
void detachTexture(GLuint texture);
|
||||
void detachTexture(const TextureMap &zeroTextures, GLuint texture);
|
||||
void initializeZeroTextures(const TextureMap &zeroTextures);
|
||||
|
||||
// Sampler object binding manipulation
|
||||
void setSamplerBinding(GLuint textureUnit, Sampler *sampler);
|
||||
@ -199,6 +201,7 @@ class State
|
||||
GLuint getIndexedTransformFeedbackBufferId(GLuint index) const;
|
||||
Buffer *getIndexedTransformFeedbackBuffer(GLuint index) const;
|
||||
GLuint getIndexedTransformFeedbackBufferOffset(GLuint index) const;
|
||||
size_t getTransformFeedbackBufferIndexRange() const;
|
||||
|
||||
// GL_COPY_[READ/WRITE]_BUFFER
|
||||
void setCopyReadBufferBinding(Buffer *buffer);
|
||||
@ -220,7 +223,6 @@ class State
|
||||
bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
|
||||
const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;
|
||||
const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const;
|
||||
const VertexAttribCurrentValueData *getVertexAttribCurrentValues() const;
|
||||
const void *getVertexAttribPointer(unsigned int attribNum) const;
|
||||
|
||||
// Pixel pack state manipulation
|
||||
@ -238,7 +240,7 @@ class State
|
||||
// State query functions
|
||||
void getBooleanv(GLenum pname, GLboolean *params);
|
||||
void getFloatv(GLenum pname, GLfloat *params);
|
||||
void getIntegerv(GLenum pname, GLint *params);
|
||||
void getIntegerv(const gl::Data &data, GLenum pname, GLint *params);
|
||||
bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data);
|
||||
bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data);
|
||||
|
||||
@ -247,7 +249,9 @@ class State
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(State);
|
||||
|
||||
Context *mContext;
|
||||
// Cached values from Context's caps
|
||||
GLuint mMaxDrawBuffers;
|
||||
GLuint mMaxCombinedTextureImageUnits;
|
||||
|
||||
ColorF mColorClearValue;
|
||||
GLclampf mDepthClearValue;
|
||||
@ -283,7 +287,8 @@ class State
|
||||
GLuint mCurrentProgramId;
|
||||
BindingPointer<ProgramBinary> mCurrentProgramBinary;
|
||||
|
||||
VertexAttribCurrentValueData mVertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib
|
||||
typedef std::vector<VertexAttribCurrentValueData> VertexAttribVector;
|
||||
VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib
|
||||
VertexArray *mVertexArray;
|
||||
|
||||
// Texture and sampler bindings
|
||||
@ -300,11 +305,12 @@ class State
|
||||
ActiveQueryMap mActiveQueries;
|
||||
|
||||
BindingPointer<Buffer> mGenericUniformBuffer;
|
||||
OffsetBindingPointer<Buffer> mUniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
|
||||
typedef std::vector< OffsetBindingPointer<Buffer> > BufferVector;
|
||||
BufferVector mUniformBuffers;
|
||||
|
||||
BindingPointer<TransformFeedback> mTransformFeedback;
|
||||
BindingPointer<Buffer> mGenericTransformFeedbackBuffer;
|
||||
OffsetBindingPointer<Buffer> mTransformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
|
||||
BufferVector mTransformFeedbackBuffers;
|
||||
|
||||
BindingPointer<Buffer> mCopyReadBuffer;
|
||||
BindingPointer<Buffer> mCopyWriteBuffer;
|
||||
|
199
src/3rdparty/angle/src/libGLESv2/Texture.cpp
vendored
199
src/3rdparty/angle/src/libGLESv2/Texture.cpp
vendored
@ -47,11 +47,14 @@ bool IsPointSampled(const gl::SamplerState &samplerState)
|
||||
return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
|
||||
}
|
||||
|
||||
unsigned int Texture::mCurrentTextureSerial = 1;
|
||||
|
||||
Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
|
||||
: RefCountObject(id),
|
||||
mTexture(impl),
|
||||
mTextureSerial(issueTextureSerial()),
|
||||
mUsage(GL_NONE),
|
||||
mImmutable(false),
|
||||
mImmutableLevelCount(0),
|
||||
mTarget(target)
|
||||
{
|
||||
}
|
||||
@ -72,16 +75,6 @@ void Texture::setUsage(GLenum usage)
|
||||
getImplementation()->setUsage(usage);
|
||||
}
|
||||
|
||||
void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler)
|
||||
{
|
||||
*sampler = mSamplerState;
|
||||
|
||||
// Offset the effective base level by the texture storage's top level
|
||||
rx::TextureStorage *texture = getNativeTexture();
|
||||
int topLevel = texture ? texture->getTopLevel() : 0;
|
||||
sampler->baseLevel = topLevel + mSamplerState.baseLevel;
|
||||
}
|
||||
|
||||
GLenum Texture::getUsage() const
|
||||
{
|
||||
return mUsage;
|
||||
@ -138,35 +131,35 @@ GLenum Texture::getActualFormat(const ImageIndex &index) const
|
||||
return image->getActualFormat();
|
||||
}
|
||||
|
||||
rx::TextureStorage *Texture::getNativeTexture()
|
||||
Error Texture::generateMipmaps()
|
||||
{
|
||||
return getImplementation()->getNativeTexture();
|
||||
return getImplementation()->generateMipmaps();
|
||||
}
|
||||
|
||||
void Texture::generateMipmaps()
|
||||
Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
|
||||
{
|
||||
getImplementation()->generateMipmaps();
|
||||
return mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
|
||||
}
|
||||
|
||||
void Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
|
||||
unsigned int Texture::getTextureSerial() const
|
||||
{
|
||||
getImplementation()->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
|
||||
return mTextureSerial;
|
||||
}
|
||||
|
||||
unsigned int Texture::getTextureSerial()
|
||||
unsigned int Texture::issueTextureSerial()
|
||||
{
|
||||
rx::TextureStorage *texture = getNativeTexture();
|
||||
return texture ? texture->getTextureSerial() : 0;
|
||||
return mCurrentTextureSerial++;
|
||||
}
|
||||
|
||||
bool Texture::isImmutable() const
|
||||
{
|
||||
return mImmutable;
|
||||
return (mImmutableLevelCount > 0);
|
||||
}
|
||||
|
||||
int Texture::immutableLevelCount()
|
||||
{
|
||||
return (mImmutable ? getNativeTexture()->getLevelCount() : 0);
|
||||
return mImmutableLevelCount;
|
||||
}
|
||||
|
||||
int Texture::mipLevels() const
|
||||
@ -226,11 +219,11 @@ GLenum Texture2D::getActualFormat(GLint level) const
|
||||
return GL_NONE;
|
||||
}
|
||||
|
||||
void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
Error Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
releaseTexImage();
|
||||
|
||||
mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
|
||||
return mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture2D::bindTexImage(egl::Surface *surface)
|
||||
@ -254,35 +247,44 @@ void Texture2D::releaseTexImage()
|
||||
}
|
||||
}
|
||||
|
||||
void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
|
||||
Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize,
|
||||
const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
releaseTexImage();
|
||||
|
||||
mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels);
|
||||
return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
Error Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
|
||||
return mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
|
||||
Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
|
||||
GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
|
||||
return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
|
||||
Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
Framebuffer *source)
|
||||
{
|
||||
releaseTexImage();
|
||||
|
||||
mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
|
||||
return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
|
||||
}
|
||||
|
||||
void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
|
||||
Error Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
|
||||
{
|
||||
mImmutable = true;
|
||||
Error error = mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
|
||||
mImmutableLevelCount = levels;
|
||||
|
||||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
|
||||
@ -359,11 +361,11 @@ bool Texture2D::isDepth(GLint level) const
|
||||
return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
|
||||
}
|
||||
|
||||
void Texture2D::generateMipmaps()
|
||||
Error Texture2D::generateMipmaps()
|
||||
{
|
||||
releaseTexImage();
|
||||
|
||||
mTexture->generateMipmaps();
|
||||
return mTexture->generateMipmaps();
|
||||
}
|
||||
|
||||
// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
|
||||
@ -467,49 +469,27 @@ GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
|
||||
return GL_NONE;
|
||||
}
|
||||
|
||||
void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
Error TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
|
||||
return mTexture->setImage(target, level, width, height, 1, internalFormat, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height,
|
||||
GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
|
||||
return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, unpack, pixels);
|
||||
}
|
||||
|
||||
void TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
Error TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
|
||||
return mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
Error TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height, GLenum format,
|
||||
GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
|
||||
{
|
||||
mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels);
|
||||
}
|
||||
|
||||
void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
|
||||
{
|
||||
mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
|
||||
return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
|
||||
}
|
||||
|
||||
// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
|
||||
@ -549,16 +529,23 @@ bool TextureCubeMap::isDepth(GLenum target, GLint level) const
|
||||
return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
|
||||
}
|
||||
|
||||
void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
|
||||
Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height, Framebuffer *source)
|
||||
{
|
||||
mTexture->copyImage(target, level, format, x, y, width, height, source);
|
||||
return mTexture->copyImage(target, level, format, x, y, width, height, source);
|
||||
}
|
||||
|
||||
void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
|
||||
Error TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
|
||||
{
|
||||
mImmutable = true;
|
||||
Error error = mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
|
||||
mImmutableLevelCount = levels;
|
||||
|
||||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
// Tests for texture sampling completeness
|
||||
@ -734,31 +721,40 @@ bool Texture3D::isDepth(GLint level) const
|
||||
return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
|
||||
}
|
||||
|
||||
void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
Error Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels);
|
||||
return mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
|
||||
Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels);
|
||||
return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
Error Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
|
||||
return mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
|
||||
Error Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth, GLenum format,
|
||||
GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
|
||||
return mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
|
||||
Error Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
|
||||
{
|
||||
mImmutable = true;
|
||||
Error error = mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
|
||||
mImmutableLevelCount = levels;
|
||||
|
||||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
|
||||
@ -892,31 +888,40 @@ bool Texture2DArray::isDepth(GLint level) const
|
||||
return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
|
||||
}
|
||||
|
||||
void Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
Error Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels);
|
||||
return mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
|
||||
Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels);
|
||||
return mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
Error Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
|
||||
return mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
|
||||
Error Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth, GLenum format,
|
||||
GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
|
||||
{
|
||||
mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
|
||||
return mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
|
||||
}
|
||||
|
||||
void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
|
||||
Error Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
|
||||
{
|
||||
mImmutable = true;
|
||||
Error error = mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
|
||||
mImmutableLevelCount = levels;
|
||||
|
||||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
|
||||
|
74
src/3rdparty/angle/src/libGLESv2/Texture.h
vendored
74
src/3rdparty/angle/src/libGLESv2/Texture.h
vendored
@ -14,7 +14,7 @@
|
||||
#include "common/debug.h"
|
||||
#include "common/RefCountObject.h"
|
||||
#include "libGLESv2/angletypes.h"
|
||||
#include "libGLESv2/constants.h"
|
||||
#include "libGLESv2/Constants.h"
|
||||
#include "libGLESv2/renderer/TextureImpl.h"
|
||||
#include "libGLESv2/Caps.h"
|
||||
|
||||
@ -52,7 +52,6 @@ class Texture : public RefCountObject
|
||||
|
||||
const SamplerState &getSamplerState() const { return mSamplerState; }
|
||||
SamplerState &getSamplerState() { return mSamplerState; }
|
||||
void getSamplerStateWithNativeOffset(SamplerState *sampler);
|
||||
|
||||
void setUsage(GLenum usage);
|
||||
GLenum getUsage() const;
|
||||
@ -69,15 +68,16 @@ class Texture : public RefCountObject
|
||||
|
||||
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const = 0;
|
||||
|
||||
rx::TextureStorage *getNativeTexture();
|
||||
virtual Error generateMipmaps();
|
||||
|
||||
virtual void generateMipmaps();
|
||||
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
|
||||
virtual Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
|
||||
|
||||
unsigned int getTextureSerial();
|
||||
// Texture serials provide a unique way of identifying a Texture that isn't a raw pointer.
|
||||
// "id" is not good enough, as Textures can be deleted, then re-allocated with the same id.
|
||||
unsigned int getTextureSerial() const;
|
||||
|
||||
bool isImmutable() const;
|
||||
int immutableLevelCount();
|
||||
GLsizei immutableLevelCount();
|
||||
|
||||
rx::TextureImpl *getImplementation() { return mTexture; }
|
||||
const rx::TextureImpl *getImplementation() const { return mTexture; }
|
||||
@ -86,17 +86,20 @@ class Texture : public RefCountObject
|
||||
|
||||
protected:
|
||||
int mipLevels() const;
|
||||
const rx::Image *getBaseLevelImage() const;
|
||||
static unsigned int issueTextureSerial();
|
||||
|
||||
rx::TextureImpl *mTexture;
|
||||
|
||||
SamplerState mSamplerState;
|
||||
GLenum mUsage;
|
||||
|
||||
bool mImmutable;
|
||||
GLsizei mImmutableLevelCount;
|
||||
|
||||
GLenum mTarget;
|
||||
|
||||
const rx::Image *getBaseLevelImage() const;
|
||||
const unsigned int mTextureSerial;
|
||||
static unsigned int mCurrentTextureSerial;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Texture);
|
||||
@ -116,18 +119,18 @@ class Texture2D : public Texture
|
||||
bool isCompressed(GLint level) const;
|
||||
bool isDepth(GLint level) const;
|
||||
|
||||
void setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
|
||||
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
|
||||
void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
|
||||
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
Error setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
|
||||
Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
|
||||
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
|
||||
virtual void bindTexImage(egl::Surface *surface);
|
||||
virtual void releaseTexImage();
|
||||
|
||||
virtual void generateMipmaps();
|
||||
virtual Error generateMipmaps();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Texture2D);
|
||||
@ -152,19 +155,12 @@ class TextureCubeMap : public Texture
|
||||
bool isCompressed(GLenum target, GLint level) const;
|
||||
bool isDepth(GLenum target, GLint level) const;
|
||||
|
||||
void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
|
||||
void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
|
||||
|
||||
void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
|
||||
void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
|
||||
void storage(GLsizei levels, GLenum internalformat, GLsizei size);
|
||||
Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
|
||||
Error storage(GLsizei levels, GLenum internalformat, GLsizei size);
|
||||
|
||||
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
|
||||
|
||||
@ -195,11 +191,11 @@ class Texture3D : public Texture
|
||||
bool isCompressed(GLint level) const;
|
||||
bool isDepth(GLint level) const;
|
||||
|
||||
void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
|
||||
void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
|
||||
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
|
||||
Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
|
||||
|
||||
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
|
||||
|
||||
@ -225,11 +221,11 @@ class Texture2DArray : public Texture
|
||||
bool isCompressed(GLint level) const;
|
||||
bool isDepth(GLint level) const;
|
||||
|
||||
void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
|
||||
void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
|
||||
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
|
||||
Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
|
||||
Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
|
||||
|
||||
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user