Upgrade ANGLE to 2.1~99f075dade7c
This aligns with Chromium branch 2356. This version brings more complete OpenGL ES 3 support as well as various bug fixes and performance improvements. The following changes were made to earlier patches: -0000-General-fixes-for-ANGLE-2.1 Removed. All changes are now handled elsewhere. +0001-ANGLE-Improve-Windows-Phone-support Consolidated remaining parts from 0009/0010. +0002-ANGLE-Fix-compilation-with-MinGW Remaining issues from patch 0016. +0003-ANGLE-Fix-compilation-with-MSVC2010 Remaining issues from patch 0015. +0004-ANGLE-Dynamically-load-D3D-compiler-from-list Renamed from patch 0008. +0005-ANGLE-Add-support-for-querying-platform-device Renamed from patch 0013. -0004-Make-it-possible-to-link-ANGLE-statically-for-single Removed. Fixed by adding defines to project files. -0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t Renamed to patch 0005. -0009-ANGLE-Support-WinRT Removed. Mostly fixed upstream; remaining parts in patch 0001. -0010-ANGLE-Enable-D3D11-for-feature-level-9-cards Removed. Mostly fixed upstream; remaining parts in patch 0001. -0012-ANGLE-fix-semantic-index-lookup Removed. Fixed upstream. -0013-ANGLE-Add-support-for-querying-platform-device Renamed to patch 0005. -0014-Let-ANGLE-use-multithreaded-devices-if-necessary Removed. No longer needed. -0015-ANGLE-Fix-angle-d3d11-on-MSVC2010 Moved remaining parts to patch 0003. -0016-ANGLE-Fix-compilation-with-MinGW-D3D11 Moved remaining parts to patch 0002. -0017-ANGLE-Fix-compilation-with-D3D9 Removed. Fixed upstream. -0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11 Removed. Fixed upstream. -0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt Removed. Fixed upstream. -0020-ANGLE-Do-not-use-std-strlen Removed. Fixed upstream. -0020-ANGLE-Fix-compilation-with-MSVC2013-Update4 Removed. Fixed upstream. [ChangeLog][Third-party libraries] ANGLE was updated to Chromium branch 2356 (2.1~99f075dade7c). Change-Id: I32ccbfe95e10986bd94be7191dfd53445ea09158 Task-number: QTBUG-44815 Task-number: QTBUG-37660 Task-number: QTBUG-44694 Task-number: QTBUG-42443 Reviewed-by: Andrew Knight <qt@panimo.net> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
This commit is contained in:
parent
331ddacfca
commit
a218a252c4
@ -21,7 +21,7 @@ wince* {
|
||||
QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES2_RELEASE
|
||||
}
|
||||
DEFINES += QT_OPENGL_ES_2 QT_OPENGL_ES_2_ANGLE
|
||||
contains(QT_CONFIG, static): DEFINES += QT_OPENGL_ES_2_ANGLE_STATIC
|
||||
contains(QT_CONFIG, static): DEFINES += QT_OPENGL_ES_2_ANGLE_STATIC GL_APICALL= EGLAPI=
|
||||
QT_CONFIG -= opengl
|
||||
} else {
|
||||
!contains(QT_CONFIG, dynamicgl) {
|
||||
|
15
src/3rdparty/angle/.gitignore
vendored
15
src/3rdparty/angle/.gitignore
vendored
@ -6,19 +6,28 @@ build
|
||||
extensions
|
||||
samples
|
||||
tests
|
||||
third_party
|
||||
src/ipch
|
||||
util
|
||||
.svn
|
||||
|
||||
# Files from ANGLE we don't want/need
|
||||
DEPS
|
||||
*.chromium
|
||||
*.isolate
|
||||
*.md
|
||||
*.gn
|
||||
*.gyp
|
||||
*.gypi
|
||||
*.sh
|
||||
*.bat
|
||||
*.patch
|
||||
*.py
|
||||
*.rc
|
||||
*_unittest.cpp
|
||||
codereview.settings
|
||||
src/commit.h
|
||||
src/libANGLE/renderer/gl
|
||||
src/third_party/khronos/GL
|
||||
|
||||
# Generated by flex/bison
|
||||
src/compiler/preprocessor/Tokenizer.cpp
|
||||
@ -28,5 +37,5 @@ src/compiler/translator/glslang_tab.cpp
|
||||
src/compiler/translator/glslang_tab.h
|
||||
|
||||
# Generated by FXC
|
||||
src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/*.h
|
||||
src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/*.h
|
||||
src/libANGLE/renderer/d3d/d3d9/shaders/compiled/*.h
|
||||
src/libANGLE/renderer/d3d/d3d11/shaders/compiled/*.h
|
||||
|
6
src/3rdparty/angle/AUTHORS
vendored
6
src/3rdparty/angle/AUTHORS
vendored
@ -16,17 +16,22 @@ Autodesk, Inc.
|
||||
BlackBerry Limited
|
||||
Cable Television Laboratories, Inc.
|
||||
Cloud Party, Inc.
|
||||
Imagination Technologies Ltd.
|
||||
Intel Corporation
|
||||
Mozilla Corporation
|
||||
Turbulenz
|
||||
Klarälvdalens Datakonsult AB
|
||||
Microsoft Corporation
|
||||
Microsoft Open Technologies, Inc.
|
||||
NVIDIA Corporation
|
||||
Opera Software ASA
|
||||
The Qt Company Ltd.
|
||||
|
||||
Jacek Caban
|
||||
Mark Callow
|
||||
Ginn Chen
|
||||
Tibor den Ouden
|
||||
Régis Fénéon
|
||||
James Hauxwell
|
||||
Sam Hocevar
|
||||
Pierre Leveille
|
||||
@ -35,3 +40,4 @@ Boying Lu
|
||||
Aitor Moreno
|
||||
Yuri O'Donnell
|
||||
Josh Soref
|
||||
Maks Naumov
|
||||
|
21
src/3rdparty/angle/CONTRIBUTORS
vendored
21
src/3rdparty/angle/CONTRIBUTORS
vendored
@ -1,4 +1,4 @@
|
||||
# This is the official list of people who can contribute
|
||||
# This is the official list of people who can contribute
|
||||
# (and who have contributed) code to the ANGLE project
|
||||
# repository.
|
||||
# The AUTHORS file lists the copyright holders; this file
|
||||
@ -40,6 +40,7 @@ Google Inc.
|
||||
thestig@chromium.org
|
||||
Justin Schuh
|
||||
Scott Graham
|
||||
Corentin Wallez
|
||||
|
||||
Adobe Systems Inc.
|
||||
Alexandru Chiculita
|
||||
@ -55,6 +56,9 @@ Cloud Party, Inc.
|
||||
The Qt Company Ltd.
|
||||
Andrew Knight
|
||||
|
||||
Imagination Technologies Ltd.
|
||||
Gregoire Payen de La Garanderie
|
||||
|
||||
Intel Corporation
|
||||
Jin Yang
|
||||
Andy Chen
|
||||
@ -80,10 +84,21 @@ Mark Banner (standard8mbp)
|
||||
David Kilzer
|
||||
Jacek Caban
|
||||
Tibor den Ouden
|
||||
Régis Fénéon
|
||||
|
||||
Microsoft Corporation
|
||||
Cooper Partin
|
||||
Austin Kinross
|
||||
Minmin Gong
|
||||
|
||||
Microsoft Open Technologies, Inc.
|
||||
Cooper Partin
|
||||
Austin Kinross
|
||||
Cooper Partin
|
||||
Austin Kinross
|
||||
|
||||
NVIDIA Corporation
|
||||
Olli Etuaho
|
||||
Arun Patole
|
||||
Qingqing Deng
|
||||
|
||||
Opera Software ASA
|
||||
Daniel Bratell
|
||||
|
9
src/3rdparty/angle/include/EGL/egl.h
vendored
9
src/3rdparty/angle/include/EGL/egl.h
vendored
@ -33,12 +33,12 @@ extern "C" {
|
||||
** used to make the header, and the header can be found at
|
||||
** http://www.opengl.org/registry/
|
||||
**
|
||||
** Khronos $Revision: 27018 $ on $Date: 2014-06-10 08:06:12 -0700 (Tue, 10 Jun 2014) $
|
||||
** Khronos $Revision: 29318 $ on $Date: 2015-01-02 03:16:10 -0800 (Fri, 02 Jan 2015) $
|
||||
*/
|
||||
|
||||
#include <EGL/eglplatform.h>
|
||||
|
||||
/* Generated on date 20140610 */
|
||||
/* Generated on date 20150102 */
|
||||
|
||||
/* Generated C header for:
|
||||
* API: egl
|
||||
@ -240,6 +240,7 @@ EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
|
||||
typedef void *EGLSync;
|
||||
typedef intptr_t EGLAttrib;
|
||||
typedef khronos_utime_nanoseconds_t EGLTime;
|
||||
typedef void *EGLImage;
|
||||
#define EGL_CONTEXT_MAJOR_VERSION 0x3098
|
||||
#define EGL_CONTEXT_MINOR_VERSION 0x30FB
|
||||
#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
|
||||
@ -281,10 +282,14 @@ typedef khronos_utime_nanoseconds_t EGLTime;
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
|
||||
#define EGL_IMAGE_PRESERVED 0x30D2
|
||||
#define EGL_NO_IMAGE ((EGLImage)0)
|
||||
EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
|
||||
EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
|
||||
EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image);
|
||||
EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
|
||||
|
24
src/3rdparty/angle/include/EGL/eglext.h
vendored
24
src/3rdparty/angle/include/EGL/eglext.h
vendored
@ -440,24 +440,28 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle
|
||||
#define EGL_ANGLE_platform_angle 1
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
|
||||
#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
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
|
||||
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
|
||||
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206
|
||||
#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 0x3206
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207
|
||||
#define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
|
||||
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
|
||||
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A
|
||||
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B
|
||||
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C
|
||||
#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
|
||||
#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 0x3209
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320A
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
|
||||
#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
@ -73,15 +73,14 @@
|
||||
#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;
|
||||
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) /* Windows Desktop */
|
||||
typedef HWND EGLNativeWindowType;
|
||||
#else /* Windows Store */
|
||||
#include <inspectable.h>
|
||||
typedef IInspectable* EGLNativeWindowType;
|
||||
#endif
|
||||
|
||||
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
|
||||
@ -110,6 +109,14 @@ typedef Display *EGLNativeDisplayType;
|
||||
typedef Pixmap EGLNativePixmapType;
|
||||
typedef Window EGLNativeWindowType;
|
||||
|
||||
#elif defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) )
|
||||
|
||||
// TODO(jmadill): native implementation for OSX
|
||||
|
||||
typedef void *EGLNativeDisplayType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
typedef void *EGLNativeWindowType;
|
||||
|
||||
#else
|
||||
#error "Platform not recognized"
|
||||
#endif
|
||||
|
30
src/3rdparty/angle/include/GLSLANG/ShaderLang.h
vendored
30
src/3rdparty/angle/include/GLSLANG/ShaderLang.h
vendored
@ -3,8 +3,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
#ifndef _COMPILER_INTERFACE_INCLUDED_
|
||||
#define _COMPILER_INTERFACE_INCLUDED_
|
||||
#ifndef GLSLANG_SHADERLANG_H_
|
||||
#define GLSLANG_SHADERLANG_H_
|
||||
|
||||
#if defined(COMPONENT_BUILD) && !defined(ANGLE_TRANSLATOR_STATIC)
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
@ -48,7 +48,7 @@ typedef unsigned int GLenum;
|
||||
|
||||
// Version number for shader translation API.
|
||||
// It is incremented every time the API changes.
|
||||
#define ANGLE_SH_VERSION 132
|
||||
#define ANGLE_SH_VERSION 134
|
||||
|
||||
typedef enum {
|
||||
SH_GLES2_SPEC = 0x8B40,
|
||||
@ -81,11 +81,16 @@ typedef enum {
|
||||
} ShShaderSpec;
|
||||
|
||||
typedef enum {
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
SH_GLSL_OUTPUT = 0x8B46,
|
||||
SH_HLSL_OUTPUT = 0x8B47,
|
||||
SH_HLSL9_OUTPUT = 0x8B47,
|
||||
SH_HLSL11_OUTPUT = 0x8B48
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
// SH_GLSL_OUTPUT is deprecated. This is to not break the build.
|
||||
SH_GLSL_OUTPUT = 0x8B46,
|
||||
SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46,
|
||||
SH_GLSL_CORE_OUTPUT = 0x8B47,
|
||||
|
||||
// HLSL output only supported in some configurations.
|
||||
SH_HLSL_OUTPUT = 0x8B48,
|
||||
SH_HLSL9_OUTPUT = 0x8B48,
|
||||
SH_HLSL11_OUTPUT = 0x8B49
|
||||
} ShShaderOutput;
|
||||
|
||||
// Compile options.
|
||||
@ -223,6 +228,10 @@ typedef struct
|
||||
int EXT_draw_buffers;
|
||||
int EXT_frag_depth;
|
||||
int EXT_shader_texture_lod;
|
||||
int WEBGL_debug_shader_precision;
|
||||
int EXT_shader_framebuffer_fetch;
|
||||
int NV_shader_framebuffer_fetch;
|
||||
int ARM_shader_framebuffer_fetch;
|
||||
|
||||
// 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
|
||||
@ -290,7 +299,8 @@ COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle ha
|
||||
// spec: Specifies the language spec the compiler must conform to -
|
||||
// SH_GLES2_SPEC or SH_WEBGL_SPEC.
|
||||
// output: Specifies the output code type - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
|
||||
// SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT.
|
||||
// SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT. Note: HLSL output is only
|
||||
// supported in some configurations.
|
||||
// resources: Specifies the built-in resources.
|
||||
COMPILER_EXPORT ShHandle ShConstructCompiler(
|
||||
sh::GLenum type,
|
||||
@ -408,4 +418,4 @@ COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
|
||||
const std::string &uniformName,
|
||||
unsigned int *indexOut);
|
||||
|
||||
#endif // _COMPILER_INTERFACE_INCLUDED_
|
||||
#endif // GLSLANG_SHADERLANG_H_
|
||||
|
@ -7,8 +7,8 @@
|
||||
// Types to represent GL variables (varyings, uniforms, etc)
|
||||
//
|
||||
|
||||
#ifndef _COMPILER_INTERFACE_VARIABLES_
|
||||
#define _COMPILER_INTERFACE_VARIABLES_
|
||||
#ifndef GLSLANG_SHADERVARS_H_
|
||||
#define GLSLANG_SHADERVARS_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -28,6 +28,9 @@ enum InterpolationType
|
||||
INTERPOLATION_FLAT
|
||||
};
|
||||
|
||||
// Validate link & SSO consistency of interpolation qualifiers
|
||||
COMPILER_EXPORT bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
|
||||
|
||||
// Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
|
||||
enum BlockLayoutType
|
||||
{
|
||||
@ -182,4 +185,4 @@ struct COMPILER_EXPORT InterfaceBlock
|
||||
|
||||
}
|
||||
|
||||
#endif // _COMPILER_INTERFACE_VARIABLES_
|
||||
#endif // GLSLANG_SHADERVARS_H_
|
||||
|
2
src/3rdparty/angle/include/KHR/khrplatform.h
vendored
Normal file → Executable file
2
src/3rdparty/angle/include/KHR/khrplatform.h
vendored
Normal file → Executable file
@ -97,7 +97,7 @@
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(__SCITECH_SNAP__) && !defined(QT_OPENGL_ES_2_ANGLE_STATIC)
|
||||
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
|
6
src/3rdparty/angle/include/angle_gl.h
vendored
6
src/3rdparty/angle/include/angle_gl.h
vendored
@ -7,8 +7,8 @@
|
||||
// Includes all necessary GL headers and definitions for ANGLE.
|
||||
//
|
||||
|
||||
#ifndef ANGLE_GL_H_
|
||||
#define ANGLE_GL_H_
|
||||
#ifndef ANGLEGL_H_
|
||||
#define ANGLEGL_H_
|
||||
|
||||
#include "GLES2/gl2.h"
|
||||
#include "GLES2/gl2ext.h"
|
||||
@ -20,4 +20,4 @@
|
||||
#define GL_SAMPLER_2D_RECT_ARB 0x8B63
|
||||
#endif
|
||||
|
||||
#endif // ANGLE_GL_H_
|
||||
#endif // ANGLEGL_H_
|
||||
|
28
src/3rdparty/angle/include/export.h
vendored
Normal file
28
src/3rdparty/angle/include/export.h
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// export.h : Defines ANGLE_EXPORT, a macro for exporting functions from the DLL
|
||||
|
||||
#ifndef LIBGLESV2_EXPORT_H_
|
||||
#define LIBGLESV2_EXPORT_H_
|
||||
|
||||
#if defined(_WIN32)
|
||||
# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION)
|
||||
# define ANGLE_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define ANGLE_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION)
|
||||
# define ANGLE_EXPORT __attribute__((visibility ("default")))
|
||||
# else
|
||||
# define ANGLE_EXPORT
|
||||
# endif
|
||||
#else
|
||||
# define ANGLE_EXPORT
|
||||
#endif
|
||||
|
||||
#endif // LIBGLESV2_EXPORT_H_
|
112
src/3rdparty/angle/include/platform/Platform.h
vendored
Normal file
112
src/3rdparty/angle/include/platform/Platform.h
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
//
|
||||
// Copyright (c) 2015 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.
|
||||
|
||||
// Platform.h: The public interface ANGLE exposes to the API layer, for
|
||||
// doing platform-specific tasks like gathering data, or for tracing.
|
||||
|
||||
#ifndef ANGLE_PLATFORM_H
|
||||
#define ANGLE_PLATFORM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../export.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
class Platform
|
||||
{
|
||||
public:
|
||||
|
||||
// Tracing --------
|
||||
|
||||
typedef uint64_t TraceEventHandle;
|
||||
|
||||
// Add a trace event to the platform tracing system. Depending on the actual
|
||||
// enabled state, this event may be recorded or dropped.
|
||||
// - phase specifies the type of event:
|
||||
// - BEGIN ('B'): Marks the beginning of a scoped event.
|
||||
// - END ('E'): Marks the end of a scoped event.
|
||||
// - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't
|
||||
// need a matching END event. Instead, at the end of the scope,
|
||||
// updateTraceEventDuration() must be called with the TraceEventHandle
|
||||
// returned from addTraceEvent().
|
||||
// - INSTANT ('I'): Standalone, instantaneous event.
|
||||
// - START ('S'): Marks the beginning of an asynchronous event (the end
|
||||
// event can occur in a different scope or thread). The id parameter is
|
||||
// used to match START/FINISH pairs.
|
||||
// - FINISH ('F'): Marks the end of an asynchronous event.
|
||||
// - COUNTER ('C'): Used to trace integer quantities that change over
|
||||
// time. The argument values are expected to be of type int.
|
||||
// - METADATA ('M'): Reserved for internal use.
|
||||
// - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag.
|
||||
// - name is the name of the event. Also used to match BEGIN/END and
|
||||
// START/FINISH pairs.
|
||||
// - id optionally allows events of the same name to be distinguished from
|
||||
// each other. For example, to trace the consutruction and destruction of
|
||||
// objects, specify the pointer as the id parameter.
|
||||
// - numArgs specifies the number of elements in argNames, argTypes, and
|
||||
// argValues.
|
||||
// - argNames is the array of argument names. Use long-lived literal strings
|
||||
// or specify the COPY flag.
|
||||
// - argTypes is the array of argument types:
|
||||
// - BOOL (1): bool
|
||||
// - UINT (2): unsigned long long
|
||||
// - INT (3): long long
|
||||
// - DOUBLE (4): double
|
||||
// - POINTER (5): void*
|
||||
// - STRING (6): char* (long-lived null-terminated char* string)
|
||||
// - COPY_STRING (7): char* (temporary null-terminated char* string)
|
||||
// - CONVERTABLE (8): WebConvertableToTraceFormat
|
||||
// - argValues is the array of argument values. Each value is the unsigned
|
||||
// long long member of a union of all supported types.
|
||||
// - flags can be 0 or one or more of the following, ORed together:
|
||||
// - COPY (0x1): treat all strings (name, argNames and argValues of type
|
||||
// string) as temporary so that they will be copied by addTraceEvent.
|
||||
// - HAS_ID (0x2): use the id argument to uniquely identify the event for
|
||||
// matching with other events of the same name.
|
||||
// - MANGLE_ID (0x4): specify this flag if the id parameter is the value
|
||||
// of a pointer.
|
||||
virtual TraceEventHandle addTraceEvent(char phase,
|
||||
const unsigned char *categoryEnabledFlag,
|
||||
const char *name,
|
||||
unsigned long long id,
|
||||
double timestamp,
|
||||
int numArgs,
|
||||
const char **argNames,
|
||||
const unsigned char *argTypes,
|
||||
const unsigned long long *argValues,
|
||||
unsigned char flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the duration field of a COMPLETE trace event.
|
||||
virtual void updateTraceEventDuration(const unsigned char* categoryEnabledFlag, const char* name, TraceEventHandle) { }
|
||||
|
||||
// Callbacks for reporting histogram data.
|
||||
// CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50 would do.
|
||||
virtual void histogramCustomCounts(const char* name, int sample, int min, int max, int bucketCount) { }
|
||||
// Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample value.
|
||||
virtual void histogramEnumeration(const char* name, int sample, int boundaryValue) { }
|
||||
// Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets.
|
||||
virtual void histogramSparse(const char* name, int sample) { }
|
||||
|
||||
protected:
|
||||
virtual ~Platform() { }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef void(*ANGLEPlatformInitializeFunc)(angle::Platform*);
|
||||
ANGLE_EXPORT void ANGLEPlatformInitialize(angle::Platform*);
|
||||
|
||||
typedef void (*ANGLEPlatformShutdownFunc)();
|
||||
ANGLE_EXPORT void ANGLEPlatformShutdown();
|
||||
|
||||
typedef angle::Platform *(*ANGLEPlatformCurrentFunc)();
|
||||
ANGLE_EXPORT angle::Platform *ANGLEPlatformCurrent();
|
||||
|
||||
#endif // ANGLE_PLATFORM_H
|
12
src/3rdparty/angle/src/commit.h
vendored
12
src/3rdparty/angle/src/commit.h
vendored
@ -1,12 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// commit.h:
|
||||
// This is a default commit hash header, when git is not available.
|
||||
//
|
||||
|
||||
#define ANGLE_COMMIT_HASH "30d6c255d238"
|
||||
#define ANGLE_COMMIT_HASH_SIZE 12
|
||||
#define ANGLE_COMMIT_DATE "2014-11-13 17:37:03 +0000"
|
@ -4,12 +4,13 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/MemoryBuffer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
@ -32,26 +33,31 @@ bool MemoryBuffer::resize(size_t size)
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mSize = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
||||
if (size == mSize)
|
||||
{
|
||||
uint8_t *newMemory = reinterpret_cast<uint8_t*>(malloc(sizeof(uint8_t) * size));
|
||||
if (newMemory == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mData)
|
||||
{
|
||||
// Copy the intersection of the old data and the new data
|
||||
std::copy(mData, mData + std::min(mSize, size), newMemory);
|
||||
free(mData);
|
||||
}
|
||||
|
||||
mData = newMemory;
|
||||
mSize = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Only reallocate if the size has changed.
|
||||
uint8_t *newMemory = reinterpret_cast<uint8_t*>(malloc(sizeof(uint8_t) * size));
|
||||
if (newMemory == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mData)
|
||||
{
|
||||
// Copy the intersection of the old data and the new data
|
||||
std::copy(mData, mData + std::min(mSize, size), newMemory);
|
||||
free(mData);
|
||||
}
|
||||
|
||||
mData = newMemory;
|
||||
mSize = size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -4,16 +4,18 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H_
|
||||
#define LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H_
|
||||
#ifndef COMMON_MEMORYBUFFER_H_
|
||||
#define COMMON_MEMORYBUFFER_H_
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
class MemoryBuffer
|
||||
class MemoryBuffer : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
MemoryBuffer();
|
||||
@ -33,4 +35,4 @@ class MemoryBuffer
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H
|
||||
#endif // COMMON_MEMORYBUFFER_H_
|
61
src/3rdparty/angle/src/common/Optional.h
vendored
Normal file
61
src/3rdparty/angle/src/common/Optional.h
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
//
|
||||
// Copyright (c) 2015 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.
|
||||
//
|
||||
// Optional.h:
|
||||
// Represents a type that may be invalid, similar to std::optional.
|
||||
//
|
||||
|
||||
#ifndef COMMON_OPTIONAL_H_
|
||||
#define COMMON_OPTIONAL_H_
|
||||
|
||||
template <class T>
|
||||
struct Optional
|
||||
{
|
||||
Optional()
|
||||
: mValid(false),
|
||||
mValue(T())
|
||||
{}
|
||||
|
||||
explicit Optional(const T &valueIn)
|
||||
: mValid(true),
|
||||
mValue(valueIn)
|
||||
{}
|
||||
|
||||
Optional(const Optional &other)
|
||||
: mValid(other.mValid),
|
||||
mValue(other.mValue)
|
||||
{}
|
||||
|
||||
Optional &operator=(const Optional &other)
|
||||
{
|
||||
this->mValid = other.mValid;
|
||||
this->mValue = other.mValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static Optional None()
|
||||
{
|
||||
return Optional();
|
||||
}
|
||||
|
||||
bool valid() const { return mValid; }
|
||||
const T &value() const { return mValue; }
|
||||
|
||||
bool operator==(const Optional &other) const
|
||||
{
|
||||
return ((mValid == other.mValid) && (!mValid || (mValue == other.mValue)));
|
||||
}
|
||||
|
||||
bool operator!=(const Optional &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
bool mValid;
|
||||
T mValue;
|
||||
};
|
||||
|
||||
#endif // COMMON_OPTIONAL_H_
|
95
src/3rdparty/angle/src/common/RefCountObject.h
vendored
95
src/3rdparty/angle/src/common/RefCountObject.h
vendored
@ -1,95 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2002-2010 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.
|
||||
//
|
||||
|
||||
// RefCountObject.h: Defines the gl::RefCountObject base class that provides
|
||||
// lifecycle support for GL objects using the traditional BindObject scheme, but
|
||||
// that need to be reference counted for correct cross-context deletion.
|
||||
// (Concretely, textures, buffers and renderbuffers.)
|
||||
|
||||
#ifndef COMMON_REFCOUNTOBJECT_H_
|
||||
#define COMMON_REFCOUNTOBJECT_H_
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include "angle_gl.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
class RefCountObject
|
||||
{
|
||||
public:
|
||||
explicit RefCountObject(GLuint id);
|
||||
virtual ~RefCountObject();
|
||||
|
||||
virtual void addRef() const;
|
||||
virtual void release() const;
|
||||
|
||||
GLuint id() const { return mId; }
|
||||
|
||||
private:
|
||||
GLuint mId;
|
||||
|
||||
mutable std::size_t mRefCount;
|
||||
};
|
||||
|
||||
class RefCountObjectBindingPointer
|
||||
{
|
||||
protected:
|
||||
RefCountObjectBindingPointer() : mObject(NULL) { }
|
||||
~RefCountObjectBindingPointer() { ASSERT(mObject == NULL); } // Objects have to be released before the resource manager is destroyed, so they must be explicitly cleaned up.
|
||||
|
||||
void set(RefCountObject *newObject);
|
||||
RefCountObject *get() const { return mObject; }
|
||||
|
||||
public:
|
||||
GLuint id() const { return (mObject != NULL) ? mObject->id() : 0; }
|
||||
bool operator!() const { return (get() == NULL); }
|
||||
|
||||
private:
|
||||
RefCountObject *mObject;
|
||||
};
|
||||
|
||||
template <class ObjectType>
|
||||
class BindingPointer : public RefCountObjectBindingPointer
|
||||
{
|
||||
public:
|
||||
void set(ObjectType *newObject) { RefCountObjectBindingPointer::set(newObject); }
|
||||
ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); }
|
||||
ObjectType *operator->() const { return get(); }
|
||||
};
|
||||
|
||||
template <class ObjectType>
|
||||
class OffsetBindingPointer : public RefCountObjectBindingPointer
|
||||
{
|
||||
public:
|
||||
OffsetBindingPointer() : mOffset(0), mSize(0) { }
|
||||
|
||||
void set(ObjectType *newObject)
|
||||
{
|
||||
RefCountObjectBindingPointer::set(newObject);
|
||||
mOffset = 0;
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
void set(ObjectType *newObject, GLintptr offset, GLsizeiptr size)
|
||||
{
|
||||
RefCountObjectBindingPointer::set(newObject);
|
||||
mOffset = offset;
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
GLintptr getOffset() const { return mOffset; }
|
||||
GLsizeiptr getSize() const { return mSize; }
|
||||
|
||||
ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); }
|
||||
ObjectType *operator->() const { return get(); }
|
||||
|
||||
private:
|
||||
GLintptr mOffset;
|
||||
GLsizeiptr mSize;
|
||||
};
|
||||
|
||||
#endif // COMMON_REFCOUNTOBJECT_H_
|
3
src/3rdparty/angle/src/common/angleutils.cpp
vendored
3
src/3rdparty/angle/src/common/angleutils.cpp
vendored
@ -5,7 +5,8 @@
|
||||
//
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "debug.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
|
35
src/3rdparty/angle/src/common/angleutils.h
vendored
35
src/3rdparty/angle/src/common/angleutils.h
vendored
@ -11,19 +11,31 @@
|
||||
|
||||
#include "common/platform.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <climits>
|
||||
#include <cstdarg>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#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
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName&); \
|
||||
void operator=(const TypeName&)
|
||||
// A helper class to disallow copy and assignment operators
|
||||
namespace angle
|
||||
{
|
||||
|
||||
class NonCopyable
|
||||
{
|
||||
#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
|
||||
public:
|
||||
NonCopyable() = default;
|
||||
~NonCopyable() = default;
|
||||
protected:
|
||||
NonCopyable(const NonCopyable&) = delete;
|
||||
void operator=(const NonCopyable&) = delete;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
inline size_t ArraySize(T(&)[N])
|
||||
@ -150,13 +162,12 @@ std::string FormatString(const char *fmt, ...);
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#define VENDOR_ID_AMD 0x1002
|
||||
#define VENDOR_ID_INTEL 0x8086
|
||||
#define VENDOR_ID_NVIDIA 0x10DE
|
||||
|
||||
#define GL_BGRA4_ANGLEX 0x6ABC
|
||||
#define GL_BGR5_A1_ANGLEX 0x6ABD
|
||||
#define GL_INT_64_ANGLEX 0x6ABE
|
||||
#define GL_STRUCT_ANGLEX 0x6ABF
|
||||
|
||||
// Hidden enum for the NULL D3D device type.
|
||||
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x6AC0
|
||||
|
||||
#endif // COMMON_ANGLEUTILS_H_
|
||||
|
267
src/3rdparty/angle/src/common/debug.cpp
vendored
267
src/3rdparty/angle/src/common/debug.cpp
vendored
@ -17,172 +17,9 @@
|
||||
|
||||
namespace gl
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
// Wraps the D3D9/D3D11 debug annotation functions.
|
||||
class DebugAnnotationWrapper
|
||||
|
||||
namespace
|
||||
{
|
||||
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
|
||||
|
||||
// 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,
|
||||
@ -190,29 +27,44 @@ enum DebugTraceOutputType
|
||||
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);
|
||||
DebugAnnotator *g_debugAnnotator = nullptr;
|
||||
|
||||
if (perfActive())
|
||||
void output(bool traceInDebugOnly, MessageType messageType, DebugTraceOutputType outputType,
|
||||
const char *format, va_list vararg)
|
||||
{
|
||||
if (DebugAnnotationsActive())
|
||||
{
|
||||
static std::vector<char> buffer(512);
|
||||
size_t len = FormatStringIntoVector(format, vararg, buffer);
|
||||
std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
|
||||
|
||||
ASSERT(g_debugAnnotator != nullptr);
|
||||
switch (outputType)
|
||||
{
|
||||
case DebugTraceOutputTypeNone:
|
||||
break;
|
||||
case DebugTraceOutputTypeBeginEvent:
|
||||
g_DebugAnnotationWrapper->beginEvent(formattedWideMessage);
|
||||
break;
|
||||
case DebugTraceOutputTypeSetMarker:
|
||||
g_DebugAnnotationWrapper->setMarker(formattedWideMessage);
|
||||
break;
|
||||
case DebugTraceOutputTypeNone:
|
||||
break;
|
||||
case DebugTraceOutputTypeBeginEvent:
|
||||
g_debugAnnotator->beginEvent(formattedWideMessage);
|
||||
break;
|
||||
case DebugTraceOutputTypeSetMarker:
|
||||
g_debugAnnotator->setMarker(formattedWideMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
|
||||
std::string formattedMessage;
|
||||
UNUSED_TRACE_VARIABLE(formattedMessage);
|
||||
|
||||
#if !defined(NDEBUG) && defined(_MSC_VER)
|
||||
if (messageType == MESSAGE_ERR)
|
||||
{
|
||||
if (formattedMessage.empty())
|
||||
{
|
||||
formattedMessage = FormatString(format, vararg);
|
||||
}
|
||||
OutputDebugStringA(formattedMessage.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
#if defined(NDEBUG)
|
||||
@ -221,7 +73,10 @@ static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const
|
||||
return;
|
||||
}
|
||||
#endif // NDEBUG
|
||||
std::string formattedMessage = FormatString(format, vararg);
|
||||
if (formattedMessage.empty())
|
||||
{
|
||||
formattedMessage = FormatString(format, vararg);
|
||||
}
|
||||
|
||||
static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
|
||||
if (file)
|
||||
@ -237,53 +92,57 @@ static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const
|
||||
#endif // ANGLE_ENABLE_DEBUG_TRACE
|
||||
}
|
||||
|
||||
void trace(bool traceInDebugOnly, const char *format, ...)
|
||||
{
|
||||
va_list vararg;
|
||||
va_start(vararg, format);
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
output(traceInDebugOnly, DebugTraceOutputTypeSetMarker, format, vararg);
|
||||
#else
|
||||
output(traceInDebugOnly, DebugTraceOutputTypeNone, format, vararg);
|
||||
#endif
|
||||
va_end(vararg);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool perfActive()
|
||||
bool DebugAnnotationsActive()
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
static bool active = g_DebugAnnotationWrapper->getStatus();
|
||||
return active;
|
||||
return g_debugAnnotator != nullptr && g_debugAnnotator->getStatus();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator)
|
||||
{
|
||||
UninitializeDebugAnnotations();
|
||||
g_debugAnnotator = debugAnnotator;
|
||||
}
|
||||
|
||||
void UninitializeDebugAnnotations()
|
||||
{
|
||||
// Pointer is not managed.
|
||||
g_debugAnnotator = nullptr;
|
||||
}
|
||||
|
||||
void trace(bool traceInDebugOnly, MessageType messageType, const char *format, ...)
|
||||
{
|
||||
va_list vararg;
|
||||
va_start(vararg, format);
|
||||
output(traceInDebugOnly, messageType, DebugTraceOutputTypeSetMarker, format, vararg);
|
||||
va_end(vararg);
|
||||
}
|
||||
|
||||
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
|
||||
{
|
||||
#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
if (!perfActive())
|
||||
if (!DebugAnnotationsActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif // !ANGLE_ENABLE_DEBUG_TRACE
|
||||
va_list vararg;
|
||||
va_start(vararg, format);
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
output(true, DebugTraceOutputTypeBeginEvent, format, vararg);
|
||||
#else
|
||||
output(true, DebugTraceOutputTypeNone, format, vararg);
|
||||
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
output(true, MESSAGE_EVENT, DebugTraceOutputTypeBeginEvent, format, vararg);
|
||||
va_end(vararg);
|
||||
}
|
||||
|
||||
ScopedPerfEventHelper::~ScopedPerfEventHelper()
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
if (perfActive())
|
||||
if (DebugAnnotationsActive())
|
||||
{
|
||||
g_DebugAnnotationWrapper->endEvent();
|
||||
g_debugAnnotator->endEvent();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
82
src/3rdparty/angle/src/common/debug.h
vendored
82
src/3rdparty/angle/src/common/debug.h
vendored
@ -9,8 +9,9 @@
|
||||
#ifndef COMMON_DEBUG_H_
|
||||
#define COMMON_DEBUG_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
@ -20,50 +21,71 @@
|
||||
|
||||
namespace gl
|
||||
{
|
||||
// Outputs text to the debugging log, or the debugging window
|
||||
void trace(bool traceInDebugOnly, const char *format, ...);
|
||||
|
||||
// Returns whether D3DPERF is active.
|
||||
bool perfActive();
|
||||
enum MessageType
|
||||
{
|
||||
MESSAGE_TRACE,
|
||||
MESSAGE_FIXME,
|
||||
MESSAGE_ERR,
|
||||
MESSAGE_EVENT,
|
||||
};
|
||||
|
||||
// Pairs a D3D begin event with an end event.
|
||||
class ScopedPerfEventHelper
|
||||
{
|
||||
public:
|
||||
ScopedPerfEventHelper(const char* format, ...);
|
||||
~ScopedPerfEventHelper();
|
||||
// Outputs text to the debugging log, or the debugging window
|
||||
void trace(bool traceInDebugOnly, MessageType messageType, const char *format, ...);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper);
|
||||
};
|
||||
// Pairs a D3D begin event with an end event.
|
||||
class ScopedPerfEventHelper : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
ScopedPerfEventHelper(const char* format, ...);
|
||||
~ScopedPerfEventHelper();
|
||||
};
|
||||
|
||||
// Wraps the D3D9/D3D11 debug annotation functions.
|
||||
class DebugAnnotator : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
DebugAnnotator() { };
|
||||
virtual ~DebugAnnotator() { };
|
||||
virtual void beginEvent(const std::wstring &eventName) = 0;
|
||||
virtual void endEvent() = 0;
|
||||
virtual void setMarker(const std::wstring &markerName) = 0;
|
||||
virtual bool getStatus() = 0;
|
||||
};
|
||||
|
||||
void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator);
|
||||
void UninitializeDebugAnnotations();
|
||||
bool DebugAnnotationsActive();
|
||||
|
||||
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_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#define TRACE(message, ...) gl::trace(true, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define ANGLE_TRACE_ENABLED
|
||||
#endif
|
||||
|
||||
// A macro to output a trace of a function call and its arguments to the debugging log
|
||||
#if defined(ANGLE_TRACE_ENABLED)
|
||||
#define TRACE(message, ...) gl::trace(true, gl::MESSAGE_TRACE, "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_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#if defined(ANGLE_TRACE_ENABLED)
|
||||
#define FIXME(message, ...) gl::trace(false, gl::MESSAGE_FIXME, "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_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#define ERR(message, ...) gl::trace(false, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#if defined(ANGLE_TRACE_ENABLED)
|
||||
#define ERR(message, ...) gl::trace(false, gl::MESSAGE_ERR, "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_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#if defined(ANGLE_TRACE_ENABLED)
|
||||
#if defined(_MSC_VER)
|
||||
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
|
||||
#else
|
||||
@ -73,6 +95,10 @@ namespace gl
|
||||
#define EVENT(message, ...) (void(0))
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_TRACE_ENABLED)
|
||||
#undef ANGLE_TRACE_ENABLED
|
||||
#endif
|
||||
|
||||
// A macro asserting a condition and outputting failures to the debug log
|
||||
#if !defined(NDEBUG)
|
||||
#define ASSERT(expression) do { \
|
||||
@ -130,14 +156,4 @@ namespace gl
|
||||
#define HAS_DYNAMIC_TYPE(type, obj) true
|
||||
#endif
|
||||
|
||||
// A macro functioning as a compile-time assert to validate constant conditions
|
||||
#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
|
||||
#define META_ASSERT_CONCAT2(a, b) META_ASSERT_CONCAT(a, b)
|
||||
#define META_ASSERT_MSG(condition, msg) typedef int META_ASSERT_CONCAT2(COMPILE_TIME_ASSERT_, __LINE__)[static_cast<bool>(condition)?1:-1]
|
||||
#endif
|
||||
#define META_ASSERT(condition) META_ASSERT_MSG(condition, "compile time assertion failed.")
|
||||
|
||||
#endif // COMMON_DEBUG_H_
|
||||
|
38
src/3rdparty/angle/src/common/event_tracer.cpp
vendored
Normal file
38
src/3rdparty/angle/src/common/event_tracer.cpp
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "common/event_tracer.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
GetCategoryEnabledFlagFunc g_getCategoryEnabledFlag;
|
||||
AddTraceEventFunc g_addTraceEvent;
|
||||
|
||||
} // namespace gl
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
const unsigned char* TraceGetTraceCategoryEnabledFlag(const char* name)
|
||||
{
|
||||
if (g_getCategoryEnabledFlag)
|
||||
{
|
||||
return g_getCategoryEnabledFlag(name);
|
||||
}
|
||||
static unsigned char disabled = 0;
|
||||
return &disabled;
|
||||
}
|
||||
|
||||
void TraceAddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, unsigned long long id,
|
||||
int numArgs, const char** argNames, const unsigned char* argTypes,
|
||||
const unsigned long long* argValues, unsigned char flags)
|
||||
{
|
||||
if (g_addTraceEvent)
|
||||
{
|
||||
g_addTraceEvent(phase, categoryGroupEnabled, name, id, numArgs, argNames, argTypes, argValues, flags);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gl
|
34
src/3rdparty/angle/src/common/event_tracer.h
vendored
Normal file
34
src/3rdparty/angle/src/common/event_tracer.h
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef COMMON_EVENT_TRACER_H_
|
||||
#define COMMON_EVENT_TRACER_H_
|
||||
|
||||
#include "common/platform.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
typedef const unsigned char* (*GetCategoryEnabledFlagFunc)(const char* name);
|
||||
typedef void (*AddTraceEventFunc)(char phase, const unsigned char* categoryGroupEnabled, const char* name,
|
||||
unsigned long long id, int numArgs, const char** argNames,
|
||||
const unsigned char* argTypes, const unsigned long long* argValues,
|
||||
unsigned char flags);
|
||||
|
||||
}
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
extern GetCategoryEnabledFlagFunc g_getCategoryEnabledFlag;
|
||||
extern AddTraceEventFunc g_addTraceEvent;
|
||||
|
||||
const unsigned char* TraceGetTraceCategoryEnabledFlag(const char* name);
|
||||
|
||||
void TraceAddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, unsigned long long id,
|
||||
int numArgs, const char** argNames, const unsigned char* argTypes,
|
||||
const unsigned long long* argValues, unsigned char flags);
|
||||
|
||||
}
|
||||
|
||||
#endif // COMMON_EVENT_TRACER_H_
|
61
src/3rdparty/angle/src/common/mathutil.h
vendored
61
src/3rdparty/angle/src/common/mathutil.h
vendored
@ -6,8 +6,8 @@
|
||||
|
||||
// mathutil.h: Math and bit manipulation functions.
|
||||
|
||||
#ifndef LIBGLESV2_MATHUTIL_H_
|
||||
#define LIBGLESV2_MATHUTIL_H_
|
||||
#ifndef COMMON_MATHUTIL_H_
|
||||
#define COMMON_MATHUTIL_H_
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/platform.h"
|
||||
@ -15,6 +15,7 @@
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -118,6 +119,9 @@ inline bool supportsSSE2()
|
||||
return supports;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
supports = __builtin_cpu_supports("sse2");
|
||||
#else
|
||||
int info[4];
|
||||
__cpuid(info, 0);
|
||||
|
||||
@ -127,6 +131,7 @@ inline bool supportsSSE2()
|
||||
|
||||
supports = (info[3] >> 26) & 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
checked = true;
|
||||
|
||||
@ -353,7 +358,7 @@ inline float float11ToFloat32(unsigned short fp11)
|
||||
}
|
||||
else // The value is zero
|
||||
{
|
||||
exponent = -112;
|
||||
exponent = static_cast<unsigned short>(-112);
|
||||
}
|
||||
|
||||
return bitCast<float>(((exponent + 112) << 23) | (mantissa << 17));
|
||||
@ -392,7 +397,7 @@ inline float float10ToFloat32(unsigned short fp11)
|
||||
}
|
||||
else // The value is zero
|
||||
{
|
||||
exponent = -112;
|
||||
exponent = static_cast<unsigned short>(-112);
|
||||
}
|
||||
|
||||
return bitCast<float>(((exponent + 112) << 23) | (mantissa << 18));
|
||||
@ -402,7 +407,7 @@ inline float float10ToFloat32(unsigned short fp11)
|
||||
template <typename T>
|
||||
inline float normalizedToFloat(T input)
|
||||
{
|
||||
META_ASSERT(std::numeric_limits<T>::is_integer);
|
||||
static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
|
||||
|
||||
const float inverseMax = 1.0f / std::numeric_limits<T>::max();
|
||||
return input * inverseMax;
|
||||
@ -411,8 +416,8 @@ inline float normalizedToFloat(T input)
|
||||
template <unsigned int inputBitCount, typename T>
|
||||
inline float normalizedToFloat(T input)
|
||||
{
|
||||
META_ASSERT(std::numeric_limits<T>::is_integer);
|
||||
META_ASSERT(inputBitCount < (sizeof(T) * 8));
|
||||
static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
|
||||
static_assert(inputBitCount < (sizeof(T) * 8), "T must have more bits than inputBitCount.");
|
||||
|
||||
const float inverseMax = 1.0f / ((1 << inputBitCount) - 1);
|
||||
return input * inverseMax;
|
||||
@ -427,14 +432,15 @@ inline T floatToNormalized(float input)
|
||||
template <unsigned int outputBitCount, typename T>
|
||||
inline T floatToNormalized(float input)
|
||||
{
|
||||
META_ASSERT(outputBitCount < (sizeof(T) * 8));
|
||||
static_assert(outputBitCount < (sizeof(T) * 8), "T must have more bits than outputBitCount.");
|
||||
return ((1 << outputBitCount) - 1) * input + 0.5f;
|
||||
}
|
||||
|
||||
template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
|
||||
inline T getShiftedData(T input)
|
||||
{
|
||||
META_ASSERT(inputBitCount + inputBitStart <= (sizeof(T) * 8));
|
||||
static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
|
||||
"T must have at least as many bits as inputBitCount + inputBitStart.");
|
||||
const T mask = (1 << inputBitCount) - 1;
|
||||
return (input >> inputBitStart) & mask;
|
||||
}
|
||||
@ -442,7 +448,8 @@ inline T getShiftedData(T input)
|
||||
template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
|
||||
inline T shiftData(T input)
|
||||
{
|
||||
META_ASSERT(inputBitCount + inputBitStart <= (sizeof(T) * 8));
|
||||
static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
|
||||
"T must have at least as many bits as inputBitCount + inputBitStart.");
|
||||
const T mask = (1 << inputBitCount) - 1;
|
||||
return (input & mask) << inputBitStart;
|
||||
}
|
||||
@ -503,6 +510,7 @@ inline unsigned int averageFloat10(unsigned int a, unsigned int b)
|
||||
namespace rx
|
||||
{
|
||||
|
||||
// Represents intervals of the type [a, b)
|
||||
template <typename T>
|
||||
struct Range
|
||||
{
|
||||
@ -513,6 +521,18 @@ struct Range
|
||||
T end;
|
||||
|
||||
T length() const { return end - start; }
|
||||
|
||||
bool intersects(Range<T> other)
|
||||
{
|
||||
if (start <= other.start)
|
||||
{
|
||||
return other.start < end;
|
||||
}
|
||||
else
|
||||
{
|
||||
return start < other.end;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef Range<int> RangeI;
|
||||
@ -533,14 +553,14 @@ inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
|
||||
template <class T>
|
||||
inline bool IsUnsignedAdditionSafe(T lhs, T rhs)
|
||||
{
|
||||
META_ASSERT(!std::numeric_limits<T>::is_signed);
|
||||
static_assert(!std::numeric_limits<T>::is_signed, "T must be unsigned.");
|
||||
return (rhs <= std::numeric_limits<T>::max() - lhs);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool IsUnsignedMultiplicationSafe(T lhs, T rhs)
|
||||
{
|
||||
META_ASSERT(!std::numeric_limits<T>::is_signed);
|
||||
static_assert(!std::numeric_limits<T>::is_signed, "T must be unsigned.");
|
||||
return (lhs == T(0) || rhs == T(0) || (rhs <= std::numeric_limits<T>::max() / lhs));
|
||||
}
|
||||
|
||||
@ -550,6 +570,21 @@ inline bool IsIntegerCastSafe(BigIntT bigValue)
|
||||
return (static_cast<BigIntT>(static_cast<SmallIntT>(bigValue)) == bigValue);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#define ANGLE_ROTL(x,y) _rotl(x,y)
|
||||
|
||||
#else
|
||||
|
||||
inline uint32_t RotL(uint32_t x, int8_t r)
|
||||
{
|
||||
return (x << r) | (x >> (32 - r));
|
||||
}
|
||||
|
||||
#endif // LIBGLESV2_MATHUTIL_H_
|
||||
#define ANGLE_ROTL(x,y) RotL(x,y)
|
||||
|
||||
#endif // namespace rx
|
||||
|
||||
}
|
||||
|
||||
#endif // COMMON_MATHUTIL_H_
|
||||
|
109
src/3rdparty/angle/src/common/platform.h
vendored
109
src/3rdparty/angle/src/common/platform.h
vendored
@ -14,12 +14,12 @@
|
||||
#elif defined(__APPLE__)
|
||||
# define ANGLE_PLATFORM_APPLE 1
|
||||
# define ANGLE_PLATFORM_POSIX 1
|
||||
#elif defined(__linux__)
|
||||
# define ANGLE_PLATFORM_LINUX 1
|
||||
# define ANGLE_PLATFORM_POSIX 1
|
||||
#elif defined(ANDROID)
|
||||
# define ANGLE_PLATFORM_ANDROID 1
|
||||
# define ANGLE_PLATFORM_POSIX 1
|
||||
#elif defined(__linux__) || defined(EMSCRIPTEN)
|
||||
# define ANGLE_PLATFORM_LINUX 1
|
||||
# define ANGLE_PLATFORM_POSIX 1
|
||||
#elif defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__NetBSD__) || \
|
||||
@ -34,9 +34,6 @@
|
||||
#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,24 +47,32 @@
|
||||
# include <windows.h>
|
||||
# include <intrin.h>
|
||||
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
|
||||
# define ANGLE_ENABLE_WINDOWS_STORE 1
|
||||
# endif
|
||||
|
||||
# if defined(ANGLE_ENABLE_D3D9)
|
||||
# include <d3d9.h>
|
||||
# include <dxgi.h>
|
||||
# if !defined(COMPILER_IMPLEMENTATION)
|
||||
# if !defined(ANGLE_TRANSLATOR_IMPLEMENTATION)
|
||||
# include <d3dcompiler.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(ANGLE_ENABLE_D3D11)
|
||||
# include <d3d10_1.h>
|
||||
# include <d3d10.h>
|
||||
# include <d3d11.h>
|
||||
# include <dxgi.h>
|
||||
# if defined(_MSC_VER) && (_MSC_VER >= 1700)
|
||||
# if defined(__MINGW32__) && !defined(__d3d11sdklayers_h__)
|
||||
# define ANGLE_MINGW32_COMPAT
|
||||
# endif
|
||||
# if defined(_MSC_VER) && _MSC_VER >= 1800
|
||||
# define ANGLE_ENABLE_D3D11_1
|
||||
# endif
|
||||
# if defined(ANGLE_ENABLE_D3D11_1)
|
||||
# include <d3d11_1.h>
|
||||
# include <dxgi1_2.h>
|
||||
# endif
|
||||
# if !defined(COMPILER_IMPLEMENTATION)
|
||||
# if !defined(ANGLE_TRANSLATOR_IMPLEMENTATION)
|
||||
# include <d3dcompiler.h>
|
||||
# endif
|
||||
# endif
|
||||
@ -75,88 +80,24 @@
|
||||
# if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
# include <dxgi1_3.h>
|
||||
# if defined(_DEBUG)
|
||||
# if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
|
||||
# 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
|
||||
} D3D11_MAP_FLAG;
|
||||
typedef struct D3D11_QUERY_DATA_SO_STATISTICS
|
||||
{
|
||||
UINT64 NumPrimitivesWritten;
|
||||
UINT64 PrimitivesStorageNeeded;
|
||||
} D3D11_QUERY_DATA_SO_STATISTICS;
|
||||
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__
|
||||
# if defined(_MSC_VER) && (_MSC_VER <= 1600)
|
||||
# define final
|
||||
# define override
|
||||
# endif
|
||||
|
||||
# undef near
|
||||
# undef far
|
||||
#endif
|
||||
|
||||
#if !defined(_M_ARM) && !defined(ANGLE_PLATFORM_ANDROID)
|
||||
# define ANGLE_USE_SSE
|
||||
#endif
|
||||
|
||||
#endif // COMMON_PLATFORM_H_
|
||||
|
4
src/3rdparty/angle/src/common/tls.h
vendored
4
src/3rdparty/angle/src/common/tls.h
vendored
@ -15,7 +15,9 @@
|
||||
|
||||
// TLS does not exist for Windows Store and needs to be emulated
|
||||
# ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
# define TLS_OUT_OF_INDEXES -1
|
||||
# ifndef TLS_OUT_OF_INDEXES
|
||||
# define TLS_OUT_OF_INDEXES static_cast<DWORD>(0xFFFFFFFF)
|
||||
# endif
|
||||
# ifndef CREATE_SUSPENDED
|
||||
# define CREATE_SUSPENDED 0x00000004
|
||||
# endif
|
||||
|
40
src/3rdparty/angle/src/common/utilities.cpp
vendored
40
src/3rdparty/angle/src/common/utilities.cpp
vendored
@ -254,7 +254,7 @@ int VariableColumnCount(GLenum type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsSampler(GLenum type)
|
||||
bool IsSamplerType(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@ -343,9 +343,27 @@ int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsig
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool IsCubemapTextureTarget(GLenum target)
|
||||
static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value.");
|
||||
static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value.");
|
||||
static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value.");
|
||||
static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value.");
|
||||
static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, "Unexpected GL cube map enum value.");
|
||||
|
||||
bool IsCubeMapTextureTarget(GLenum target)
|
||||
{
|
||||
return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
|
||||
return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
|
||||
}
|
||||
|
||||
size_t CubeMapTextureTargetToLayerIndex(GLenum target)
|
||||
{
|
||||
ASSERT(IsCubeMapTextureTarget(target));
|
||||
return target - static_cast<size_t>(FirstCubeMapTextureTarget);
|
||||
}
|
||||
|
||||
GLenum LayerIndexToCubeMapTextureTarget(size_t index)
|
||||
{
|
||||
ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
|
||||
return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
|
||||
}
|
||||
|
||||
bool IsTriangleMode(GLenum drawMode)
|
||||
@ -486,10 +504,15 @@ void writeFile(const char* path, const void* content, size_t size)
|
||||
}
|
||||
#endif // !ANGLE_ENABLE_WINDOWS_STORE
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE) && _MSC_FULL_VER < 180031101
|
||||
#if defined (ANGLE_PLATFORM_WINDOWS)
|
||||
|
||||
void Sleep(unsigned long dwMilliseconds)
|
||||
// Causes the thread to relinquish the remainder of its time slice to any
|
||||
// other thread that is ready to run.If there are no other threads ready
|
||||
// to run, the function returns immediately, and the thread continues execution.
|
||||
void ScheduleYield()
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
// This implementation of Sleep exists because it is not available prior to Update 4.
|
||||
static HANDLE singletonEvent = nullptr;
|
||||
HANDLE sleepEvent = singletonEvent;
|
||||
if (!sleepEvent)
|
||||
@ -510,7 +533,10 @@ void Sleep(unsigned long dwMilliseconds)
|
||||
}
|
||||
|
||||
// Emulate sleep by waiting with timeout on an event that is never signalled.
|
||||
WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false);
|
||||
WaitForSingleObjectEx(sleepEvent, 0, false);
|
||||
#else
|
||||
Sleep(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // ANGLE_ENABLE_WINDOWS_STORE
|
||||
#endif
|
||||
|
18
src/3rdparty/angle/src/common/utilities.h
vendored
18
src/3rdparty/angle/src/common/utilities.h
vendored
@ -6,8 +6,8 @@
|
||||
|
||||
// utilities.h: Conversion functions and other utility routines.
|
||||
|
||||
#ifndef LIBGLESV2_UTILITIES_H
|
||||
#define LIBGLESV2_UTILITIES_H
|
||||
#ifndef COMMON_UTILITIES_H_
|
||||
#define COMMON_UTILITIES_H_
|
||||
|
||||
#include "angle_gl.h"
|
||||
#include <string>
|
||||
@ -24,7 +24,7 @@ size_t VariableExternalSize(GLenum type);
|
||||
GLenum VariableBoolVectorType(GLenum type);
|
||||
int VariableRowCount(GLenum type);
|
||||
int VariableColumnCount(GLenum type);
|
||||
bool IsSampler(GLenum type);
|
||||
bool IsSamplerType(GLenum type);
|
||||
bool IsMatrixType(GLenum type);
|
||||
GLenum TransposeMatrixType(GLenum type);
|
||||
int VariableRegisterCount(GLenum type);
|
||||
@ -34,7 +34,11 @@ int VariableSortOrder(GLenum type);
|
||||
|
||||
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
|
||||
|
||||
bool IsCubemapTextureTarget(GLenum target);
|
||||
static const GLenum FirstCubeMapTextureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
static const GLenum LastCubeMapTextureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
|
||||
bool IsCubeMapTextureTarget(GLenum target);
|
||||
size_t CubeMapTextureTargetToLayerIndex(GLenum target);
|
||||
GLenum LayerIndexToCubeMapTextureTarget(size_t index);
|
||||
|
||||
bool IsTriangleMode(GLenum drawMode);
|
||||
|
||||
@ -51,8 +55,8 @@ std::string getTempPath();
|
||||
void writeFile(const char* path, const void* data, size_t size);
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE) && _MSC_FULL_VER < 180031101
|
||||
void Sleep(_In_ unsigned long dwMilliseconds);
|
||||
#if defined (ANGLE_PLATFORM_WINDOWS)
|
||||
void ScheduleYield();
|
||||
#endif
|
||||
|
||||
#endif // LIBGLESV2_UTILITIES_H
|
||||
#endif // COMMON_UTILITIES_H_
|
||||
|
13
src/3rdparty/angle/src/common/version.h
vendored
13
src/3rdparty/angle/src/common/version.h
vendored
@ -1,4 +1,13 @@
|
||||
#include "../commit.h"
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMMON_VERSION_H_
|
||||
#define COMMON_VERSION_H_
|
||||
|
||||
#include "id/commit.h"
|
||||
|
||||
#define ANGLE_MAJOR_VERSION 2
|
||||
#define ANGLE_MINOR_VERSION 1
|
||||
@ -10,3 +19,5 @@
|
||||
ANGLE_MACRO_STRINGIFY(ANGLE_MAJOR_VERSION) "." \
|
||||
ANGLE_MACRO_STRINGIFY(ANGLE_MINOR_VERSION) "." \
|
||||
ANGLE_COMMIT_HASH
|
||||
|
||||
#endif // COMMON_VERSION_H_
|
||||
|
@ -1,39 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// 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_
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
|
||||
#define COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
|
||||
#ifndef COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
|
||||
#define COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -84,4 +84,5 @@ class Diagnostics
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
#endif // COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
|
||||
#define COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
|
||||
#ifndef COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
|
||||
#define COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -41,4 +41,5 @@ class DirectiveHandler
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
#endif // COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_
|
||||
#define COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_
|
||||
#ifndef COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
||||
#define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
||||
|
||||
#include "Lexer.h"
|
||||
#include "Macro.h"
|
||||
@ -78,5 +78,5 @@ class DirectiveParser : public Lexer
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
#endif // COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
|
||||
#define COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
|
||||
#ifndef COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
||||
#define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
||||
|
||||
#include "pp_utils.h"
|
||||
|
||||
@ -31,4 +31,5 @@ class ExpressionParser
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
#endif // COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
||||
|
@ -28,7 +28,7 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser.
|
||||
#pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(disable: 4065 4701)
|
||||
#pragma warning(disable: 4065 4701 4702)
|
||||
#endif
|
||||
|
||||
#include "ExpressionParser.h"
|
||||
@ -69,7 +69,7 @@ struct Context
|
||||
%}
|
||||
|
||||
%pure-parser
|
||||
%name-prefix="pp"
|
||||
%name-prefix "pp"
|
||||
%parse-param {Context *context}
|
||||
%lex-param {Context *context}
|
||||
|
||||
|
@ -58,5 +58,5 @@ class Input
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
#endif // COMPILER_PREPROCESSOR_INPUT_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_INPUT_H_
|
||||
|
@ -21,5 +21,5 @@ class Lexer
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
#endif // COMPILER_PREPROCESSOR_LEXER_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_LEXER_H_
|
||||
|
@ -46,4 +46,5 @@ struct Macro
|
||||
typedef std::map<std::string, Macro> MacroSet;
|
||||
|
||||
} // namespace pp
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_MACRO_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
|
||||
#define COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
|
||||
#ifndef COMPILER_PREPROCESSOR_MACROEXPANDER_H_
|
||||
#define COMPILER_PREPROCESSOR_MACROEXPANDER_H_
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
@ -85,5 +85,5 @@ class MacroExpander : public Lexer
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
#endif // COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_MACROEXPANDER_H_
|
||||
|
@ -50,5 +50,5 @@ class Preprocessor
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
#endif // COMPILER_PREPROCESSOR_PREPROCESSOR_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_PREPROCESSOR_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_
|
||||
#define COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_
|
||||
#ifndef COMPILER_PREPROCESSOR_SOURCELOCATION_H_
|
||||
#define COMPILER_PREPROCESSOR_SOURCELOCATION_H_
|
||||
|
||||
namespace pp
|
||||
{
|
||||
@ -43,4 +43,5 @@ inline bool operator!=(const SourceLocation &lhs, const SourceLocation &rhs)
|
||||
}
|
||||
|
||||
} // namespace pp
|
||||
#endif // COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_SOURCELOCATION_H_
|
||||
|
@ -116,4 +116,5 @@ inline bool operator!=(const Token &lhs, const Token &rhs)
|
||||
extern std::ostream &operator<<(std::ostream &out, const Token &token);
|
||||
|
||||
} // namepsace pp
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_TOKEN_H_
|
||||
|
@ -55,5 +55,5 @@ class Tokenizer : public Lexer
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
#endif // COMPILER_PREPROCESSOR_TOKENIZER_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_TOKENIZER_H_
|
||||
|
@ -267,7 +267,9 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
|
||||
|
||||
namespace pp {
|
||||
|
||||
Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(0)
|
||||
Tokenizer::Tokenizer(Diagnostics *diagnostics)
|
||||
: mHandle(0),
|
||||
mMaxTokenSize(256)
|
||||
{
|
||||
mContext.diagnostics = diagnostics;
|
||||
}
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
// numeric_lex.h: Functions to extract numeric values from string.
|
||||
|
||||
#ifndef COMPILER_PREPROCESSOR_NUMERIC_LEX_H_
|
||||
#define COMPILER_PREPROCESSOR_NUMERIC_LEX_H_
|
||||
#ifndef COMPILER_PREPROCESSOR_NUMERICLEX_H_
|
||||
#define COMPILER_PREPROCESSOR_NUMERICLEX_H_
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@ -58,4 +58,5 @@ bool numeric_lex_float(const std::string &str, FloatType *value)
|
||||
}
|
||||
|
||||
} // namespace pp.
|
||||
#endif // COMPILER_PREPROCESSOR_NUMERIC_LEX_H_
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_NUMERICLEX_H_
|
||||
|
@ -4,10 +4,10 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _BASICTYPES_INCLUDED_
|
||||
#define _BASICTYPES_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_BASETYPES_H_
|
||||
#define COMPILER_TRANSLATOR_BASETYPES_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include "compiler/translator/compilerdebug.h"
|
||||
|
||||
//
|
||||
// Precision qualifiers
|
||||
@ -42,7 +42,15 @@ enum TBasicType
|
||||
EbtInt,
|
||||
EbtUInt,
|
||||
EbtBool,
|
||||
EbtGVec4, // non type: represents vec4, ivec4 and uvec4
|
||||
EbtGVec4, // non type: represents vec4, ivec4, and uvec4
|
||||
EbtGenType, // non type: represents float, vec2, vec3, and vec4
|
||||
EbtGenIType, // non type: represents int, ivec2, ivec3, and ivec4
|
||||
EbtGenUType, // non type: represents uint, uvec2, uvec3, and uvec4
|
||||
EbtGenBType, // non type: represents bool, bvec2, bvec3, and bvec4
|
||||
EbtVec, // non type: represents vec2, vec3, and vec4
|
||||
EbtIVec, // non type: represents ivec2, ivec3, and ivec4
|
||||
EbtUVec, // non type: represents uvec2, uvec3, and uvec4
|
||||
EbtBVec, // non type: represents bvec2, bvec3, and bvec4
|
||||
EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
|
||||
EbtSampler2D,
|
||||
EbtSampler3D,
|
||||
@ -62,10 +70,10 @@ enum TBasicType
|
||||
EbtSamplerCubeShadow,
|
||||
EbtSampler2DArrayShadow,
|
||||
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
|
||||
EbtGSampler2D, // non type: represents sampler2D, isampler2D and usampler2D
|
||||
EbtGSampler3D, // non type: represents sampler3D, isampler3D and usampler3D
|
||||
EbtGSamplerCube, // non type: represents samplerCube, isamplerCube and usamplerCube
|
||||
EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray and usampler2DArray
|
||||
EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
|
||||
EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
|
||||
EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
|
||||
EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray
|
||||
EbtStruct,
|
||||
EbtInterfaceBlock,
|
||||
EbtAddress, // should be deprecated??
|
||||
@ -258,6 +266,11 @@ inline bool IsShadowSampler(TBasicType type)
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool IsInteger(TBasicType type)
|
||||
{
|
||||
return type == EbtInt || type == EbtUInt;
|
||||
}
|
||||
|
||||
inline bool SupportsPrecision(TBasicType type)
|
||||
{
|
||||
return type == EbtFloat || type == EbtInt || type == EbtUInt || IsSampler(type);
|
||||
@ -293,6 +306,9 @@ enum TQualifier
|
||||
EvqInOut,
|
||||
EvqConstReadOnly,
|
||||
|
||||
// built-ins read by vertex shader
|
||||
EvqInstanceID,
|
||||
|
||||
// built-ins written by vertex shader
|
||||
EvqPosition,
|
||||
EvqPointSize,
|
||||
@ -307,6 +323,10 @@ enum TQualifier
|
||||
EvqFragData,
|
||||
EvqFragDepth,
|
||||
|
||||
// built-ins written by the shader_framebuffer_fetch extension(s)
|
||||
EvqLastFragColor,
|
||||
EvqLastFragData,
|
||||
|
||||
// GLSL ES 3.0 vertex output and fragment input
|
||||
EvqSmooth, // Incomplete qualifier, smooth is the default
|
||||
EvqFlat, // Incomplete qualifier
|
||||
@ -383,6 +403,7 @@ inline const char* getQualifierString(TQualifier q)
|
||||
case EvqIn: return "in"; break;
|
||||
case EvqOut: return "out"; break;
|
||||
case EvqInOut: return "inout"; break;
|
||||
case EvqInstanceID: return "InstanceID"; break;
|
||||
case EvqPosition: return "Position"; break;
|
||||
case EvqPointSize: return "PointSize"; break;
|
||||
case EvqFragCoord: return "FragCoord"; break;
|
||||
@ -396,7 +417,9 @@ inline const char* getQualifierString(TQualifier q)
|
||||
case EvqSmoothIn: return "smooth in"; break;
|
||||
case EvqCentroidIn: return "centroid in"; break;
|
||||
case EvqFlatIn: return "flat in"; break;
|
||||
default: return "unknown qualifier";
|
||||
case EvqLastFragColor: return "LastFragColor"; break;
|
||||
case EvqLastFragData: return "LastFragData"; break;
|
||||
default: UNREACHABLE(); return "unknown qualifier";
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,7 +430,7 @@ inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq)
|
||||
case EmpUnspecified: return "mp_unspecified";
|
||||
case EmpRowMajor: return "row_major";
|
||||
case EmpColumnMajor: return "column_major";
|
||||
default: return "unknown matrix packing";
|
||||
default: UNREACHABLE(); return "unknown matrix packing";
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,7 +442,7 @@ inline const char* getBlockStorageString(TLayoutBlockStorage bsq)
|
||||
case EbsShared: return "shared";
|
||||
case EbsPacked: return "packed";
|
||||
case EbsStd140: return "std140";
|
||||
default: return "unknown block storage";
|
||||
default: UNREACHABLE(); return "unknown block storage";
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,8 +456,8 @@ inline const char* getInterpolationString(TQualifier q)
|
||||
case EvqSmoothIn: return "smooth"; break;
|
||||
case EvqCentroidIn: return "centroid"; break;
|
||||
case EvqFlatIn: return "flat"; break;
|
||||
default: return "unknown interpolation";
|
||||
default: UNREACHABLE(); return "unknown interpolation";
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _BASICTYPES_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_BASETYPES_H_
|
||||
|
@ -8,193 +8,9 @@
|
||||
#include "compiler/translator/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// we use macros here instead of function definitions to work around more GLSL
|
||||
// compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are
|
||||
// problematic because if the argument has side-effects they will be repeatedly
|
||||
// evaluated. This is unlikely to show up in real shaders, but is something to
|
||||
// consider.
|
||||
const char* kFunctionEmulationVertexSource[] = {
|
||||
"#error no emulation for cos(float)",
|
||||
"#error no emulation for cos(vec2)",
|
||||
"#error no emulation for cos(vec3)",
|
||||
"#error no emulation for cos(vec4)",
|
||||
|
||||
"#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))",
|
||||
"#error no emulation for distance(vec2, vec2)",
|
||||
"#error no emulation for distance(vec3, vec3)",
|
||||
"#error no emulation for distance(vec4, vec4)",
|
||||
|
||||
"#define webgl_dot_emu(x, y) ((x) * (y))",
|
||||
"#error no emulation for dot(vec2, vec2)",
|
||||
"#error no emulation for dot(vec3, vec3)",
|
||||
"#error no emulation for dot(vec4, vec4)",
|
||||
|
||||
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
|
||||
"#error no emulation for length(vec2)",
|
||||
"#error no emulation for length(vec3)",
|
||||
"#error no emulation for length(vec4)",
|
||||
|
||||
"#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
|
||||
"#error no emulation for normalize(vec2)",
|
||||
"#error no emulation for normalize(vec3)",
|
||||
"#error no emulation for normalize(vec4)",
|
||||
|
||||
"#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))",
|
||||
"#error no emulation for reflect(vec2, vec2)",
|
||||
"#error no emulation for reflect(vec3, vec3)",
|
||||
"#error no emulation for reflect(vec4, vec4)"
|
||||
};
|
||||
|
||||
const char* kFunctionEmulationFragmentSource[] = {
|
||||
"webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }",
|
||||
"webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }",
|
||||
"webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }",
|
||||
"webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }",
|
||||
|
||||
"#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))",
|
||||
"#error no emulation for distance(vec2, vec2)",
|
||||
"#error no emulation for distance(vec3, vec3)",
|
||||
"#error no emulation for distance(vec4, vec4)",
|
||||
|
||||
"#define webgl_dot_emu(x, y) ((x) * (y))",
|
||||
"#error no emulation for dot(vec2, vec2)",
|
||||
"#error no emulation for dot(vec3, vec3)",
|
||||
"#error no emulation for dot(vec4, vec4)",
|
||||
|
||||
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
|
||||
"#error no emulation for length(vec2)",
|
||||
"#error no emulation for length(vec3)",
|
||||
"#error no emulation for length(vec4)",
|
||||
|
||||
"#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
|
||||
"#error no emulation for normalize(vec2)",
|
||||
"#error no emulation for normalize(vec3)",
|
||||
"#error no emulation for normalize(vec4)",
|
||||
|
||||
"#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))",
|
||||
"#error no emulation for reflect(vec2, vec2)",
|
||||
"#error no emulation for reflect(vec3, vec3)",
|
||||
"#error no emulation for reflect(vec4, vec4)"
|
||||
};
|
||||
|
||||
const bool kFunctionEmulationVertexMask[] = {
|
||||
#if defined(__APPLE__)
|
||||
// Work around ATI driver bugs in Mac.
|
||||
false, // TFunctionCos1
|
||||
false, // TFunctionCos2
|
||||
false, // TFunctionCos3
|
||||
false, // TFunctionCos4
|
||||
true, // TFunctionDistance1_1
|
||||
false, // TFunctionDistance2_2
|
||||
false, // TFunctionDistance3_3
|
||||
false, // TFunctionDistance4_4
|
||||
true, // TFunctionDot1_1
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
true, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
false, // TFunctionLength4
|
||||
true, // TFunctionNormalize1
|
||||
false, // TFunctionNormalize2
|
||||
false, // TFunctionNormalize3
|
||||
false, // TFunctionNormalize4
|
||||
true, // TFunctionReflect1_1
|
||||
false, // TFunctionReflect2_2
|
||||
false, // TFunctionReflect3_3
|
||||
false, // TFunctionReflect4_4
|
||||
#else
|
||||
// Work around D3D driver bug in Win.
|
||||
false, // TFunctionCos1
|
||||
false, // TFunctionCos2
|
||||
false, // TFunctionCos3
|
||||
false, // TFunctionCos4
|
||||
false, // TFunctionDistance1_1
|
||||
false, // TFunctionDistance2_2
|
||||
false, // TFunctionDistance3_3
|
||||
false, // TFunctionDistance4_4
|
||||
false, // TFunctionDot1_1
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
false, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
false, // TFunctionLength4
|
||||
false, // TFunctionNormalize1
|
||||
false, // TFunctionNormalize2
|
||||
false, // TFunctionNormalize3
|
||||
false, // TFunctionNormalize4
|
||||
false, // TFunctionReflect1_1
|
||||
false, // TFunctionReflect2_2
|
||||
false, // TFunctionReflect3_3
|
||||
false, // TFunctionReflect4_4
|
||||
#endif
|
||||
false // TFunctionUnknown
|
||||
};
|
||||
|
||||
const bool kFunctionEmulationFragmentMask[] = {
|
||||
#if defined(__APPLE__)
|
||||
// Work around ATI driver bugs in Mac.
|
||||
true, // TFunctionCos1
|
||||
true, // TFunctionCos2
|
||||
true, // TFunctionCos3
|
||||
true, // TFunctionCos4
|
||||
true, // TFunctionDistance1_1
|
||||
false, // TFunctionDistance2_2
|
||||
false, // TFunctionDistance3_3
|
||||
false, // TFunctionDistance4_4
|
||||
true, // TFunctionDot1_1
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
true, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
false, // TFunctionLength4
|
||||
true, // TFunctionNormalize1
|
||||
false, // TFunctionNormalize2
|
||||
false, // TFunctionNormalize3
|
||||
false, // TFunctionNormalize4
|
||||
true, // TFunctionReflect1_1
|
||||
false, // TFunctionReflect2_2
|
||||
false, // TFunctionReflect3_3
|
||||
false, // TFunctionReflect4_4
|
||||
#else
|
||||
// Work around D3D driver bug in Win.
|
||||
false, // TFunctionCos1
|
||||
false, // TFunctionCos2
|
||||
false, // TFunctionCos3
|
||||
false, // TFunctionCos4
|
||||
false, // TFunctionDistance1_1
|
||||
false, // TFunctionDistance2_2
|
||||
false, // TFunctionDistance3_3
|
||||
false, // TFunctionDistance4_4
|
||||
false, // TFunctionDot1_1
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
false, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
false, // TFunctionLength4
|
||||
false, // TFunctionNormalize1
|
||||
false, // TFunctionNormalize2
|
||||
false, // TFunctionNormalize3
|
||||
false, // TFunctionNormalize4
|
||||
false, // TFunctionReflect1_1
|
||||
false, // TFunctionReflect2_2
|
||||
false, // TFunctionReflect3_3
|
||||
false, // TFunctionReflect4_4
|
||||
#endif
|
||||
false // TFunctionUnknown
|
||||
};
|
||||
|
||||
class BuiltInFunctionEmulationMarker : public TIntermTraverser {
|
||||
public:
|
||||
class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator& emulator)
|
||||
: mEmulator(emulator)
|
||||
{
|
||||
@ -238,148 +54,119 @@ public:
|
||||
case EOpFaceForward:
|
||||
case EOpReflect:
|
||||
case EOpRefract:
|
||||
case EOpOuterProduct:
|
||||
case EOpMul:
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
};
|
||||
const TIntermSequence& sequence = *(node->getSequence());
|
||||
// Right now we only handle built-in functions with two parameters.
|
||||
if (sequence.size() != 2)
|
||||
bool needToEmulate = false;
|
||||
// Right now we only handle built-in functions with two or three parameters.
|
||||
if (sequence.size() == 2)
|
||||
{
|
||||
TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
if (!param1 || !param2)
|
||||
return true;
|
||||
needToEmulate = mEmulator.SetFunctionCalled(
|
||||
node->getOp(), param1->getType(), param2->getType());
|
||||
}
|
||||
else if (sequence.size() == 3)
|
||||
{
|
||||
TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
TIntermTyped* param3 = sequence[2]->getAsTyped();
|
||||
if (!param1 || !param2 || !param3)
|
||||
return true;
|
||||
needToEmulate = mEmulator.SetFunctionCalled(
|
||||
node->getOp(), param1->getType(), param2->getType(), param3->getType());
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
if (!param1 || !param2)
|
||||
return true;
|
||||
bool needToEmulate = mEmulator.SetFunctionCalled(
|
||||
node->getOp(), param1->getType(), param2->getType());
|
||||
}
|
||||
|
||||
if (needToEmulate)
|
||||
node->setUseEmulatedFunction();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
BuiltInFunctionEmulator& mEmulator;
|
||||
};
|
||||
|
||||
} // anonymous namepsace
|
||||
BuiltInFunctionEmulator::BuiltInFunctionEmulator()
|
||||
{}
|
||||
|
||||
BuiltInFunctionEmulator::BuiltInFunctionEmulator(sh::GLenum shaderType)
|
||||
void BuiltInFunctionEmulator::addEmulatedFunction(
|
||||
TOperator op, const TType& param,
|
||||
const char* emulatedFunctionDefinition)
|
||||
{
|
||||
if (shaderType == GL_FRAGMENT_SHADER) {
|
||||
mFunctionMask = kFunctionEmulationFragmentMask;
|
||||
mFunctionSource = kFunctionEmulationFragmentSource;
|
||||
} else {
|
||||
mFunctionMask = kFunctionEmulationVertexMask;
|
||||
mFunctionSource = kFunctionEmulationVertexSource;
|
||||
mEmulatedFunctions[FunctionId(op, param)] =
|
||||
std::string(emulatedFunctionDefinition);
|
||||
}
|
||||
|
||||
void BuiltInFunctionEmulator::addEmulatedFunction(
|
||||
TOperator op, const TType& param1, const TType& param2,
|
||||
const char* emulatedFunctionDefinition)
|
||||
{
|
||||
mEmulatedFunctions[FunctionId(op, param1, param2)] =
|
||||
std::string(emulatedFunctionDefinition);
|
||||
}
|
||||
|
||||
void BuiltInFunctionEmulator::addEmulatedFunction(
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3,
|
||||
const char* emulatedFunctionDefinition)
|
||||
{
|
||||
mEmulatedFunctions[FunctionId(op, param1, param2, param3)] =
|
||||
std::string(emulatedFunctionDefinition);
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::IsOutputEmpty() const
|
||||
{
|
||||
return (mFunctions.size() == 0);
|
||||
}
|
||||
|
||||
void BuiltInFunctionEmulator::OutputEmulatedFunctions(
|
||||
TInfoSinkBase& out) const
|
||||
{
|
||||
for (size_t i = 0; i < mFunctions.size(); ++i) {
|
||||
out << mEmulatedFunctions.find(mFunctions[i])->second << "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
TOperator op, const TType& param)
|
||||
{
|
||||
TBuiltInFunction function = IdentifyFunction(op, param);
|
||||
return SetFunctionCalled(function);
|
||||
return SetFunctionCalled(FunctionId(op, param));
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2)
|
||||
{
|
||||
TBuiltInFunction function = IdentifyFunction(op, param1, param2);
|
||||
return SetFunctionCalled(function);
|
||||
return SetFunctionCalled(FunctionId(op, param1, param2));
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
BuiltInFunctionEmulator::TBuiltInFunction function) {
|
||||
if (function == TFunctionUnknown || mFunctionMask[function] == false)
|
||||
return false;
|
||||
for (size_t i = 0; i < mFunctions.size(); ++i) {
|
||||
if (mFunctions[i] == function)
|
||||
return true;
|
||||
}
|
||||
mFunctions.push_back(function);
|
||||
return true;
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3)
|
||||
{
|
||||
return SetFunctionCalled(FunctionId(op, param1, param2, param3));
|
||||
}
|
||||
|
||||
void BuiltInFunctionEmulator::OutputEmulatedFunctionDefinition(
|
||||
TInfoSinkBase& out, bool withPrecision) const
|
||||
{
|
||||
if (mFunctions.size() == 0)
|
||||
return;
|
||||
out << "// BEGIN: Generated code for built-in function emulation\n\n";
|
||||
if (withPrecision) {
|
||||
out << "#if defined(GL_FRAGMENT_PRECISION_HIGH)\n"
|
||||
<< "#define webgl_emu_precision highp\n"
|
||||
<< "#else\n"
|
||||
<< "#define webgl_emu_precision mediump\n"
|
||||
<< "#endif\n\n";
|
||||
} else {
|
||||
out << "#define webgl_emu_precision\n\n";
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
const FunctionId& functionId) {
|
||||
if (mEmulatedFunctions.find(functionId) != mEmulatedFunctions.end())
|
||||
{
|
||||
for (size_t i = 0; i < mFunctions.size(); ++i) {
|
||||
if (mFunctions[i] == functionId)
|
||||
return true;
|
||||
}
|
||||
mFunctions.push_back(functionId);
|
||||
return true;
|
||||
}
|
||||
for (size_t i = 0; i < mFunctions.size(); ++i) {
|
||||
out << mFunctionSource[mFunctions[i]] << "\n\n";
|
||||
}
|
||||
out << "// END: Generated code for built-in function emulation\n\n";
|
||||
}
|
||||
|
||||
BuiltInFunctionEmulator::TBuiltInFunction
|
||||
BuiltInFunctionEmulator::IdentifyFunction(
|
||||
TOperator op, const TType& param)
|
||||
{
|
||||
if (param.getNominalSize() > 4 || param.getSecondarySize() > 4)
|
||||
return TFunctionUnknown;
|
||||
unsigned int function = TFunctionUnknown;
|
||||
switch (op) {
|
||||
case EOpCos:
|
||||
function = TFunctionCos1;
|
||||
break;
|
||||
case EOpLength:
|
||||
function = TFunctionLength1;
|
||||
break;
|
||||
case EOpNormalize:
|
||||
function = TFunctionNormalize1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (function == TFunctionUnknown)
|
||||
return TFunctionUnknown;
|
||||
if (param.isVector())
|
||||
function += param.getNominalSize() - 1;
|
||||
return static_cast<TBuiltInFunction>(function);
|
||||
}
|
||||
|
||||
BuiltInFunctionEmulator::TBuiltInFunction
|
||||
BuiltInFunctionEmulator::IdentifyFunction(
|
||||
TOperator op, const TType& param1, const TType& param2)
|
||||
{
|
||||
// Right now for all the emulated functions with two parameters, the two
|
||||
// parameters have the same type.
|
||||
if (param1.getNominalSize() != param2.getNominalSize() ||
|
||||
param1.getSecondarySize() != param2.getSecondarySize() ||
|
||||
param1.getNominalSize() > 4 || param1.getSecondarySize() > 4)
|
||||
return TFunctionUnknown;
|
||||
|
||||
unsigned int function = TFunctionUnknown;
|
||||
switch (op) {
|
||||
case EOpDistance:
|
||||
function = TFunctionDistance1_1;
|
||||
break;
|
||||
case EOpDot:
|
||||
function = TFunctionDot1_1;
|
||||
break;
|
||||
case EOpReflect:
|
||||
function = TFunctionReflect1_1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (function == TFunctionUnknown)
|
||||
return TFunctionUnknown;
|
||||
if (param1.isVector())
|
||||
function += param1.getNominalSize() - 1;
|
||||
return static_cast<TBuiltInFunction>(function);
|
||||
return false;
|
||||
}
|
||||
|
||||
void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
|
||||
@ -387,6 +174,9 @@ void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
|
||||
{
|
||||
ASSERT(root);
|
||||
|
||||
if (mEmulatedFunctions.empty())
|
||||
return;
|
||||
|
||||
BuiltInFunctionEmulationMarker marker(*this);
|
||||
root->traverse(&marker);
|
||||
}
|
||||
@ -404,3 +194,52 @@ TString BuiltInFunctionEmulator::GetEmulatedFunctionName(
|
||||
return "webgl_" + name.substr(0, name.length() - 1) + "_emu(";
|
||||
}
|
||||
|
||||
BuiltInFunctionEmulator::FunctionId::FunctionId
|
||||
(TOperator op, const TType& param)
|
||||
: mOp(op),
|
||||
mParam1(param),
|
||||
mParam2(EbtVoid),
|
||||
mParam3(EbtVoid)
|
||||
{
|
||||
}
|
||||
|
||||
BuiltInFunctionEmulator::FunctionId::FunctionId
|
||||
(TOperator op, const TType& param1, const TType& param2)
|
||||
: mOp(op),
|
||||
mParam1(param1),
|
||||
mParam2(param2),
|
||||
mParam3(EbtVoid)
|
||||
{
|
||||
}
|
||||
|
||||
BuiltInFunctionEmulator::FunctionId::FunctionId
|
||||
(TOperator op, const TType& param1, const TType& param2, const TType& param3)
|
||||
: mOp(op),
|
||||
mParam1(param1),
|
||||
mParam2(param2),
|
||||
mParam3(param3)
|
||||
{
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::FunctionId::operator==
|
||||
(const BuiltInFunctionEmulator::FunctionId& other) const
|
||||
{
|
||||
return (mOp == other.mOp &&
|
||||
mParam1 == other.mParam1 &&
|
||||
mParam2 == other.mParam2 &&
|
||||
mParam3 == other.mParam3);
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::FunctionId::operator<
|
||||
(const BuiltInFunctionEmulator::FunctionId& other) const
|
||||
{
|
||||
if (mOp != other.mOp)
|
||||
return mOp < other.mOp;
|
||||
if (mParam1 != other.mParam1)
|
||||
return mParam1 < other.mParam1;
|
||||
if (mParam2 != other.mParam2)
|
||||
return mParam2 < other.mParam2;
|
||||
if (mParam3 != other.mParam3)
|
||||
return mParam3 < other.mParam3;
|
||||
return false; // all fields are equal
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
|
||||
#define COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
|
||||
#ifndef COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
|
||||
#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
|
||||
|
||||
#include "compiler/translator/InfoSink.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
@ -13,23 +13,13 @@
|
||||
//
|
||||
// This class decides which built-in functions need to be replaced with the
|
||||
// emulated ones.
|
||||
// It's only a workaround for OpenGL driver bugs, and isn't needed in general.
|
||||
// It can be used to work around driver bugs or implement functions that are
|
||||
// not natively implemented on a specific platform.
|
||||
//
|
||||
class BuiltInFunctionEmulator {
|
||||
public:
|
||||
BuiltInFunctionEmulator(sh::GLenum shaderType);
|
||||
// Records that a function is called by the shader and might needs to be
|
||||
// emulated. If the function's group is not in mFunctionGroupFilter, this
|
||||
// becomes an no-op.
|
||||
// Returns true if the function call needs to be replaced with an emulated
|
||||
// one.
|
||||
bool SetFunctionCalled(TOperator op, const TType& param);
|
||||
bool SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2);
|
||||
|
||||
// Output function emulation definition. This should be before any other
|
||||
// shader source.
|
||||
void OutputEmulatedFunctionDefinition(TInfoSinkBase& out, bool withPrecision) const;
|
||||
class BuiltInFunctionEmulator
|
||||
{
|
||||
public:
|
||||
BuiltInFunctionEmulator();
|
||||
|
||||
void MarkBuiltInFunctionsForEmulation(TIntermNode* root);
|
||||
|
||||
@ -38,54 +28,52 @@ public:
|
||||
// "name(" becomes "webgl_name_emu(".
|
||||
static TString GetEmulatedFunctionName(const TString& name);
|
||||
|
||||
private:
|
||||
//
|
||||
// Built-in functions.
|
||||
//
|
||||
enum TBuiltInFunction {
|
||||
TFunctionCos1 = 0, // float cos(float);
|
||||
TFunctionCos2, // vec2 cos(vec2);
|
||||
TFunctionCos3, // vec3 cos(vec3);
|
||||
TFunctionCos4, // vec4 cos(vec4);
|
||||
bool IsOutputEmpty() const;
|
||||
|
||||
TFunctionDistance1_1, // float distance(float, float);
|
||||
TFunctionDistance2_2, // vec2 distance(vec2, vec2);
|
||||
TFunctionDistance3_3, // vec3 distance(vec3, vec3);
|
||||
TFunctionDistance4_4, // vec4 distance(vec4, vec4);
|
||||
// Output function emulation definition. This should be before any other
|
||||
// shader source.
|
||||
void OutputEmulatedFunctions(TInfoSinkBase& out) const;
|
||||
|
||||
TFunctionDot1_1, // float dot(float, float);
|
||||
TFunctionDot2_2, // vec2 dot(vec2, vec2);
|
||||
TFunctionDot3_3, // vec3 dot(vec3, vec3);
|
||||
TFunctionDot4_4, // vec4 dot(vec4, vec4);
|
||||
// Add functions that need to be emulated.
|
||||
void addEmulatedFunction(TOperator op, const TType& param, const char* emulatedFunctionDefinition);
|
||||
void addEmulatedFunction(TOperator op, const TType& param1, const TType& param2, const char* emulatedFunctionDefinition);
|
||||
void addEmulatedFunction(TOperator op, const TType& param1, const TType& param2, const TType& param3, const char* emulatedFunctionDefinition);
|
||||
|
||||
TFunctionLength1, // float length(float);
|
||||
TFunctionLength2, // float length(vec2);
|
||||
TFunctionLength3, // float length(vec3);
|
||||
TFunctionLength4, // float length(vec4);
|
||||
private:
|
||||
class BuiltInFunctionEmulationMarker;
|
||||
|
||||
TFunctionNormalize1, // float normalize(float);
|
||||
TFunctionNormalize2, // vec2 normalize(vec2);
|
||||
TFunctionNormalize3, // vec3 normalize(vec3);
|
||||
TFunctionNormalize4, // vec4 normalize(vec4);
|
||||
// Records that a function is called by the shader and might need to be
|
||||
// emulated. If the function is not in mEmulatedFunctions, this becomes a
|
||||
// no-op. Returns true if the function call needs to be replaced with an
|
||||
// emulated one.
|
||||
bool SetFunctionCalled(TOperator op, const TType& param);
|
||||
bool SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2);
|
||||
bool SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3);
|
||||
|
||||
TFunctionReflect1_1, // float reflect(float, float);
|
||||
TFunctionReflect2_2, // vec2 reflect(vec2, vec2);
|
||||
TFunctionReflect3_3, // vec3 reflect(vec3, vec3);
|
||||
TFunctionReflect4_4, // vec4 reflect(vec4, vec4);
|
||||
class FunctionId {
|
||||
public:
|
||||
FunctionId(TOperator op, const TType& param);
|
||||
FunctionId(TOperator op, const TType& param1, const TType& param2);
|
||||
FunctionId(TOperator op, const TType& param1, const TType& param2, const TType& param3);
|
||||
|
||||
TFunctionUnknown
|
||||
bool operator==(const FunctionId& other) const;
|
||||
bool operator<(const FunctionId& other) const;
|
||||
private:
|
||||
TOperator mOp;
|
||||
TType mParam1;
|
||||
TType mParam2;
|
||||
TType mParam3;
|
||||
};
|
||||
|
||||
TBuiltInFunction IdentifyFunction(TOperator op, const TType& param);
|
||||
TBuiltInFunction IdentifyFunction(
|
||||
TOperator op, const TType& param1, const TType& param2);
|
||||
bool SetFunctionCalled(const FunctionId& functionId);
|
||||
|
||||
bool SetFunctionCalled(TBuiltInFunction function);
|
||||
// Map from function id to emulated function definition
|
||||
std::map<FunctionId, std::string> mEmulatedFunctions;
|
||||
|
||||
std::vector<TBuiltInFunction> mFunctions;
|
||||
|
||||
const bool* mFunctionMask; // a boolean flag for each function.
|
||||
const char** mFunctionSource;
|
||||
// Called function ids
|
||||
std::vector<FunctionId> mFunctions;
|
||||
};
|
||||
|
||||
#endif // COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
|
||||
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
|
||||
|
37
src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
vendored
Normal file
37
src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright (c) 2002-2011 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 "angle_gl.h"
|
||||
#include "compiler/translator/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
|
||||
void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum shaderType)
|
||||
{
|
||||
// we use macros here instead of function definitions to work around more GLSL
|
||||
// compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are
|
||||
// problematic because if the argument has side-effects they will be repeatedly
|
||||
// evaluated. This is unlikely to show up in real shaders, but is something to
|
||||
// consider.
|
||||
|
||||
TType float1(EbtFloat);
|
||||
TType float2(EbtFloat, 2);
|
||||
TType float3(EbtFloat, 3);
|
||||
TType float4(EbtFloat, 4);
|
||||
|
||||
if (shaderType == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
emu->addEmulatedFunction(EOpCos, float1, "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }");
|
||||
emu->addEmulatedFunction(EOpCos, float2, "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }");
|
||||
emu->addEmulatedFunction(EOpCos, float3, "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }");
|
||||
emu->addEmulatedFunction(EOpCos, float4, "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }");
|
||||
}
|
||||
emu->addEmulatedFunction(EOpDistance, float1, float1, "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))");
|
||||
emu->addEmulatedFunction(EOpDot, float1, float1, "#define webgl_dot_emu(x, y) ((x) * (y))");
|
||||
emu->addEmulatedFunction(EOpLength, float1, "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))");
|
||||
emu->addEmulatedFunction(EOpNormalize, float1, "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))");
|
||||
emu->addEmulatedFunction(EOpReflect, float1, float1, "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))");
|
||||
}
|
19
src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
vendored
Normal file
19
src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
|
||||
#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
class BuiltInFunctionEmulator;
|
||||
|
||||
//
|
||||
// This is only a workaround for OpenGL driver bugs, and isn't needed in general.
|
||||
//
|
||||
void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum shaderType);
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
|
410
src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
vendored
Normal file
410
src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
vendored
Normal file
@ -0,0 +1,410 @@
|
||||
//
|
||||
// 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 "angle_gl.h"
|
||||
#include "compiler/translator/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
|
||||
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
|
||||
{
|
||||
TType float1(EbtFloat);
|
||||
TType float2(EbtFloat, 2);
|
||||
TType float3(EbtFloat, 3);
|
||||
TType float4(EbtFloat, 4);
|
||||
|
||||
emu->addEmulatedFunction(EOpMod, float1, float1,
|
||||
"float webgl_mod_emu(float x, float y)\n"
|
||||
"{\n"
|
||||
" return x - y * floor(x / y);\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
emu->addEmulatedFunction(EOpMod, float2, float2,
|
||||
"float2 webgl_mod_emu(float2 x, float2 y)\n"
|
||||
"{\n"
|
||||
" return x - y * floor(x / y);\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
emu->addEmulatedFunction(EOpMod, float2, float1,
|
||||
"float2 webgl_mod_emu(float2 x, float y)\n"
|
||||
"{\n"
|
||||
" return x - y * floor(x / y);\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
emu->addEmulatedFunction(EOpMod, float3, float3,
|
||||
"float3 webgl_mod_emu(float3 x, float3 y)\n"
|
||||
"{\n"
|
||||
" return x - y * floor(x / y);\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
emu->addEmulatedFunction(EOpMod, float3, float1,
|
||||
"float3 webgl_mod_emu(float3 x, float y)\n"
|
||||
"{\n"
|
||||
" return x - y * floor(x / y);\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
emu->addEmulatedFunction(EOpMod, float4, float4,
|
||||
"float4 webgl_mod_emu(float4 x, float4 y)\n"
|
||||
"{\n"
|
||||
" return x - y * floor(x / y);\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
emu->addEmulatedFunction(EOpMod, float4, float1,
|
||||
"float4 webgl_mod_emu(float4 x, float y)\n"
|
||||
"{\n"
|
||||
" return x - y * floor(x / y);\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
|
||||
emu->addEmulatedFunction(EOpFaceForward, float1, float1, float1,
|
||||
"float webgl_faceforward_emu(float N, float I, float Nref)\n"
|
||||
"{\n"
|
||||
" if(dot(Nref, I) >= 0)\n"
|
||||
" {\n"
|
||||
" return -N;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" return N;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
emu->addEmulatedFunction(EOpFaceForward, float2, float2, float2,
|
||||
"float2 webgl_faceforward_emu(float2 N, float2 I, float2 Nref)\n"
|
||||
"{\n"
|
||||
" if(dot(Nref, I) >= 0)\n"
|
||||
" {\n"
|
||||
" return -N;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" return N;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
emu->addEmulatedFunction(EOpFaceForward, float3, float3, float3,
|
||||
"float3 webgl_faceforward_emu(float3 N, float3 I, float3 Nref)\n"
|
||||
"{\n"
|
||||
" if(dot(Nref, I) >= 0)\n"
|
||||
" {\n"
|
||||
" return -N;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" return N;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
emu->addEmulatedFunction(EOpFaceForward, float4, float4, float4,
|
||||
"float4 webgl_faceforward_emu(float4 N, float4 I, float4 Nref)\n"
|
||||
"{\n"
|
||||
" if(dot(Nref, I) >= 0)\n"
|
||||
" {\n"
|
||||
" return -N;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" return N;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
|
||||
emu->addEmulatedFunction(EOpAtan, float1, float1,
|
||||
"float webgl_atan_emu(float y, float x)\n"
|
||||
"{\n"
|
||||
" if(x == 0 && y == 0) x = 1;\n" // Avoid producing a NaN
|
||||
" return atan2(y, x);\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAtan, float2, float2,
|
||||
"float2 webgl_atan_emu(float2 y, float2 x)\n"
|
||||
"{\n"
|
||||
" if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
|
||||
" if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
|
||||
" return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAtan, float3, float3,
|
||||
"float3 webgl_atan_emu(float3 y, float3 x)\n"
|
||||
"{\n"
|
||||
" if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
|
||||
" if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
|
||||
" if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
|
||||
" return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAtan, float4, float4,
|
||||
"float4 webgl_atan_emu(float4 y, float4 x)\n"
|
||||
"{\n"
|
||||
" if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
|
||||
" if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
|
||||
" if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
|
||||
" if(x[3] == 0 && y[3] == 0) x[3] = 1;\n"
|
||||
" return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]), atan2(y[3], x[3]));\n"
|
||||
"}\n");
|
||||
|
||||
emu->addEmulatedFunction(EOpAsinh, float1,
|
||||
"float webgl_asinh_emu(in float x) {\n"
|
||||
" return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAsinh, float2,
|
||||
"float2 webgl_asinh_emu(in float2 x) {\n"
|
||||
" return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAsinh, float3,
|
||||
"float3 webgl_asinh_emu(in float3 x) {\n"
|
||||
" return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAsinh, float4,
|
||||
"float4 webgl_asinh_emu(in float4 x) {\n"
|
||||
" return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
|
||||
"}\n");
|
||||
|
||||
emu->addEmulatedFunction(EOpAcosh, float1,
|
||||
"float webgl_acosh_emu(in float x) {\n"
|
||||
" return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAcosh, float2,
|
||||
"float2 webgl_acosh_emu(in float2 x) {\n"
|
||||
" return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAcosh, float3,
|
||||
"float3 webgl_acosh_emu(in float3 x) {\n"
|
||||
" return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAcosh, float4,
|
||||
"float4 webgl_acosh_emu(in float4 x) {\n"
|
||||
" return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
|
||||
"}\n");
|
||||
|
||||
emu->addEmulatedFunction(EOpAtanh, float1,
|
||||
"float webgl_atanh_emu(in float x) {\n"
|
||||
" return 0.5 * log((1.0 + x) / (1.0 - x));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAtanh, float2,
|
||||
"float2 webgl_atanh_emu(in float2 x) {\n"
|
||||
" return 0.5 * log((1.0 + x) / (1.0 - x));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAtanh, float3,
|
||||
"float3 webgl_atanh_emu(in float3 x) {\n"
|
||||
" return 0.5 * log((1.0 + x) / (1.0 - x));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpAtanh, float4,
|
||||
"float4 webgl_atanh_emu(in float4 x) {\n"
|
||||
" return 0.5 * log((1.0 + x) / (1.0 - x));\n"
|
||||
"}\n");
|
||||
|
||||
emu->addEmulatedFunction(EOpRoundEven, float1,
|
||||
"float webgl_roundEven_emu(in float x) {\n"
|
||||
" return (frac(x) == 0.5 && trunc(x) % 2.0 == 0.0) ? trunc(x) : round(x);\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpRoundEven, float2,
|
||||
"float2 webgl_roundEven_emu(in float2 x) {\n"
|
||||
" float2 v;\n"
|
||||
" v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
|
||||
" v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
|
||||
" return v;\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpRoundEven, float3,
|
||||
"float3 webgl_roundEven_emu(in float3 x) {\n"
|
||||
" float3 v;\n"
|
||||
" v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
|
||||
" v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
|
||||
" v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
|
||||
" return v;\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpRoundEven, float4,
|
||||
"float4 webgl_roundEven_emu(in float4 x) {\n"
|
||||
" float4 v;\n"
|
||||
" v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
|
||||
" v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
|
||||
" v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
|
||||
" v[3] = (frac(x[3]) == 0.5 && trunc(x[3]) % 2.0 == 0.0) ? trunc(x[3]) : round(x[3]);\n"
|
||||
" return v;\n"
|
||||
"}\n");
|
||||
|
||||
emu->addEmulatedFunction(EOpPackSnorm2x16, float2,
|
||||
"int webgl_toSnorm(in float x) {\n"
|
||||
" return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"uint webgl_packSnorm2x16_emu(in float2 v) {\n"
|
||||
" int x = webgl_toSnorm(v.x);\n"
|
||||
" int y = webgl_toSnorm(v.y);\n"
|
||||
" return (asuint(y) << 16) | (asuint(x) & 0xffffu);\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpPackUnorm2x16, float2,
|
||||
"uint webgl_toUnorm(in float x) {\n"
|
||||
" return uint(round(clamp(x, 0.0, 1.0) * 65535.0));\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"uint webgl_packUnorm2x16_emu(in float2 v) {\n"
|
||||
" uint x = webgl_toUnorm(v.x);\n"
|
||||
" uint y = webgl_toUnorm(v.y);\n"
|
||||
" return (y << 16) | x;\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpPackHalf2x16, float2,
|
||||
"uint webgl_packHalf2x16_emu(in float2 v) {\n"
|
||||
" uint x = f32tof16(v.x);\n"
|
||||
" uint y = f32tof16(v.y);\n"
|
||||
" return (y << 16) | x;\n"
|
||||
"}\n");
|
||||
|
||||
TType uint1(EbtUInt);
|
||||
|
||||
emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1,
|
||||
"float webgl_fromSnorm(in uint x) {\n"
|
||||
" int xi = asint(x & 0x7fffu) - asint(x & 0x8000u);\n"
|
||||
" return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"float2 webgl_unpackSnorm2x16_emu(in uint u) {\n"
|
||||
" uint y = (u >> 16);\n"
|
||||
" uint x = u;\n"
|
||||
" return float2(webgl_fromSnorm(x), webgl_fromSnorm(y));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1,
|
||||
"float webgl_fromUnorm(in uint x) {\n"
|
||||
" return float(x) / 65535.0;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"float2 webgl_unpackUnorm2x16_emu(in uint u) {\n"
|
||||
" uint y = (u >> 16);\n"
|
||||
" uint x = u & 0xffffu;\n"
|
||||
" return float2(webgl_fromUnorm(x), webgl_fromUnorm(y));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1,
|
||||
"float2 webgl_unpackHalf2x16_emu(in uint u) {\n"
|
||||
" uint y = (u >> 16);\n"
|
||||
" uint x = u & 0xffffu;\n"
|
||||
" return float2(f16tof32(x), f16tof32(y));\n"
|
||||
"}\n");
|
||||
|
||||
// The matrix resulting from outer product needs to be transposed
|
||||
// (matrices are stored as transposed to simplify element access in HLSL).
|
||||
// So the function should return transpose(c * r) where c is a column vector
|
||||
// and r is a row vector. This can be simplified by using the following
|
||||
// formula:
|
||||
// transpose(c * r) = transpose(r) * transpose(c)
|
||||
// transpose(r) and transpose(c) are in a sense free, since to get the
|
||||
// transpose of r, we simply can build a column matrix out of the original
|
||||
// vector instead of a row matrix.
|
||||
emu->addEmulatedFunction(EOpOuterProduct, float2, float2,
|
||||
"float2x2 webgl_outerProduct_emu(in float2 c, in float2 r) {\n"
|
||||
" return mul(float2x1(r), float1x2(c));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpOuterProduct, float3, float3,
|
||||
"float3x3 webgl_outerProduct_emu(in float3 c, in float3 r) {\n"
|
||||
" return mul(float3x1(r), float1x3(c));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpOuterProduct, float4, float4,
|
||||
"float4x4 webgl_outerProduct_emu(in float4 c, in float4 r) {\n"
|
||||
" return mul(float4x1(r), float1x4(c));\n"
|
||||
"}\n");
|
||||
|
||||
emu->addEmulatedFunction(EOpOuterProduct, float3, float2,
|
||||
"float2x3 webgl_outerProduct_emu(in float3 c, in float2 r) {\n"
|
||||
" return mul(float2x1(r), float1x3(c));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpOuterProduct, float2, float3,
|
||||
"float3x2 webgl_outerProduct_emu(in float2 c, in float3 r) {\n"
|
||||
" return mul(float3x1(r), float1x2(c));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpOuterProduct, float4, float2,
|
||||
"float2x4 webgl_outerProduct_emu(in float4 c, in float2 r) {\n"
|
||||
" return mul(float2x1(r), float1x4(c));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpOuterProduct, float2, float4,
|
||||
"float4x2 webgl_outerProduct_emu(in float2 c, in float4 r) {\n"
|
||||
" return mul(float4x1(r), float1x2(c));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpOuterProduct, float4, float3,
|
||||
"float3x4 webgl_outerProduct_emu(in float4 c, in float3 r) {\n"
|
||||
" return mul(float3x1(r), float1x4(c));\n"
|
||||
"}\n");
|
||||
emu->addEmulatedFunction(EOpOuterProduct, float3, float4,
|
||||
"float4x3 webgl_outerProduct_emu(in float3 c, in float4 r) {\n"
|
||||
" return mul(float4x1(r), float1x3(c));\n"
|
||||
"}\n");
|
||||
|
||||
TType mat2(EbtFloat, 2, 2);
|
||||
TType mat3(EbtFloat, 3, 3);
|
||||
TType mat4(EbtFloat, 4, 4);
|
||||
|
||||
// Remember here that the parameter matrix is actually the transpose
|
||||
// of the matrix that we're trying to invert, and the resulting matrix
|
||||
// should also be the transpose of the inverse.
|
||||
|
||||
// When accessing the parameter matrix with m[a][b] it can be thought of so
|
||||
// that a is the column and b is the row of the matrix that we're inverting.
|
||||
|
||||
// We calculate the inverse as the adjugate matrix divided by the
|
||||
// determinant of the matrix being inverted. However, as the result needs
|
||||
// to be transposed, we actually use of the transpose of the adjugate matrix
|
||||
// which happens to be the cofactor matrix. That's stored in "cof".
|
||||
|
||||
// We don't need to care about divide-by-zero since results are undefined
|
||||
// for singular or poorly-conditioned matrices.
|
||||
|
||||
emu->addEmulatedFunction(EOpInverse, mat2,
|
||||
"float2x2 webgl_inverse_emu(in float2x2 m) {\n"
|
||||
" float2x2 cof = { m[1][1], -m[0][1], -m[1][0], m[0][0] };\n"
|
||||
" return cof / determinant(transpose(m));\n"
|
||||
"}\n");
|
||||
|
||||
// cofAB is the cofactor for column A and row B.
|
||||
|
||||
emu->addEmulatedFunction(EOpInverse, mat3,
|
||||
"float3x3 webgl_inverse_emu(in float3x3 m) {\n"
|
||||
" float cof00 = m[1][1] * m[2][2] - m[2][1] * m[1][2];\n"
|
||||
" float cof01 = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]);\n"
|
||||
" float cof02 = m[1][0] * m[2][1] - m[2][0] * m[1][1];\n"
|
||||
" float cof10 = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]);\n"
|
||||
" float cof11 = m[0][0] * m[2][2] - m[2][0] * m[0][2];\n"
|
||||
" float cof12 = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]);\n"
|
||||
" float cof20 = m[0][1] * m[1][2] - m[1][1] * m[0][2];\n"
|
||||
" float cof21 = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]);\n"
|
||||
" float cof22 = m[0][0] * m[1][1] - m[1][0] * m[0][1];\n"
|
||||
" float3x3 cof = { cof00, cof10, cof20, cof01, cof11, cof21, cof02, cof12, cof22 };\n"
|
||||
" return cof / determinant(transpose(m));\n"
|
||||
"}\n");
|
||||
|
||||
emu->addEmulatedFunction(EOpInverse, mat4,
|
||||
"float4x4 webgl_inverse_emu(in float4x4 m) {\n"
|
||||
" float cof00 = m[1][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3]"
|
||||
" - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] - m[3][1] * m[2][2] * m[1][3];\n"
|
||||
" float cof01 = -(m[1][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[1][3] + m[3][0] * m[1][2] * m[2][3]"
|
||||
" - m[1][0] * m[3][2] * m[2][3] - m[2][0] * m[1][2] * m[3][3] - m[3][0] * m[2][2] * m[1][3]);\n"
|
||||
" float cof02 = m[1][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3]"
|
||||
" - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] - m[3][0] * m[2][1] * m[1][3];\n"
|
||||
" float cof03 = -(m[1][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[1][2] + m[3][0] * m[1][1] * m[2][2]"
|
||||
" - m[1][0] * m[3][1] * m[2][2] - m[2][0] * m[1][1] * m[3][2] - m[3][0] * m[2][1] * m[1][2]);\n"
|
||||
" float cof10 = -(m[0][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[0][3] + m[3][1] * m[0][2] * m[2][3]"
|
||||
" - m[0][1] * m[3][2] * m[2][3] - m[2][1] * m[0][2] * m[3][3] - m[3][1] * m[2][2] * m[0][3]);\n"
|
||||
" float cof11 = m[0][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[0][3] + m[3][0] * m[0][2] * m[2][3]"
|
||||
" - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] - m[3][0] * m[2][2] * m[0][3];\n"
|
||||
" float cof12 = -(m[0][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[0][3] + m[3][0] * m[0][1] * m[2][3]"
|
||||
" - m[0][0] * m[3][1] * m[2][3] - m[2][0] * m[0][1] * m[3][3] - m[3][0] * m[2][1] * m[0][3]);\n"
|
||||
" float cof13 = m[0][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[0][2] + m[3][0] * m[0][1] * m[2][2]"
|
||||
" - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] - m[3][0] * m[2][1] * m[0][2];\n"
|
||||
" float cof20 = m[0][1] * m[1][2] * m[3][3] + m[1][1] * m[3][2] * m[0][3] + m[3][1] * m[0][2] * m[1][3]"
|
||||
" - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] - m[3][1] * m[1][2] * m[0][3];\n"
|
||||
" float cof21 = -(m[0][0] * m[1][2] * m[3][3] + m[1][0] * m[3][2] * m[0][3] + m[3][0] * m[0][2] * m[1][3]"
|
||||
" - m[0][0] * m[3][2] * m[1][3] - m[1][0] * m[0][2] * m[3][3] - m[3][0] * m[1][2] * m[0][3]);\n"
|
||||
" float cof22 = m[0][0] * m[1][1] * m[3][3] + m[1][0] * m[3][1] * m[0][3] + m[3][0] * m[0][1] * m[1][3]"
|
||||
" - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] - m[3][0] * m[1][1] * m[0][3];\n"
|
||||
" float cof23 = -(m[0][0] * m[1][1] * m[3][2] + m[1][0] * m[3][1] * m[0][2] + m[3][0] * m[0][1] * m[1][2]"
|
||||
" - m[0][0] * m[3][1] * m[1][2] - m[1][0] * m[0][1] * m[3][2] - m[3][0] * m[1][1] * m[0][2]);\n"
|
||||
" float cof30 = -(m[0][1] * m[1][2] * m[2][3] + m[1][1] * m[2][2] * m[0][3] + m[2][1] * m[0][2] * m[1][3]"
|
||||
" - m[0][1] * m[2][2] * m[1][3] - m[1][1] * m[0][2] * m[2][3] - m[2][1] * m[1][2] * m[0][3]);\n"
|
||||
" float cof31 = m[0][0] * m[1][2] * m[2][3] + m[1][0] * m[2][2] * m[0][3] + m[2][0] * m[0][2] * m[1][3]"
|
||||
" - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] - m[2][0] * m[1][2] * m[0][3];\n"
|
||||
" float cof32 = -(m[0][0] * m[1][1] * m[2][3] + m[1][0] * m[2][1] * m[0][3] + m[2][0] * m[0][1] * m[1][3]"
|
||||
" - m[0][0] * m[2][1] * m[1][3] - m[1][0] * m[0][1] * m[2][3] - m[2][0] * m[1][1] * m[0][3]);\n"
|
||||
" float cof33 = m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2]"
|
||||
" - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] - m[2][0] * m[1][1] * m[0][2];\n"
|
||||
" float4x4 cof = { cof00, cof10, cof20, cof30, cof01, cof11, cof21, cof31,"
|
||||
" cof02, cof12, cof22, cof32, cof03, cof13, cof23, cof33 };\n"
|
||||
" return cof / determinant(transpose(m));\n"
|
||||
"}\n");
|
||||
}
|
16
src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
vendored
Normal file
16
src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// 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 COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
|
||||
#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
class BuiltInFunctionEmulator;
|
||||
|
||||
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu);
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
|
@ -6,7 +6,9 @@
|
||||
|
||||
#include "compiler/translator/TranslatorESSL.h"
|
||||
#include "compiler/translator/TranslatorGLSL.h"
|
||||
#ifdef ANGLE_ENABLE_HLSL
|
||||
#include "compiler/translator/TranslatorHLSL.h"
|
||||
#endif // ANGLE_ENABLE_HLSL
|
||||
|
||||
//
|
||||
// This function must be provided to create the actual
|
||||
@ -17,14 +19,22 @@ TCompiler* ConstructCompiler(
|
||||
sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
|
||||
{
|
||||
switch (output) {
|
||||
case SH_ESSL_OUTPUT:
|
||||
case SH_ESSL_OUTPUT:
|
||||
return new TranslatorESSL(type, spec);
|
||||
case SH_GLSL_OUTPUT:
|
||||
return new TranslatorGLSL(type, spec);
|
||||
case SH_HLSL9_OUTPUT:
|
||||
case SH_HLSL11_OUTPUT:
|
||||
case SH_GLSL_CORE_OUTPUT:
|
||||
case SH_GLSL_COMPATIBILITY_OUTPUT:
|
||||
return new TranslatorGLSL(type, spec, output);
|
||||
case SH_HLSL9_OUTPUT:
|
||||
case SH_HLSL11_OUTPUT:
|
||||
#ifdef ANGLE_ENABLE_HLSL
|
||||
return new TranslatorHLSL(type, spec, output);
|
||||
default:
|
||||
#else
|
||||
// This compiler is not supported in this
|
||||
// configuration. Return NULL per the ShConstructCompiler API.
|
||||
return NULL;
|
||||
#endif // ANGLE_ENABLE_HLSL
|
||||
default:
|
||||
// Unknown format. Return NULL per the ShConstructCompiler API.
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _COMMON_INCLUDED_
|
||||
#define _COMMON_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_COMMON_H_
|
||||
#define COMPILER_TRANSLATOR_COMMON_H_
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
@ -89,4 +89,4 @@ inline TString str(T i)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#endif // _COMMON_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_COMMON_H_
|
||||
|
@ -4,7 +4,6 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/translator/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/translator/Compiler.h"
|
||||
#include "compiler/translator/DetectCallDepth.h"
|
||||
#include "compiler/translator/ForLoopUnroll.h"
|
||||
@ -126,7 +125,8 @@ TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
|
||||
maxCallStackDepth(0),
|
||||
fragmentPrecisionHigh(false),
|
||||
clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
|
||||
builtInFunctionEmulator(type)
|
||||
builtInFunctionEmulator(),
|
||||
mSourcePath(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -159,33 +159,41 @@ bool TCompiler::Init(const ShBuiltInResources& resources)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TCompiler::compile(const char* const shaderStrings[],
|
||||
size_t numStrings,
|
||||
int compileOptions)
|
||||
TIntermNode *TCompiler::compileTreeForTesting(const char* const shaderStrings[],
|
||||
size_t numStrings, int compileOptions)
|
||||
{
|
||||
return compileTreeImpl(shaderStrings, numStrings, compileOptions);
|
||||
}
|
||||
|
||||
TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
|
||||
size_t numStrings, int compileOptions)
|
||||
{
|
||||
TScopedPoolAllocator scopedAlloc(&allocator);
|
||||
clearResults();
|
||||
|
||||
if (numStrings == 0)
|
||||
return true;
|
||||
ASSERT(numStrings > 0);
|
||||
ASSERT(GetGlobalPoolAllocator());
|
||||
|
||||
// Reset the extension behavior for each compilation unit.
|
||||
ResetExtensionBehavior(extensionBehavior);
|
||||
|
||||
// If compiling for WebGL, validate loop and indexing as well.
|
||||
if (IsWebGLBasedSpec(shaderSpec))
|
||||
compileOptions |= SH_VALIDATE_LOOP_INDEXING;
|
||||
|
||||
// First string is path of source file if flag is set. The actual source follows.
|
||||
const char* sourcePath = NULL;
|
||||
size_t firstSource = 0;
|
||||
if (compileOptions & SH_SOURCE_PATH)
|
||||
{
|
||||
sourcePath = shaderStrings[0];
|
||||
mSourcePath = shaderStrings[0];
|
||||
++firstSource;
|
||||
}
|
||||
|
||||
bool debugShaderPrecision = getResources().WEBGL_debug_shader_precision == 1;
|
||||
TIntermediate intermediate(infoSink);
|
||||
TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
|
||||
shaderType, shaderSpec, compileOptions, true,
|
||||
sourcePath, infoSink);
|
||||
infoSink, debugShaderPrecision);
|
||||
|
||||
parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
|
||||
SetGlobalParseContext(&parseContext);
|
||||
|
||||
@ -206,6 +214,8 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
||||
success = false;
|
||||
}
|
||||
|
||||
TIntermNode *root = NULL;
|
||||
|
||||
if (success)
|
||||
{
|
||||
mPragma = parseContext.pragma();
|
||||
@ -214,7 +224,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
||||
symbolTable.setGlobalInvariant();
|
||||
}
|
||||
|
||||
TIntermNode* root = parseContext.treeRoot;
|
||||
root = parseContext.treeRoot;
|
||||
success = intermediate.postProcess(root);
|
||||
|
||||
// Disallow expressions deemed too complex.
|
||||
@ -255,8 +265,11 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
||||
}
|
||||
|
||||
// Built-in function emulation needs to happen after validateLimitations pass.
|
||||
if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
|
||||
if (success)
|
||||
{
|
||||
initBuiltInFunctionEmulator(&builtInFunctionEmulator, compileOptions);
|
||||
builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
|
||||
}
|
||||
|
||||
// Clamping uniform array bounds needs to happen after validateLimitations pass.
|
||||
if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
|
||||
@ -301,18 +314,37 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
||||
RegenerateStructNames gen(symbolTable, shaderVersion);
|
||||
root->traverse(&gen);
|
||||
}
|
||||
|
||||
if (success && (compileOptions & SH_INTERMEDIATE_TREE))
|
||||
intermediate.outputTree(root);
|
||||
|
||||
if (success && (compileOptions & SH_OBJECT_CODE))
|
||||
translate(root);
|
||||
}
|
||||
|
||||
// Cleanup memory.
|
||||
intermediate.remove(parseContext.treeRoot);
|
||||
SetGlobalParseContext(NULL);
|
||||
return success;
|
||||
if (success)
|
||||
return root;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool TCompiler::compile(const char* const shaderStrings[],
|
||||
size_t numStrings, int compileOptions)
|
||||
{
|
||||
if (numStrings == 0)
|
||||
return true;
|
||||
|
||||
TScopedPoolAllocator scopedAlloc(&allocator);
|
||||
TIntermNode *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
|
||||
|
||||
if (root)
|
||||
{
|
||||
if (compileOptions & SH_INTERMEDIATE_TREE)
|
||||
TIntermediate::outputTree(root, infoSink.info);
|
||||
|
||||
if (compileOptions & SH_OBJECT_CODE)
|
||||
translate(root, compileOptions);
|
||||
|
||||
// The IntermNode tree doesn't need to be deleted here, since the
|
||||
// memory will be freed in a big chunk by the PoolAllocator.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
|
||||
@ -390,11 +422,15 @@ void TCompiler::setResourceString()
|
||||
<< ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
|
||||
<< ":EXT_frag_depth:" << compileResources.EXT_frag_depth
|
||||
<< ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
|
||||
<< ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
|
||||
<< ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
|
||||
<< ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
|
||||
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
|
||||
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
|
||||
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
|
||||
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
|
||||
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers;
|
||||
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers
|
||||
<< ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision;
|
||||
|
||||
builtInResourcesString = strstream.str();
|
||||
}
|
||||
@ -416,27 +452,29 @@ void TCompiler::clearResults()
|
||||
builtInFunctionEmulator.Cleanup();
|
||||
|
||||
nameMap.clear();
|
||||
|
||||
mSourcePath = NULL;
|
||||
}
|
||||
|
||||
bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
|
||||
bool TCompiler::detectCallDepth(TIntermNode* inputRoot, TInfoSink& inputInfoSink, bool limitCallStackDepth)
|
||||
{
|
||||
DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
|
||||
root->traverse(&detect);
|
||||
DetectCallDepth detect(inputInfoSink, limitCallStackDepth, maxCallStackDepth);
|
||||
inputRoot->traverse(&detect);
|
||||
switch (detect.detectCallDepth())
|
||||
{
|
||||
case DetectCallDepth::kErrorNone:
|
||||
return true;
|
||||
case DetectCallDepth::kErrorMissingMain:
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Missing main()";
|
||||
inputInfoSink.info.prefix(EPrefixError);
|
||||
inputInfoSink.info << "Missing main()";
|
||||
return false;
|
||||
case DetectCallDepth::kErrorRecursion:
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Function recursion detected";
|
||||
inputInfoSink.info.prefix(EPrefixError);
|
||||
inputInfoSink.info << "Function recursion detected";
|
||||
return false;
|
||||
case DetectCallDepth::kErrorMaxDepthExceeded:
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Function call stack too deep";
|
||||
inputInfoSink.info.prefix(EPrefixError);
|
||||
inputInfoSink.info << "Function call stack too deep";
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -594,6 +632,11 @@ const TExtensionBehavior& TCompiler::getExtensionBehavior() const
|
||||
return extensionBehavior;
|
||||
}
|
||||
|
||||
const char *TCompiler::getSourcePath() const
|
||||
{
|
||||
return mSourcePath;
|
||||
}
|
||||
|
||||
const ShBuiltInResources& TCompiler::getResources() const
|
||||
{
|
||||
return compileResources;
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _SHHANDLE_INCLUDED_
|
||||
#define _SHHANDLE_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_COMPILER_H_
|
||||
#define COMPILER_TRANSLATOR_COMPILER_H_
|
||||
|
||||
//
|
||||
// Machine independent part of the compiler private objects
|
||||
@ -25,7 +25,9 @@
|
||||
|
||||
class TCompiler;
|
||||
class TDependencyGraph;
|
||||
#ifdef ANGLE_ENABLE_HLSL
|
||||
class TranslatorHLSL;
|
||||
#endif // ANGLE_ENABLE_HLSL
|
||||
|
||||
//
|
||||
// Helper function to identify specs that are based on the WebGL spec,
|
||||
@ -41,7 +43,9 @@ public:
|
||||
TShHandleBase();
|
||||
virtual ~TShHandleBase();
|
||||
virtual TCompiler* getAsCompiler() { return 0; }
|
||||
#ifdef ANGLE_ENABLE_HLSL
|
||||
virtual TranslatorHLSL* getAsTranslatorHLSL() { return 0; }
|
||||
#endif // ANGLE_ENABLE_HLSL
|
||||
|
||||
protected:
|
||||
// Memory allocator. Allocates and tracks memory required by the compiler.
|
||||
@ -61,9 +65,15 @@ class TCompiler : public TShHandleBase
|
||||
virtual TCompiler* getAsCompiler() { return this; }
|
||||
|
||||
bool Init(const ShBuiltInResources& resources);
|
||||
|
||||
// compileTreeForTesting should be used only when tests require access to
|
||||
// the AST. Users of this function need to manually manage the global pool
|
||||
// allocator. Returns NULL whenever there are compilation errors.
|
||||
TIntermNode *compileTreeForTesting(const char* const shaderStrings[],
|
||||
size_t numStrings, int compileOptions);
|
||||
|
||||
bool compile(const char* const shaderStrings[],
|
||||
size_t numStrings,
|
||||
int compileOptions);
|
||||
size_t numStrings, int compileOptions);
|
||||
|
||||
// Get results of the last compilation.
|
||||
int getShaderVersion() const { return shaderVersion; }
|
||||
@ -104,8 +114,10 @@ class TCompiler : public TShHandleBase
|
||||
bool validateLimitations(TIntermNode* root);
|
||||
// Collect info for all attribs, uniforms, varyings.
|
||||
void collectVariables(TIntermNode* root);
|
||||
// Add emulated functions to the built-in function emulator.
|
||||
virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) {};
|
||||
// Translate to object code.
|
||||
virtual void translate(TIntermNode* root) = 0;
|
||||
virtual void translate(TIntermNode *root, int compileOptions) = 0;
|
||||
// Returns true if, after applying the packing rules in the GLSL 1.017 spec
|
||||
// Appendix A, section 7, the shader does not use too many uniforms.
|
||||
bool enforcePackingRestrictions();
|
||||
@ -130,6 +142,7 @@ class TCompiler : public TShHandleBase
|
||||
bool limitExpressionComplexity(TIntermNode* root);
|
||||
// Get built-in extensions with default behavior.
|
||||
const TExtensionBehavior& getExtensionBehavior() const;
|
||||
const char *getSourcePath() const;
|
||||
const TPragma& getPragma() const { return mPragma; }
|
||||
void writePragma();
|
||||
|
||||
@ -145,6 +158,9 @@ class TCompiler : public TShHandleBase
|
||||
std::vector<sh::InterfaceBlock> interfaceBlocks;
|
||||
|
||||
private:
|
||||
TIntermNode *compileTreeImpl(const char* const shaderStrings[],
|
||||
size_t numStrings, int compileOptions);
|
||||
|
||||
sh::GLenum shaderType;
|
||||
ShShaderSpec shaderSpec;
|
||||
ShShaderOutput outputType;
|
||||
@ -170,6 +186,7 @@ class TCompiler : public TShHandleBase
|
||||
// Results of compilation.
|
||||
int shaderVersion;
|
||||
TInfoSink infoSink; // Output sink.
|
||||
const char *mSourcePath; // Path of source file or NULL
|
||||
|
||||
// name hashing.
|
||||
ShHashFunction64 hashFunction;
|
||||
@ -191,4 +208,4 @@ TCompiler* ConstructCompiler(
|
||||
sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
|
||||
void DeleteCompiler(TCompiler*);
|
||||
|
||||
#endif // _SHHANDLE_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_COMPILER_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _CONSTANT_UNION_INCLUDED_
|
||||
#define _CONSTANT_UNION_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_CONSTANTUNION_H_
|
||||
#define COMPILER_TRANSLATOR_CONSTANTUNION_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@ -254,7 +254,10 @@ public:
|
||||
ConstantUnion operator<<(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
// The signedness of the second parameter might be different, but we
|
||||
// don't care, since the result is undefined if the second parameter is
|
||||
// negative, and aliasing should not be a problem with unions.
|
||||
assert(constant.type == EbtInt || constant.type == EbtUInt);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
|
||||
case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break;
|
||||
@ -267,7 +270,7 @@ public:
|
||||
ConstantUnion operator&(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
assert(constant.type == EbtInt || constant.type == EbtUInt);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
|
||||
case EbtUInt: returnValue.setUConst(uConst & constant.uConst); break;
|
||||
@ -340,4 +343,4 @@ private:
|
||||
TBasicType type;
|
||||
};
|
||||
|
||||
#endif // _CONSTANT_UNION_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_
|
||||
|
@ -33,7 +33,7 @@ int DetectCallDepth::FunctionNode::detectCallDepth(DetectCallDepth* detectCallDe
|
||||
ASSERT(visit == PreVisit);
|
||||
ASSERT(detectCallDepth);
|
||||
|
||||
int maxDepth = depth;
|
||||
int retMaxDepth = depth;
|
||||
visit = InVisit;
|
||||
for (size_t i = 0; i < callees.size(); ++i) {
|
||||
switch (callees[i]->visit) {
|
||||
@ -52,7 +52,7 @@ int DetectCallDepth::FunctionNode::detectCallDepth(DetectCallDepth* detectCallDe
|
||||
detectCallDepth->getInfoSink().info << "<-" << callees[i]->getName();
|
||||
return callDepth;
|
||||
}
|
||||
maxDepth = std::max(callDepth, maxDepth);
|
||||
retMaxDepth = std::max(callDepth, retMaxDepth);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -61,7 +61,7 @@ int DetectCallDepth::FunctionNode::detectCallDepth(DetectCallDepth* detectCallDe
|
||||
}
|
||||
}
|
||||
visit = PostVisit;
|
||||
return maxDepth;
|
||||
return retMaxDepth;
|
||||
}
|
||||
|
||||
void DetectCallDepth::FunctionNode::reset()
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_DETECT_RECURSION_H_
|
||||
#define COMPILER_DETECT_RECURSION_H_
|
||||
#ifndef COMPILER_TRANSLATOR_DETECTCALLDEPTH_H_
|
||||
#define COMPILER_TRANSLATOR_DETECTCALLDEPTH_H_
|
||||
|
||||
#include <limits.h>
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
@ -75,4 +75,4 @@ private:
|
||||
void operator=(const DetectCallDepth&);
|
||||
};
|
||||
|
||||
#endif // COMPILER_DETECT_RECURSION_H_
|
||||
#endif // COMPILER_TRANSLATOR_DETECTCALLDEPTH_H_
|
||||
|
@ -8,8 +8,8 @@
|
||||
// gradients of functions with discontinuities.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_DETECTDISCONTINUITY_H_
|
||||
#define COMPILER_DETECTDISCONTINUITY_H_
|
||||
#ifndef COMPILER_TRANSLATOR_DETECTDISCONTINUITY_H_
|
||||
#define COMPILER_TRANSLATOR_DETECTDISCONTINUITY_H_
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
@ -68,4 +68,4 @@ bool containsGradientOperation(TIntermNode *node);
|
||||
|
||||
}
|
||||
|
||||
#endif // COMPILER_DETECTDISCONTINUITY_H_
|
||||
#endif // COMPILER_TRANSLATOR_DETECTDISCONTINUITY_H_
|
||||
|
@ -4,14 +4,15 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_DIAGNOSTICS_H_
|
||||
#define COMPILER_DIAGNOSTICS_H_
|
||||
#ifndef COMPILER_TRANSLATOR_DIAGNOSTICS_H_
|
||||
#define COMPILER_TRANSLATOR_DIAGNOSTICS_H_
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||
|
||||
class TInfoSink;
|
||||
|
||||
class TDiagnostics : public pp::Diagnostics
|
||||
class TDiagnostics : public pp::Diagnostics, angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
TDiagnostics(TInfoSink& infoSink);
|
||||
@ -41,4 +42,4 @@ class TDiagnostics : public pp::Diagnostics
|
||||
int mNumWarnings;
|
||||
};
|
||||
|
||||
#endif // COMPILER_DIAGNOSTICS_H_
|
||||
#endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_
|
||||
|
@ -27,10 +27,12 @@ static TBehavior getBehavior(const std::string& str)
|
||||
|
||||
TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
|
||||
TDiagnostics& diagnostics,
|
||||
int& shaderVersion)
|
||||
int& shaderVersion,
|
||||
bool debugShaderPrecisionSupported)
|
||||
: mExtensionBehavior(extBehavior),
|
||||
mDiagnostics(diagnostics),
|
||||
mShaderVersion(shaderVersion)
|
||||
mShaderVersion(shaderVersion),
|
||||
mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
|
||||
{
|
||||
}
|
||||
|
||||
@ -65,6 +67,7 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
|
||||
{
|
||||
const char kOptimize[] = "optimize";
|
||||
const char kDebug[] = "debug";
|
||||
const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
|
||||
const char kOn[] = "on";
|
||||
const char kOff[] = "off";
|
||||
|
||||
@ -81,6 +84,12 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
|
||||
else if (value == kOff) mPragma.debug = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
|
||||
{
|
||||
if (value == kOn) mPragma.debugShaderPrecision = true;
|
||||
else if (value == kOff) mPragma.debugShaderPrecision = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
|
||||
|
@ -4,21 +4,23 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_DIRECTIVE_HANDLER_H_
|
||||
#define COMPILER_DIRECTIVE_HANDLER_H_
|
||||
#ifndef COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
|
||||
#define COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/translator/ExtensionBehavior.h"
|
||||
#include "compiler/translator/Pragma.h"
|
||||
#include "compiler/preprocessor/DirectiveHandlerBase.h"
|
||||
|
||||
class TDiagnostics;
|
||||
|
||||
class TDirectiveHandler : public pp::DirectiveHandler
|
||||
class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
TDirectiveHandler(TExtensionBehavior& extBehavior,
|
||||
TDiagnostics& diagnostics,
|
||||
int& shaderVersion);
|
||||
int& shaderVersion,
|
||||
bool debugShaderPrecisionSupported);
|
||||
virtual ~TDirectiveHandler();
|
||||
|
||||
const TPragma& pragma() const { return mPragma; }
|
||||
@ -44,6 +46,7 @@ class TDirectiveHandler : public pp::DirectiveHandler
|
||||
TExtensionBehavior& mExtensionBehavior;
|
||||
TDiagnostics& mDiagnostics;
|
||||
int& mShaderVersion;
|
||||
bool mDebugShaderPrecisionSupported;
|
||||
};
|
||||
|
||||
#endif // COMPILER_DIRECTIVE_HANDLER_H_
|
||||
#endif // COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
|
||||
|
528
src/3rdparty/angle/src/compiler/translator/EmulatePrecision.cpp
vendored
Normal file
528
src/3rdparty/angle/src/compiler/translator/EmulatePrecision.cpp
vendored
Normal file
@ -0,0 +1,528 @@
|
||||
//
|
||||
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/translator/EmulatePrecision.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
static void writeVectorPrecisionEmulationHelpers(
|
||||
TInfoSinkBase& sink, ShShaderOutput outputLanguage, unsigned int size)
|
||||
{
|
||||
std::stringstream vecTypeStrStr;
|
||||
if (outputLanguage == SH_ESSL_OUTPUT)
|
||||
vecTypeStrStr << "highp ";
|
||||
vecTypeStrStr << "vec" << size;
|
||||
std::string vecType = vecTypeStrStr.str();
|
||||
|
||||
sink <<
|
||||
vecType << " angle_frm(in " << vecType << " v) {\n"
|
||||
" v = clamp(v, -65504.0, 65504.0);\n"
|
||||
" " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
|
||||
" bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n"
|
||||
" v = v * exp2(-exponent);\n"
|
||||
" v = sign(v) * floor(abs(v));\n"
|
||||
" return v * exp2(exponent) * vec" << size << "(isNonZero);\n"
|
||||
"}\n";
|
||||
|
||||
sink <<
|
||||
vecType << " angle_frl(in " << vecType << " v) {\n"
|
||||
" v = clamp(v, -2.0, 2.0);\n"
|
||||
" v = v * 256.0;\n"
|
||||
" v = sign(v) * floor(abs(v));\n"
|
||||
" return v * 0.00390625;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
static void writeMatrixPrecisionEmulationHelper(
|
||||
TInfoSinkBase& sink, ShShaderOutput outputLanguage, unsigned int size, const char *functionName)
|
||||
{
|
||||
std::stringstream matTypeStrStr;
|
||||
if (outputLanguage == SH_ESSL_OUTPUT)
|
||||
matTypeStrStr << "highp ";
|
||||
matTypeStrStr << "mat" << size;
|
||||
std::string matType = matTypeStrStr.str();
|
||||
|
||||
sink << matType << " " << functionName << "(in " << matType << " m) {\n"
|
||||
" " << matType << " rounded;\n";
|
||||
|
||||
for (unsigned int i = 0; i < size; ++i)
|
||||
{
|
||||
sink << " rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
|
||||
}
|
||||
|
||||
sink << " return rounded;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
static void writeCommonPrecisionEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage)
|
||||
{
|
||||
// Write the angle_frm functions that round floating point numbers to
|
||||
// half precision, and angle_frl functions that round them to minimum lowp
|
||||
// precision.
|
||||
|
||||
// Unoptimized version of angle_frm for single floats:
|
||||
//
|
||||
// int webgl_maxNormalExponent(in int exponentBits) {
|
||||
// int possibleExponents = int(exp2(float(exponentBits)));
|
||||
// int exponentBias = possibleExponents / 2 - 1;
|
||||
// int allExponentBitsOne = possibleExponents - 1;
|
||||
// return (allExponentBitsOne - 1) - exponentBias;
|
||||
// }
|
||||
//
|
||||
// float angle_frm(in float x) {
|
||||
// int mantissaBits = 10;
|
||||
// int exponentBits = 5;
|
||||
// float possibleMantissas = exp2(float(mantissaBits));
|
||||
// float mantissaMax = 2.0 - 1.0 / possibleMantissas;
|
||||
// int maxNE = webgl_maxNormalExponent(exponentBits);
|
||||
// float max = exp2(float(maxNE)) * mantissaMax;
|
||||
// if (x > max) {
|
||||
// return max;
|
||||
// }
|
||||
// if (x < -max) {
|
||||
// return -max;
|
||||
// }
|
||||
// float exponent = floor(log2(abs(x)));
|
||||
// if (abs(x) == 0.0 || exponent < -float(maxNE)) {
|
||||
// return 0.0 * sign(x)
|
||||
// }
|
||||
// x = x * exp2(-(exponent - float(mantissaBits)));
|
||||
// x = sign(x) * floor(abs(x));
|
||||
// return x * exp2(exponent - float(mantissaBits));
|
||||
// }
|
||||
|
||||
// All numbers with a magnitude less than 2^-15 are subnormal, and are
|
||||
// flushed to zero.
|
||||
|
||||
// Note the constant numbers below:
|
||||
// a) 65504 is the maximum possible mantissa (1.1111111111 in binary) times
|
||||
// 2^15, the maximum normal exponent.
|
||||
// b) 10.0 is the number of mantissa bits.
|
||||
// c) -25.0 is the minimum normal half-float exponent -15.0 minus the number
|
||||
// of mantissa bits.
|
||||
// d) + 1e-30 is to make sure the argument of log2() won't be zero. It can
|
||||
// only affect the result of log2 on x where abs(x) < 1e-22. Since these
|
||||
// numbers will be flushed to zero either way (2^-15 is the smallest
|
||||
// normal positive number), this does not introduce any error.
|
||||
|
||||
std::string floatType = "float";
|
||||
if (outputLanguage == SH_ESSL_OUTPUT)
|
||||
floatType = "highp float";
|
||||
|
||||
sink <<
|
||||
floatType << " angle_frm(in " << floatType << " x) {\n"
|
||||
" x = clamp(x, -65504.0, 65504.0);\n"
|
||||
" " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n"
|
||||
" bool isNonZero = (exponent >= -25.0);\n"
|
||||
" x = x * exp2(-exponent);\n"
|
||||
" x = sign(x) * floor(abs(x));\n"
|
||||
" return x * exp2(exponent) * float(isNonZero);\n"
|
||||
"}\n";
|
||||
|
||||
sink <<
|
||||
floatType << " angle_frl(in " << floatType << " x) {\n"
|
||||
" x = clamp(x, -2.0, 2.0);\n"
|
||||
" x = x * 256.0;\n"
|
||||
" x = sign(x) * floor(abs(x));\n"
|
||||
" return x * 0.00390625;\n"
|
||||
"}\n";
|
||||
|
||||
writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 2);
|
||||
writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 3);
|
||||
writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 4);
|
||||
for (unsigned int size = 2; size <= 4; ++size)
|
||||
{
|
||||
writeMatrixPrecisionEmulationHelper(sink, outputLanguage, size, "angle_frm");
|
||||
writeMatrixPrecisionEmulationHelper(sink, outputLanguage, size, "angle_frl");
|
||||
}
|
||||
}
|
||||
|
||||
static void writeCompoundAssignmentPrecisionEmulation(
|
||||
TInfoSinkBase& sink, ShShaderOutput outputLanguage,
|
||||
const char *lType, const char *rType, const char *opStr, const char *opNameStr)
|
||||
{
|
||||
std::string lTypeStr = lType;
|
||||
std::string rTypeStr = rType;
|
||||
if (outputLanguage == SH_ESSL_OUTPUT)
|
||||
{
|
||||
std::stringstream lTypeStrStr;
|
||||
lTypeStrStr << "highp " << lType;
|
||||
lTypeStr = lTypeStrStr.str();
|
||||
std::stringstream rTypeStrStr;
|
||||
rTypeStrStr << "highp " << rType;
|
||||
rTypeStr = rTypeStrStr.str();
|
||||
}
|
||||
|
||||
// Note that y should be passed through angle_frm at the function call site,
|
||||
// but x can't be passed through angle_frm there since it is an inout parameter.
|
||||
// So only pass x and the result through angle_frm here.
|
||||
sink <<
|
||||
lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
|
||||
" x = angle_frm(angle_frm(x) " << opStr << " y);\n"
|
||||
" return x;\n"
|
||||
"}\n";
|
||||
sink <<
|
||||
lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
|
||||
" x = angle_frl(angle_frm(x) " << opStr << " y);\n"
|
||||
" return x;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *getFloatTypeStr(const TType& type)
|
||||
{
|
||||
switch (type.getNominalSize())
|
||||
{
|
||||
case 1:
|
||||
return "float";
|
||||
case 2:
|
||||
return type.getSecondarySize() > 1 ? "mat2" : "vec2";
|
||||
case 3:
|
||||
return type.getSecondarySize() > 1 ? "mat3" : "vec3";
|
||||
case 4:
|
||||
return type.getSecondarySize() > 1 ? "mat4" : "vec4";
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool canRoundFloat(const TType &type)
|
||||
{
|
||||
return type.getBasicType() == EbtFloat && !type.isNonSquareMatrix() && !type.isArray() &&
|
||||
(type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium);
|
||||
}
|
||||
|
||||
TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *child)
|
||||
{
|
||||
TIntermAggregate *callNode = new TIntermAggregate();
|
||||
callNode->setOp(EOpInternalFunctionCall);
|
||||
callNode->setName(name);
|
||||
callNode->getSequence()->push_back(child);
|
||||
return callNode;
|
||||
}
|
||||
|
||||
TIntermAggregate *createRoundingFunctionCallNode(TIntermTyped *roundedChild)
|
||||
{
|
||||
TString roundFunctionName;
|
||||
if (roundedChild->getPrecision() == EbpMedium)
|
||||
roundFunctionName = "angle_frm";
|
||||
else
|
||||
roundFunctionName = "angle_frl";
|
||||
return createInternalFunctionCallNode(roundFunctionName, roundedChild);
|
||||
}
|
||||
|
||||
TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left, TIntermTyped *right, const char *opNameStr)
|
||||
{
|
||||
std::stringstream strstr;
|
||||
if (left->getPrecision() == EbpMedium)
|
||||
strstr << "angle_compound_" << opNameStr << "_frm";
|
||||
else
|
||||
strstr << "angle_compound_" << opNameStr << "_frl";
|
||||
TString functionName = strstr.str().c_str();
|
||||
TIntermAggregate *callNode = createInternalFunctionCallNode(functionName, left);
|
||||
callNode->getSequence()->push_back(right);
|
||||
return callNode;
|
||||
}
|
||||
|
||||
bool parentUsesResult(TIntermNode* parent, TIntermNode* node)
|
||||
{
|
||||
if (!parent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TIntermAggregate *aggParent = parent->getAsAggregate();
|
||||
// If the parent's op is EOpSequence, the result is not assigned anywhere,
|
||||
// so rounding it is not needed. In particular, this can avoid a lot of
|
||||
// unnecessary rounding of unused return values of assignment.
|
||||
if (aggParent && aggParent->getOp() == EOpSequence)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (aggParent && aggParent->getOp() == EOpComma && (aggParent->getSequence()->back() != node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace anonymous
|
||||
|
||||
EmulatePrecision::EmulatePrecision()
|
||||
: TIntermTraverser(true, true, true),
|
||||
mDeclaringVariables(false),
|
||||
mInLValue(false),
|
||||
mInFunctionCallOutParameter(false)
|
||||
{}
|
||||
|
||||
void EmulatePrecision::visitSymbol(TIntermSymbol *node)
|
||||
{
|
||||
if (canRoundFloat(node->getType()) &&
|
||||
!mDeclaringVariables && !mInLValue && !mInFunctionCallOutParameter)
|
||||
{
|
||||
TIntermNode *parent = getParentNode();
|
||||
TIntermNode *replacement = createRoundingFunctionCallNode(node);
|
||||
mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
|
||||
{
|
||||
bool visitChildren = true;
|
||||
|
||||
if (node->isAssignment())
|
||||
{
|
||||
if (visit == PreVisit)
|
||||
mInLValue = true;
|
||||
else if (visit == InVisit)
|
||||
mInLValue = false;
|
||||
}
|
||||
|
||||
TOperator op = node->getOp();
|
||||
|
||||
// RHS of initialize is not being declared.
|
||||
if (op == EOpInitialize && visit == InVisit)
|
||||
mDeclaringVariables = false;
|
||||
|
||||
if ((op == EOpIndexDirectStruct || op == EOpVectorSwizzle) && visit == InVisit)
|
||||
visitChildren = false;
|
||||
|
||||
if (visit != PreVisit)
|
||||
return visitChildren;
|
||||
|
||||
const TType& type = node->getType();
|
||||
bool roundFloat = canRoundFloat(type);
|
||||
|
||||
if (roundFloat) {
|
||||
switch (op) {
|
||||
// Math operators that can result in a float may need to apply rounding to the return
|
||||
// value. Note that in the case of assignment, the rounding is applied to its return
|
||||
// value here, not the value being assigned.
|
||||
case EOpAssign:
|
||||
case EOpAdd:
|
||||
case EOpSub:
|
||||
case EOpMul:
|
||||
case EOpDiv:
|
||||
case EOpVectorTimesScalar:
|
||||
case EOpVectorTimesMatrix:
|
||||
case EOpMatrixTimesVector:
|
||||
case EOpMatrixTimesScalar:
|
||||
case EOpMatrixTimesMatrix:
|
||||
{
|
||||
TIntermNode *parent = getParentNode();
|
||||
if (!parentUsesResult(parent, node))
|
||||
{
|
||||
break;
|
||||
}
|
||||
TIntermNode *replacement = createRoundingFunctionCallNode(node);
|
||||
mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
|
||||
break;
|
||||
}
|
||||
|
||||
// Compound assignment cases need to replace the operator with a function call.
|
||||
case EOpAddAssign:
|
||||
{
|
||||
mEmulateCompoundAdd.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType())));
|
||||
TIntermNode *parent = getParentNode();
|
||||
TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "add");
|
||||
mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
|
||||
break;
|
||||
}
|
||||
case EOpSubAssign:
|
||||
{
|
||||
mEmulateCompoundSub.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType())));
|
||||
TIntermNode *parent = getParentNode();
|
||||
TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "sub");
|
||||
mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
|
||||
break;
|
||||
}
|
||||
case EOpMulAssign:
|
||||
case EOpVectorTimesMatrixAssign:
|
||||
case EOpVectorTimesScalarAssign:
|
||||
case EOpMatrixTimesScalarAssign:
|
||||
case EOpMatrixTimesMatrixAssign:
|
||||
{
|
||||
mEmulateCompoundMul.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType())));
|
||||
TIntermNode *parent = getParentNode();
|
||||
TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "mul");
|
||||
mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
|
||||
break;
|
||||
}
|
||||
case EOpDivAssign:
|
||||
{
|
||||
mEmulateCompoundDiv.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType())));
|
||||
TIntermNode *parent = getParentNode();
|
||||
TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "div");
|
||||
mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// The rest of the binary operations should not need precision emulation.
|
||||
break;
|
||||
}
|
||||
}
|
||||
return visitChildren;
|
||||
}
|
||||
|
||||
bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
{
|
||||
bool visitChildren = true;
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpSequence:
|
||||
case EOpConstructStruct:
|
||||
// No special handling
|
||||
break;
|
||||
case EOpFunction:
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
const TIntermSequence &sequence = *(node->getSequence());
|
||||
TIntermSequence::const_iterator seqIter = sequence.begin();
|
||||
TIntermAggregate *params = (*seqIter)->getAsAggregate();
|
||||
ASSERT(params != NULL);
|
||||
ASSERT(params->getOp() == EOpParameters);
|
||||
mFunctionMap[node->getName()] = params->getSequence();
|
||||
}
|
||||
break;
|
||||
case EOpPrototype:
|
||||
if (visit == PreVisit)
|
||||
mFunctionMap[node->getName()] = node->getSequence();
|
||||
visitChildren = false;
|
||||
break;
|
||||
case EOpParameters:
|
||||
visitChildren = false;
|
||||
break;
|
||||
case EOpInvariantDeclaration:
|
||||
visitChildren = false;
|
||||
break;
|
||||
case EOpDeclaration:
|
||||
// Variable declaration.
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
mDeclaringVariables = true;
|
||||
}
|
||||
else if (visit == InVisit)
|
||||
{
|
||||
mDeclaringVariables = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDeclaringVariables = false;
|
||||
}
|
||||
break;
|
||||
case EOpFunctionCall:
|
||||
{
|
||||
// Function call.
|
||||
bool inFunctionMap = (mFunctionMap.find(node->getName()) != mFunctionMap.end());
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
// User-defined function return values are not rounded, this relies on that
|
||||
// calculations producing the value were rounded.
|
||||
TIntermNode *parent = getParentNode();
|
||||
if (canRoundFloat(node->getType()) && !inFunctionMap && parentUsesResult(parent, node))
|
||||
{
|
||||
TIntermNode *replacement = createRoundingFunctionCallNode(node);
|
||||
mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
|
||||
}
|
||||
|
||||
if (inFunctionMap)
|
||||
{
|
||||
mSeqIterStack.push_back(mFunctionMap[node->getName()]->begin());
|
||||
if (mSeqIterStack.back() != mFunctionMap[node->getName()]->end())
|
||||
{
|
||||
TQualifier qualifier = (*mSeqIterStack.back())->getAsTyped()->getQualifier();
|
||||
mInFunctionCallOutParameter = (qualifier == EvqOut || qualifier == EvqInOut);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The function is not user-defined - it is likely built-in texture function.
|
||||
// Assume that those do not have out parameters.
|
||||
mInFunctionCallOutParameter = false;
|
||||
}
|
||||
}
|
||||
else if (visit == InVisit)
|
||||
{
|
||||
if (inFunctionMap)
|
||||
{
|
||||
++mSeqIterStack.back();
|
||||
TQualifier qualifier = (*mSeqIterStack.back())->getAsTyped()->getQualifier();
|
||||
mInFunctionCallOutParameter = (qualifier == EvqOut || qualifier == EvqInOut);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inFunctionMap)
|
||||
{
|
||||
mSeqIterStack.pop_back();
|
||||
mInFunctionCallOutParameter = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
TIntermNode *parent = getParentNode();
|
||||
if (canRoundFloat(node->getType()) && visit == PreVisit && parentUsesResult(parent, node))
|
||||
{
|
||||
TIntermNode *replacement = createRoundingFunctionCallNode(node);
|
||||
mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return visitChildren;
|
||||
}
|
||||
|
||||
bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node)
|
||||
{
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpNegative:
|
||||
case EOpVectorLogicalNot:
|
||||
case EOpLogicalNot:
|
||||
break;
|
||||
case EOpPostIncrement:
|
||||
case EOpPostDecrement:
|
||||
case EOpPreIncrement:
|
||||
case EOpPreDecrement:
|
||||
if (visit == PreVisit)
|
||||
mInLValue = true;
|
||||
else if (visit == PostVisit)
|
||||
mInLValue = false;
|
||||
break;
|
||||
default:
|
||||
if (canRoundFloat(node->getType()) && visit == PreVisit)
|
||||
{
|
||||
TIntermNode *parent = getParentNode();
|
||||
TIntermNode *replacement = createRoundingFunctionCallNode(node);
|
||||
mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage)
|
||||
{
|
||||
// Other languages not yet supported
|
||||
ASSERT(outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
|
||||
outputLanguage == SH_GLSL_CORE_OUTPUT ||
|
||||
outputLanguage == SH_ESSL_OUTPUT);
|
||||
writeCommonPrecisionEmulationHelpers(sink, outputLanguage);
|
||||
|
||||
EmulationSet::const_iterator it;
|
||||
for (it = mEmulateCompoundAdd.begin(); it != mEmulateCompoundAdd.end(); it++)
|
||||
writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "+", "add");
|
||||
for (it = mEmulateCompoundSub.begin(); it != mEmulateCompoundSub.end(); it++)
|
||||
writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "-", "sub");
|
||||
for (it = mEmulateCompoundDiv.begin(); it != mEmulateCompoundDiv.end(); it++)
|
||||
writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "/", "div");
|
||||
for (it = mEmulateCompoundMul.begin(); it != mEmulateCompoundMul.end(); it++)
|
||||
writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "*", "mul");
|
||||
}
|
||||
|
74
src/3rdparty/angle/src/compiler/translator/EmulatePrecision.h
vendored
Normal file
74
src/3rdparty/angle/src/compiler/translator/EmulatePrecision.h
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
//
|
||||
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
|
||||
#define COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/translator/InfoSink.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
// This class gathers all compound assignments from the AST and can then write
|
||||
// the functions required for their precision emulation. This way there is no
|
||||
// need to write a huge number of variations of the emulated compound assignment
|
||||
// to every translated shader with emulation enabled.
|
||||
|
||||
class EmulatePrecision : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
EmulatePrecision();
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol *node);
|
||||
virtual bool visitBinary(Visit visit, TIntermBinary *node);
|
||||
virtual bool visitUnary(Visit visit, TIntermUnary *node);
|
||||
virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
|
||||
|
||||
void writeEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage);
|
||||
|
||||
private:
|
||||
struct TypePair
|
||||
{
|
||||
TypePair(const char *l, const char *r)
|
||||
: lType(l), rType(r) { }
|
||||
|
||||
const char *lType;
|
||||
const char *rType;
|
||||
};
|
||||
|
||||
struct TypePairComparator
|
||||
{
|
||||
bool operator() (const TypePair& l, const TypePair& r) const
|
||||
{
|
||||
if (l.lType == r.lType)
|
||||
return l.rType < r.rType;
|
||||
return l.lType < r.lType;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::set<TypePair, TypePairComparator> EmulationSet;
|
||||
EmulationSet mEmulateCompoundAdd;
|
||||
EmulationSet mEmulateCompoundSub;
|
||||
EmulationSet mEmulateCompoundMul;
|
||||
EmulationSet mEmulateCompoundDiv;
|
||||
|
||||
// Stack of function call parameter iterators
|
||||
std::vector<TIntermSequence::const_iterator> mSeqIterStack;
|
||||
|
||||
bool mDeclaringVariables;
|
||||
bool mInLValue;
|
||||
bool mInFunctionCallOutParameter;
|
||||
|
||||
struct TStringComparator
|
||||
{
|
||||
bool operator() (const TString& a, const TString& b) const { return a.compare(b) < 0; }
|
||||
};
|
||||
|
||||
// Map from function names to their parameter sequences
|
||||
std::map<TString, TIntermSequence*, TStringComparator> mFunctionMap;
|
||||
};
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _EXTENSION_BEHAVIOR_INCLUDED_
|
||||
#define _EXTENSION_BEHAVIOR_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
|
||||
#define COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
@ -34,4 +34,4 @@ inline const char* getBehaviorString(TBehavior b)
|
||||
// Mapping between extension name and behavior.
|
||||
typedef std::map<std::string, TBehavior> TExtensionBehavior;
|
||||
|
||||
#endif // _EXTENSION_TABLE_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_FLAGSTD140STRUCTS_H_
|
||||
#define COMPILER_FLAGSTD140STRUCTS_H_
|
||||
#ifndef COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
|
||||
#define COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
@ -34,4 +34,4 @@ std::vector<TIntermTyped *> FlagStd140ValueStructs(TIntermNode *node);
|
||||
|
||||
}
|
||||
|
||||
#endif // COMPILER_FLAGSTD140STRUCTS_H_
|
||||
#endif // COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_FORLOOPUNROLL_H_
|
||||
#define COMPILER_FORLOOPUNROLL_H_
|
||||
#ifndef COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
|
||||
#define COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
|
||||
|
||||
#include "compiler/translator/LoopInfo.h"
|
||||
|
||||
@ -47,4 +47,4 @@ class ForLoopUnrollMarker : public TIntermTraverser
|
||||
bool mVisitSamplerArrayIndexNodeInsideLoop;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_HASH_NAMES_H_
|
||||
#define COMPILER_HASH_NAMES_H_
|
||||
#ifndef COMPILER_TRANSLATOR_HASHNAMES_H_
|
||||
#define COMPILER_TRANSLATOR_HASHNAMES_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
@ -15,4 +15,4 @@
|
||||
|
||||
typedef std::map<TPersistString, TPersistString> NameMap;
|
||||
|
||||
#endif // COMPILER_HASH_NAMES_H_
|
||||
#endif // COMPILER_TRANSLATOR_HASHNAMES_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _INFOSINK_INCLUDED_
|
||||
#define _INFOSINK_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_INFOSINK_H_
|
||||
#define COMPILER_TRANSLATOR_INFOSINK_H_
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
@ -113,4 +113,4 @@ public:
|
||||
TInfoSinkBase obj;
|
||||
};
|
||||
|
||||
#endif // _INFOSINK_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_INFOSINK_H_
|
||||
|
@ -21,307 +21,208 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
|
||||
TType *float2 = new TType(EbtFloat, 2);
|
||||
TType *float3 = new TType(EbtFloat, 3);
|
||||
TType *float4 = new TType(EbtFloat, 4);
|
||||
|
||||
TType *int1 = new TType(EbtInt);
|
||||
TType *int2 = new TType(EbtInt, 2);
|
||||
TType *int3 = new TType(EbtInt, 3);
|
||||
TType *int4 = new TType(EbtInt, 4);
|
||||
TType *uint1 = new TType(EbtUInt);
|
||||
TType *bool1 = new TType(EbtBool);
|
||||
TType *genType = new TType(EbtGenType);
|
||||
TType *genIType = new TType(EbtGenIType);
|
||||
TType *genUType = new TType(EbtGenUType);
|
||||
TType *genBType = new TType(EbtGenBType);
|
||||
|
||||
//
|
||||
// Angle and Trigonometric Functions.
|
||||
//
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "radians", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "radians", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "radians", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "radians", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "degrees", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "degrees", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "degrees", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "degrees", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "sin", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "sin", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "sin", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "sin", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "cos", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "cos", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "cos", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "cos", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "tan", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "tan", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "tan", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "tan", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "asin", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "asin", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "asin", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "asin", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "acos", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "acos", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "acos", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "acos", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "atan", float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "atan", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "atan", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "atan", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "atan", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "atan", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "atan", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "atan", float4);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRadians, genType, "radians", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDegrees, genType, "degrees", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSin, genType, "sin", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCos, genType, "cos", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpTan, genType, "tan", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAsin, genType, "asin", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAcos, genType, "acos", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAtan, genType, "atan", genType, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAtan, genType, "atan", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSinh, genType, "sinh", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpCosh, genType, "cosh", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTanh, genType, "tanh", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAsinh, genType, "asinh", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAcosh, genType, "acosh", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAtanh, genType, "atanh", genType);
|
||||
|
||||
//
|
||||
// Exponential Functions.
|
||||
//
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "pow", float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "pow", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "pow", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "pow", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "exp", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "exp", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "exp", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "exp", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "log", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "log", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "log", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "log", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "exp2", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "exp2", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "exp2", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "exp2", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "log2", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "log2", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "log2", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "log2", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "sqrt", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "sqrt", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "sqrt", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "sqrt", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "inversesqrt", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "inversesqrt", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "inversesqrt", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "inversesqrt", float4);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpPow, genType, "pow", genType, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpExp, genType, "exp", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLog, genType, "log", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpExp2, genType, "exp2", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLog2, genType, "log2", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSqrt, genType, "sqrt", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpInverseSqrt, genType, "inversesqrt", genType);
|
||||
|
||||
//
|
||||
// Common Functions.
|
||||
//
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "abs", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "abs", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "abs", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "abs", float4);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAbs, genType, "abs", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAbs, genIType, "abs", genIType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSign, genType, "sign", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSign, genIType, "sign", genIType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFloor, genType, "floor", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTrunc, genType, "trunc", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRound, genType, "round", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRoundEven, genType, "roundEven", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCeil, genType, "ceil", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFract, genType, "fract", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMin, genType, "min", genType, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMin, genType, "min", genType, genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genIType, "min", genIType, genIType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genIType, "min", genIType, int1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genUType, "min", genUType, genUType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genUType, "min", genUType, uint1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMax, genType, "max", genType, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMax, genType, "max", genType, genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genIType, "max", genIType, genIType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genIType, "max", genIType, int1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genUType, "max", genUType, genUType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genUType, "max", genUType, uint1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpClamp, genType, "clamp", genType, float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpClamp, genType, "clamp", genType, genType, genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genIType, "clamp", genIType, int1, int1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genIType, "clamp", genIType, genIType, genIType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, uint1, uint1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, genUType, genUType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", genType, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", float1, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", genType, genType, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", float1, float1, genType);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "sign", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "sign", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "sign", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "sign", float4);
|
||||
TType *outFloat1 = new TType(EbtFloat);
|
||||
TType *outFloat2 = new TType(EbtFloat, 2);
|
||||
TType *outFloat3 = new TType(EbtFloat, 3);
|
||||
TType *outFloat4 = new TType(EbtFloat, 4);
|
||||
outFloat1->setQualifier(EvqOut);
|
||||
outFloat2->setQualifier(EvqOut);
|
||||
outFloat3->setQualifier(EvqOut);
|
||||
outFloat4->setQualifier(EvqOut);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "floor", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "floor", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "floor", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "floor", float4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float1, "modf", float1, outFloat1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float2, "modf", float2, outFloat2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float3, "modf", float3, outFloat3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float4, "modf", float4, outFloat4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "ceil", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "ceil", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "ceil", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "ceil", float4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsNan, genBType, "isnan", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsInf, genBType, "isinf", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, "floatBitsToInt", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, "floatBitsToUint", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, "intBitsToFloat", genIType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUintBitsToFloat, genType, "uintBitsToFloat", genUType);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "fract", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "fract", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "fract", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "fract", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "mod", float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mod", float2, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mod", float3, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mod", float4, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mod", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mod", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mod", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "min", float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "min", float2, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "min", float3, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "min", float4, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "min", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "min", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "min", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "max", float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "max", float2, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "max", float3, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "max", float4, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "max", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "max", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "max", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "clamp", float1, float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "clamp", float2, float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "clamp", float3, float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "clamp", float4, float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "clamp", float2, float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "clamp", float3, float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "clamp", float4, float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "mix", float1, float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mix", float2, float2, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mix", float3, float3, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mix", float4, float4, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mix", float2, float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mix", float3, float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mix", float4, float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "step", float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "step", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "step", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "step", float4, float4);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "step", float1, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "step", float1, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "step", float1, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "smoothstep", float1, float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "smoothstep", float2, float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "smoothstep", float3, float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "smoothstep", float4, float4, float4);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "smoothstep", float1, float1, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "smoothstep", float1, float1, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "smoothstep", float1, float1, float4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackSnorm2x16, uint1, "packSnorm2x16", float2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackUnorm2x16, uint1, "packUnorm2x16", float2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackHalf2x16, uint1, "packHalf2x16", float2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackSnorm2x16, float2, "unpackSnorm2x16", uint1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, "unpackUnorm2x16", uint1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, "unpackHalf2x16", uint1);
|
||||
|
||||
//
|
||||
// Geometric Functions.
|
||||
//
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "cross", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "normalize", float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "normalize", float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "normalize", float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "normalize", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "faceforward", float1, float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "faceforward", float2, float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "faceforward", float3, float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "faceforward", float4, float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "reflect", float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "reflect", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "reflect", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "reflect", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "refract", float1, float1, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "refract", float2, float2, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "refract", float3, float3, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "refract", float4, float4, float1);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLength, float1, "length", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDistance, float1, "distance", genType, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDot, float1, "dot", genType, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCross, float3, "cross", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpNormalize, genType, "normalize", genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFaceForward, genType, "faceforward", genType, genType, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpReflect, genType, "reflect", genType, genType);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRefract, genType, "refract", genType, genType, float1);
|
||||
|
||||
TType *mat2 = new TType(EbtFloat, 2, 2);
|
||||
TType *mat3 = new TType(EbtFloat, 3, 3);
|
||||
TType *mat4 = new TType(EbtFloat, 4, 4);
|
||||
TType *mat2x3 = new TType(EbtFloat, 2, 3);
|
||||
TType *mat3x2 = new TType(EbtFloat, 3, 2);
|
||||
TType *mat2x4 = new TType(EbtFloat, 2, 4);
|
||||
TType *mat4x2 = new TType(EbtFloat, 4, 2);
|
||||
TType *mat3x4 = new TType(EbtFloat, 3, 4);
|
||||
TType *mat4x3 = new TType(EbtFloat, 4, 3);
|
||||
|
||||
//
|
||||
// Matrix Functions.
|
||||
//
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, mat2, "matrixCompMult", mat2, mat2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, mat3, "matrixCompMult", mat3, mat3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, mat4, "matrixCompMult", mat4, mat4);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat2, "matrixCompMult", mat2, mat2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat3, "matrixCompMult", mat3, mat3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat4, "matrixCompMult", mat4, mat4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat2x3, "matrixCompMult", mat2x3, mat2x3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat3x2, "matrixCompMult", mat3x2, mat3x2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat2x4, "matrixCompMult", mat2x4, mat2x4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat4x2, "matrixCompMult", mat4x2, mat4x2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat3x4, "matrixCompMult", mat3x4, mat3x4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat4x3, "matrixCompMult", mat4x3, mat4x3);
|
||||
|
||||
TType *bool1 = new TType(EbtBool);
|
||||
TType *bool2 = new TType(EbtBool, 2);
|
||||
TType *bool3 = new TType(EbtBool, 3);
|
||||
TType *bool4 = new TType(EbtBool, 4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2, "outerProduct", float2, float2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3, "outerProduct", float3, float3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4, "outerProduct", float4, float4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2x3, "outerProduct", float3, float2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3x2, "outerProduct", float2, float3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2x4, "outerProduct", float4, float2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4x2, "outerProduct", float2, float4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3x4, "outerProduct", float4, float3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4x3, "outerProduct", float3, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2, "transpose", mat2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3, "transpose", mat3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4, "transpose", mat4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2x3, "transpose", mat3x2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3x2, "transpose", mat2x3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2x4, "transpose", mat4x2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4x2, "transpose", mat2x4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3x4, "transpose", mat4x3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4x3, "transpose", mat3x4);
|
||||
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat4);
|
||||
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat2, "inverse", mat2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat3, "inverse", mat3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat4, "inverse", mat4);
|
||||
|
||||
TType *vec = new TType(EbtVec);
|
||||
TType *ivec = new TType(EbtIVec);
|
||||
TType *uvec = new TType(EbtUVec);
|
||||
TType *bvec = new TType(EbtBVec);
|
||||
|
||||
//
|
||||
// Vector relational functions.
|
||||
//
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThan", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThan", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThan", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThan", int2, int2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThan", int3, int3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThan", int4, int4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThanEqual", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThanEqual", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThanEqual", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThanEqual", int2, int2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThanEqual", int3, int3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThanEqual", int4, int4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThan", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThan", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThan", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThan", int2, int2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThan", int3, int3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThan", int4, int4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThanEqual", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThanEqual", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThanEqual", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThanEqual", int2, int2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThanEqual", int3, int3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThanEqual", int4, int4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "equal", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "equal", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "equal", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "equal", int2, int2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "equal", int3, int3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "equal", int4, int4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "equal", bool2, bool2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "equal", bool3, bool3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "equal", bool4, bool4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "notEqual", float2, float2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "notEqual", float3, float3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "notEqual", float4, float4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "notEqual", int2, int2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "notEqual", int3, int3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "notEqual", int4, int4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "notEqual", bool2, bool2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "notEqual", bool3, bool3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "notEqual", bool4, bool4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "any", bool2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "any", bool3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "any", bool4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "all", bool2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "all", bool3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "all", bool4);
|
||||
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "not", bool2);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "not", bool3);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "not", bool4);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThan, bvec, "lessThan", vec, vec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThan, bvec, "lessThan", ivec, ivec);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpLessThan, bvec, "lessThan", uvec, uvec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", vec, vec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", ivec, ivec);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", uvec, uvec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThan, bvec, "greaterThan", vec, vec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThan, bvec, "greaterThan", ivec, ivec);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpGreaterThan, bvec, "greaterThan", uvec, uvec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", vec, vec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", ivec, ivec);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", uvec, uvec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", vec, vec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", ivec, ivec);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpVectorEqual, bvec, "equal", uvec, uvec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", bvec, bvec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", vec, vec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", ivec, ivec);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", uvec, uvec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", bvec, bvec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAny, bool1, "any", bvec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAll, bool1, "all", bvec);
|
||||
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorLogicalNot, bvec, "not", bvec);
|
||||
|
||||
TType *sampler2D = new TType(EbtSampler2D);
|
||||
TType *samplerCube = new TType(EbtSamplerCube);
|
||||
@ -357,10 +258,10 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
|
||||
/* The *Grad* variants are new to both vertex and fragment shaders; the fragment
|
||||
* shader specific pieces are added separately below.
|
||||
*/
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DGradEXT", sampler2D, float2, float2, float2);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjGradEXT", sampler2D, float3, float2, float2);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjGradEXT", sampler2D, float4, float2, float2);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeGradEXT", samplerCube, float3, float3, float3);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DGradEXT", sampler2D, float2, float2, float2);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjGradEXT", sampler2D, float3, float2, float2);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjGradEXT", sampler2D, float4, float2, float2);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "textureCubeGradEXT", samplerCube, float3, float3, float3);
|
||||
}
|
||||
|
||||
if (type == GL_FRAGMENT_SHADER)
|
||||
@ -372,32 +273,21 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
|
||||
|
||||
if (resources.OES_standard_derivatives)
|
||||
{
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float1, "dFdx", float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float2, "dFdx", float2);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float3, "dFdx", float3);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "dFdx", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float1, "dFdy", float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float2, "dFdy", float2);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float3, "dFdy", float3);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "dFdy", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float1, "fwidth", float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float2, "fwidth", float2);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float3, "fwidth", float3);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "fwidth", float4);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, EOpDFdx, "GL_OES_standard_derivatives", genType, "dFdx", genType);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, EOpDFdy, "GL_OES_standard_derivatives", genType, "dFdy", genType);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, EOpFwidth, "GL_OES_standard_derivatives", genType, "fwidth", genType);
|
||||
}
|
||||
|
||||
if (resources.EXT_shader_texture_lod)
|
||||
{
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLodEXT", sampler2D, float2, float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLodEXT", sampler2D, float3, float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLodEXT", sampler2D, float4, float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLodEXT", samplerCube, float3, float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DLodEXT", sampler2D, float2, float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjLodEXT", sampler2D, float3, float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjLodEXT", sampler2D, float4, float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "textureCubeLodEXT", samplerCube, float3, float1);
|
||||
}
|
||||
}
|
||||
|
||||
if(type == GL_VERTEX_SHADER)
|
||||
if (type == GL_VERTEX_SHADER)
|
||||
{
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLod", sampler2D, float2, float1);
|
||||
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3, float1);
|
||||
@ -463,22 +353,11 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
|
||||
|
||||
if(type == GL_FRAGMENT_SHADER)
|
||||
if (type == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "dFdx", float1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "dFdx", float2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float3, "dFdx", float3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "dFdx", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "dFdy", float1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "dFdy", float2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float3, "dFdy", float3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "dFdy", float4);
|
||||
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "fwidth", float1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "fwidth", float2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float3, "fwidth", float3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "fwidth", float4);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdx, genType, "dFdx", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdy, genType, "dFdy", genType);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFwidth, genType, "fwidth", genType);
|
||||
}
|
||||
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2);
|
||||
@ -486,7 +365,7 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2);
|
||||
|
||||
if(type == GL_FRAGMENT_SHADER)
|
||||
if (type == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2, float1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3, float1);
|
||||
@ -499,7 +378,7 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2);
|
||||
|
||||
if(type == GL_FRAGMENT_SHADER)
|
||||
if (type == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2, float1);
|
||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2, float1);
|
||||
@ -600,146 +479,84 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
|
||||
TSymbolTable &symbolTable)
|
||||
{
|
||||
//
|
||||
// First, insert some special built-in variables that are not in
|
||||
// Insert some special built-in variables that are not in
|
||||
// the built-in header files.
|
||||
//
|
||||
switch(type) {
|
||||
case GL_FRAGMENT_SHADER:
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
|
||||
switch (type)
|
||||
{
|
||||
case GL_FRAGMENT_SHADER:
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"),
|
||||
TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"),
|
||||
TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"),
|
||||
TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
|
||||
|
||||
//
|
||||
// In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available.
|
||||
// Instead, css_MixColor and css_ColorMatrix are available.
|
||||
//
|
||||
if (spec != SH_CSS_SHADERS_SPEC) {
|
||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
|
||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
|
||||
if (resources.EXT_frag_depth) {
|
||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragDepthEXT"), TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
|
||||
symbolTable.relateToExtension(ESSL1_BUILTINS, "gl_FragDepthEXT", "GL_EXT_frag_depth");
|
||||
}
|
||||
} else {
|
||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4)));
|
||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4)));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GL_VERTEX_SHADER:
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
|
||||
break;
|
||||
|
||||
default: assert(false && "Language not supported");
|
||||
}
|
||||
|
||||
//
|
||||
// Next, identify which built-ins from the already loaded headers have
|
||||
// a mapping to an operator. Those that are not identified as such are
|
||||
// expected to be resolved through a library of functions, versus as
|
||||
// operations.
|
||||
//
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "matrixCompMult", EOpMul);
|
||||
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "equal", EOpVectorEqual);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "notEqual", EOpVectorNotEqual);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "lessThan", EOpLessThan);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "greaterThan", EOpGreaterThan);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "lessThanEqual", EOpLessThanEqual);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "greaterThanEqual", EOpGreaterThanEqual);
|
||||
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "radians", EOpRadians);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "degrees", EOpDegrees);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "sin", EOpSin);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "cos", EOpCos);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "tan", EOpTan);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "asin", EOpAsin);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "acos", EOpAcos);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "atan", EOpAtan);
|
||||
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "pow", EOpPow);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "exp2", EOpExp2);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "log", EOpLog);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "exp", EOpExp);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "log2", EOpLog2);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "sqrt", EOpSqrt);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "inversesqrt", EOpInverseSqrt);
|
||||
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "abs", EOpAbs);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "sign", EOpSign);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "floor", EOpFloor);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "ceil", EOpCeil);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "fract", EOpFract);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "mod", EOpMod);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "min", EOpMin);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "max", EOpMax);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "clamp", EOpClamp);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "mix", EOpMix);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "step", EOpStep);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "smoothstep", EOpSmoothStep);
|
||||
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "length", EOpLength);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "distance", EOpDistance);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "dot", EOpDot);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "cross", EOpCross);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "normalize", EOpNormalize);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "faceforward", EOpFaceForward);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "reflect", EOpReflect);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "refract", EOpRefract);
|
||||
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "any", EOpAny);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "all", EOpAll);
|
||||
symbolTable.relateToOperator(COMMON_BUILTINS, "not", EOpVectorLogicalNot);
|
||||
|
||||
// Map language-specific operators.
|
||||
switch(type) {
|
||||
case GL_VERTEX_SHADER:
|
||||
break;
|
||||
case GL_FRAGMENT_SHADER:
|
||||
if (resources.OES_standard_derivatives)
|
||||
if (spec != SH_CSS_SHADERS_SPEC)
|
||||
{
|
||||
symbolTable.relateToOperator(ESSL1_BUILTINS, "dFdx", EOpDFdx);
|
||||
symbolTable.relateToOperator(ESSL1_BUILTINS, "dFdy", EOpDFdy);
|
||||
symbolTable.relateToOperator(ESSL1_BUILTINS, "fwidth", EOpFwidth);
|
||||
|
||||
symbolTable.relateToExtension(ESSL1_BUILTINS, "dFdx", "GL_OES_standard_derivatives");
|
||||
symbolTable.relateToExtension(ESSL1_BUILTINS, "dFdy", "GL_OES_standard_derivatives");
|
||||
symbolTable.relateToExtension(ESSL1_BUILTINS, "fwidth", "GL_OES_standard_derivatives");
|
||||
}
|
||||
if (resources.EXT_shader_texture_lod)
|
||||
{
|
||||
symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DLodEXT", "GL_EXT_shader_texture_lod");
|
||||
symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DProjLodEXT", "GL_EXT_shader_texture_lod");
|
||||
symbolTable.relateToExtension(ESSL1_BUILTINS, "textureCubeLodEXT", "GL_EXT_shader_texture_lod");
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
symbolTable.relateToOperator(ESSL3_BUILTINS, "dFdx", EOpDFdx);
|
||||
symbolTable.relateToOperator(ESSL3_BUILTINS, "dFdy", EOpDFdy);
|
||||
symbolTable.relateToOperator(ESSL3_BUILTINS, "fwidth", EOpFwidth);
|
||||
|
||||
if (resources.EXT_shader_texture_lod)
|
||||
{
|
||||
symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DGradEXT", "GL_EXT_shader_texture_lod");
|
||||
symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DProjGradEXT", "GL_EXT_shader_texture_lod");
|
||||
symbolTable.relateToExtension(ESSL1_BUILTINS, "textureCubeGradEXT", "GL_EXT_shader_texture_lod");
|
||||
}
|
||||
|
||||
// Finally add resource-specific variables.
|
||||
switch(type) {
|
||||
case GL_FRAGMENT_SHADER:
|
||||
if (spec != SH_CSS_SHADERS_SPEC) {
|
||||
// Set up gl_FragData. The array size.
|
||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"),
|
||||
TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
|
||||
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
|
||||
fragData.setArraySize(resources.MaxDrawBuffers);
|
||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
|
||||
|
||||
if (resources.EXT_frag_depth)
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_frag_depth", new TVariable(NewPoolTString("gl_FragDepthEXT"),
|
||||
TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
|
||||
}
|
||||
|
||||
if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
|
||||
{
|
||||
TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true);
|
||||
lastFragData.setArraySize(resources.MaxDrawBuffers);
|
||||
|
||||
if (resources.EXT_shader_framebuffer_fetch)
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
|
||||
}
|
||||
else if (resources.NV_shader_framebuffer_fetch)
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragColor"),
|
||||
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
|
||||
}
|
||||
}
|
||||
else if (resources.ARM_shader_framebuffer_fetch)
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragColorARM"),
|
||||
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"),
|
||||
TType(EbtFloat, EbpMedium, EvqGlobal, 4)));
|
||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"),
|
||||
TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4)));
|
||||
}
|
||||
|
||||
break;
|
||||
default: break;
|
||||
|
||||
case GL_VERTEX_SHADER:
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_Position"),
|
||||
TType(EbtFloat, EbpHigh, EvqPosition, 4)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointSize"),
|
||||
TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
|
||||
symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_InstanceID"),
|
||||
TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false && "Language not supported");
|
||||
}
|
||||
}
|
||||
|
||||
@ -758,4 +575,20 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
|
||||
extBehavior["GL_EXT_frag_depth"] = EBhUndefined;
|
||||
if (resources.EXT_shader_texture_lod)
|
||||
extBehavior["GL_EXT_shader_texture_lod"] = EBhUndefined;
|
||||
if (resources.EXT_shader_framebuffer_fetch)
|
||||
extBehavior["GL_EXT_shader_framebuffer_fetch"] = EBhUndefined;
|
||||
if (resources.NV_shader_framebuffer_fetch)
|
||||
extBehavior["GL_NV_shader_framebuffer_fetch"] = EBhUndefined;
|
||||
if (resources.ARM_shader_framebuffer_fetch)
|
||||
extBehavior["GL_ARM_shader_framebuffer_fetch"] = EBhUndefined;
|
||||
}
|
||||
|
||||
void ResetExtensionBehavior(TExtensionBehavior &extBehavior)
|
||||
{
|
||||
for (auto ext_iter = extBehavior.begin();
|
||||
ext_iter != extBehavior.end();
|
||||
++ext_iter)
|
||||
{
|
||||
ext_iter->second = EBhUndefined;
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _INITIALIZE_INCLUDED_
|
||||
#define _INITIALIZE_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_INITIALIZE_H_
|
||||
#define COMPILER_TRANSLATOR_INITIALIZE_H_
|
||||
|
||||
#include "compiler/translator/Common.h"
|
||||
#include "compiler/translator/Compiler.h"
|
||||
@ -20,4 +20,10 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
|
||||
void InitExtensionBehavior(const ShBuiltInResources& resources,
|
||||
TExtensionBehavior& extensionBehavior);
|
||||
|
||||
#endif // _INITIALIZE_INCLUDED_
|
||||
// Resets the behavior of the extensions listed in |extensionBehavior| to the
|
||||
// undefined state. These extensions will only be those initially supported in
|
||||
// the ShBuiltInResources object for this compiler instance. All other
|
||||
// extensions will remain unsupported.
|
||||
void ResetExtensionBehavior(TExtensionBehavior &extensionBehavior);
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_INITIALIZE_H_
|
||||
|
@ -3,11 +3,11 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
#ifndef __INITIALIZEDLL_H
|
||||
#define __INITIALIZEDLL_H
|
||||
#ifndef COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
||||
#define COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
||||
|
||||
bool InitProcess();
|
||||
void DetachProcess();
|
||||
|
||||
#endif // __INITIALIZEDLL_H
|
||||
#endif // COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
||||
|
||||
|
@ -4,10 +4,10 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef __INITIALIZE_GLOBALS_INCLUDED_
|
||||
#define __INITIALIZE_GLOBALS_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
|
||||
#define COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
|
||||
|
||||
bool InitializePoolIndex();
|
||||
void FreePoolIndex();
|
||||
|
||||
#endif // __INITIALIZE_GLOBALS_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
||||
#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
||||
#define COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
||||
|
||||
bool InitializeParseContextIndex();
|
||||
void FreeParseContextIndex();
|
||||
@ -14,4 +14,4 @@ struct TParseContext;
|
||||
extern void SetGlobalParseContext(TParseContext* context);
|
||||
extern TParseContext* GetGlobalParseContext();
|
||||
|
||||
#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_INITIALIZE_VARIABLES_H_
|
||||
#define COMPILER_INITIALIZE_VARIABLES_H_
|
||||
#ifndef COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
|
||||
#define COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
@ -47,4 +47,4 @@ class InitializeVariables : public TIntermTraverser
|
||||
bool mCodeInserted;
|
||||
};
|
||||
|
||||
#endif // COMPILER_INITIALIZE_VARIABLES_H_
|
||||
#endif // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
|
||||
|
@ -157,26 +157,6 @@ bool TIntermLoop::replaceChildNode(
|
||||
return false;
|
||||
}
|
||||
|
||||
void TIntermLoop::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
|
||||
{
|
||||
if (mInit)
|
||||
{
|
||||
nodeQueue->push(mInit);
|
||||
}
|
||||
if (mCond)
|
||||
{
|
||||
nodeQueue->push(mCond);
|
||||
}
|
||||
if (mExpr)
|
||||
{
|
||||
nodeQueue->push(mExpr);
|
||||
}
|
||||
if (mBody)
|
||||
{
|
||||
nodeQueue->push(mBody);
|
||||
}
|
||||
}
|
||||
|
||||
bool TIntermBranch::replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement)
|
||||
{
|
||||
@ -184,14 +164,6 @@ bool TIntermBranch::replaceChildNode(
|
||||
return false;
|
||||
}
|
||||
|
||||
void TIntermBranch::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
|
||||
{
|
||||
if (mExpression)
|
||||
{
|
||||
nodeQueue->push(mExpression);
|
||||
}
|
||||
}
|
||||
|
||||
bool TIntermBinary::replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement)
|
||||
{
|
||||
@ -200,18 +172,6 @@ bool TIntermBinary::replaceChildNode(
|
||||
return false;
|
||||
}
|
||||
|
||||
void TIntermBinary::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
|
||||
{
|
||||
if (mLeft)
|
||||
{
|
||||
nodeQueue->push(mLeft);
|
||||
}
|
||||
if (mRight)
|
||||
{
|
||||
nodeQueue->push(mRight);
|
||||
}
|
||||
}
|
||||
|
||||
bool TIntermUnary::replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement)
|
||||
{
|
||||
@ -219,14 +179,6 @@ bool TIntermUnary::replaceChildNode(
|
||||
return false;
|
||||
}
|
||||
|
||||
void TIntermUnary::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
|
||||
{
|
||||
if (mOperand)
|
||||
{
|
||||
nodeQueue->push(mOperand);
|
||||
}
|
||||
}
|
||||
|
||||
bool TIntermAggregate::replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement)
|
||||
{
|
||||
@ -237,14 +189,6 @@ bool TIntermAggregate::replaceChildNode(
|
||||
return false;
|
||||
}
|
||||
|
||||
void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
|
||||
{
|
||||
for (size_t childIndex = 0; childIndex < mSequence.size(); childIndex++)
|
||||
{
|
||||
nodeQueue->push(mSequence[childIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
void TIntermAggregate::setPrecisionFromChildren()
|
||||
{
|
||||
if (getBasicType() == EbtBool)
|
||||
@ -300,20 +244,19 @@ bool TIntermSelection::replaceChildNode(
|
||||
return false;
|
||||
}
|
||||
|
||||
void TIntermSelection::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
|
||||
bool TIntermSwitch::replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement)
|
||||
{
|
||||
if (mCondition)
|
||||
{
|
||||
nodeQueue->push(mCondition);
|
||||
}
|
||||
if (mTrueBlock)
|
||||
{
|
||||
nodeQueue->push(mTrueBlock);
|
||||
}
|
||||
if (mFalseBlock)
|
||||
{
|
||||
nodeQueue->push(mFalseBlock);
|
||||
}
|
||||
REPLACE_IF_IS(mInit, TIntermTyped, original, replacement);
|
||||
REPLACE_IF_IS(mStatementList, TIntermAggregate, original, replacement);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TIntermCase::replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement)
|
||||
{
|
||||
REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
@ -336,6 +279,12 @@ bool TIntermOperator::isAssignment() const
|
||||
case EOpMatrixTimesScalarAssign:
|
||||
case EOpMatrixTimesMatrixAssign:
|
||||
case EOpDivAssign:
|
||||
case EOpIModAssign:
|
||||
case EOpBitShiftLeftAssign:
|
||||
case EOpBitShiftRightAssign:
|
||||
case EOpBitwiseAndAssign:
|
||||
case EOpBitwiseXorAssign:
|
||||
case EOpBitwiseOrAssign:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -379,65 +328,55 @@ bool TIntermOperator::isConstructor() const
|
||||
// Make sure the type of a unary operator is appropriate for its
|
||||
// combination of operation and operand type.
|
||||
//
|
||||
// Returns false in nothing makes sense.
|
||||
//
|
||||
bool TIntermUnary::promote(TInfoSink &)
|
||||
void TIntermUnary::promote(const TType *funcReturnType)
|
||||
{
|
||||
switch (mOp)
|
||||
{
|
||||
case EOpLogicalNot:
|
||||
if (mOperand->getBasicType() != EbtBool)
|
||||
return false;
|
||||
case EOpFloatBitsToInt:
|
||||
case EOpFloatBitsToUint:
|
||||
case EOpIntBitsToFloat:
|
||||
case EOpUintBitsToFloat:
|
||||
case EOpPackSnorm2x16:
|
||||
case EOpPackUnorm2x16:
|
||||
case EOpPackHalf2x16:
|
||||
case EOpUnpackSnorm2x16:
|
||||
case EOpUnpackUnorm2x16:
|
||||
mType.setPrecision(EbpHigh);
|
||||
break;
|
||||
case EOpNegative:
|
||||
case EOpPositive:
|
||||
case EOpPostIncrement:
|
||||
case EOpPostDecrement:
|
||||
case EOpPreIncrement:
|
||||
case EOpPreDecrement:
|
||||
if (mOperand->getBasicType() == EbtBool)
|
||||
return false;
|
||||
case EOpUnpackHalf2x16:
|
||||
mType.setPrecision(EbpMedium);
|
||||
break;
|
||||
|
||||
// operators for built-ins are already type checked against their prototype
|
||||
case EOpAny:
|
||||
case EOpAll:
|
||||
case EOpVectorLogicalNot:
|
||||
return true;
|
||||
|
||||
default:
|
||||
if (mOperand->getBasicType() != EbtFloat)
|
||||
return false;
|
||||
setType(mOperand->getType());
|
||||
}
|
||||
|
||||
setType(mOperand->getType());
|
||||
mType.setQualifier(EvqTemporary);
|
||||
if (funcReturnType != nullptr)
|
||||
{
|
||||
if (funcReturnType->getBasicType() == EbtBool)
|
||||
{
|
||||
// Bool types should not have precision.
|
||||
setType(*funcReturnType);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Precision of the node has been set based on the operand.
|
||||
setTypePreservePrecision(*funcReturnType);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
mType.setQualifier(EvqTemporary);
|
||||
}
|
||||
|
||||
//
|
||||
// Establishes the type of the resultant operation, as well as
|
||||
// makes the operator the correct one for the operands.
|
||||
//
|
||||
// Returns false if operator can't work on operands.
|
||||
// For lots of operations it should already be established that the operand
|
||||
// combination is valid, but returns false if operator can't work on operands.
|
||||
//
|
||||
bool TIntermBinary::promote(TInfoSink &infoSink)
|
||||
{
|
||||
// This function only handles scalars, vectors, and matrices.
|
||||
if (mLeft->isArray() || mRight->isArray())
|
||||
{
|
||||
infoSink.info.message(EPrefixInternalError, getLine(),
|
||||
"Invalid operation for arrays");
|
||||
return false;
|
||||
}
|
||||
|
||||
// GLSL ES 2.0 does not support implicit type casting.
|
||||
// So the basic type should always match.
|
||||
if (mLeft->getBasicType() != mRight->getBasicType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ASSERT(mLeft->isArray() == mRight->isArray());
|
||||
|
||||
//
|
||||
// Base assumption: just make the type the same as the left
|
||||
@ -483,12 +422,9 @@ bool TIntermBinary::promote(TInfoSink &infoSink)
|
||||
// And and Or operate on conditionals
|
||||
//
|
||||
case EOpLogicalAnd:
|
||||
case EOpLogicalXor:
|
||||
case EOpLogicalOr:
|
||||
// Both operands must be of type bool.
|
||||
if (mLeft->getBasicType() != EbtBool || mRight->getBasicType() != EbtBool)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ASSERT(mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool);
|
||||
setType(TType(EbtBool, EbpUndefined));
|
||||
break;
|
||||
|
||||
@ -625,12 +561,28 @@ bool TIntermBinary::promote(TInfoSink &infoSink)
|
||||
|
||||
case EOpAssign:
|
||||
case EOpInitialize:
|
||||
// No more additional checks are needed.
|
||||
ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) &&
|
||||
(mLeft->getSecondarySize() == mRight->getSecondarySize()));
|
||||
break;
|
||||
case EOpAdd:
|
||||
case EOpSub:
|
||||
case EOpDiv:
|
||||
case EOpIMod:
|
||||
case EOpBitShiftLeft:
|
||||
case EOpBitShiftRight:
|
||||
case EOpBitwiseAnd:
|
||||
case EOpBitwiseXor:
|
||||
case EOpBitwiseOr:
|
||||
case EOpAddAssign:
|
||||
case EOpSubAssign:
|
||||
case EOpDivAssign:
|
||||
case EOpIModAssign:
|
||||
case EOpBitShiftLeftAssign:
|
||||
case EOpBitShiftRightAssign:
|
||||
case EOpBitwiseAndAssign:
|
||||
case EOpBitwiseXorAssign:
|
||||
case EOpBitwiseOrAssign:
|
||||
if ((mLeft->isMatrix() && mRight->isVector()) ||
|
||||
(mLeft->isVector() && mRight->isMatrix()))
|
||||
{
|
||||
@ -641,13 +593,19 @@ bool TIntermBinary::promote(TInfoSink &infoSink)
|
||||
if (mLeft->getNominalSize() != mRight->getNominalSize() ||
|
||||
mLeft->getSecondarySize() != mRight->getSecondarySize())
|
||||
{
|
||||
// If the nominal size of operands do not match:
|
||||
// One of them must be scalar.
|
||||
// If the nominal sizes of operands do not match:
|
||||
// One of them must be a scalar.
|
||||
if (!mLeft->isScalar() && !mRight->isScalar())
|
||||
return false;
|
||||
|
||||
// Operator cannot be of type pure assignment.
|
||||
if (mOp == EOpAssign || mOp == EOpInitialize)
|
||||
// In the case of compound assignment other than multiply-assign,
|
||||
// the right side needs to be a scalar. Otherwise a vector/matrix
|
||||
// would be assigned to a scalar. A scalar can't be shifted by a
|
||||
// vector either.
|
||||
if (!mRight->isScalar() &&
|
||||
(isAssignment() ||
|
||||
mOp == EOpBitShiftLeft ||
|
||||
mOp == EOpBitShiftRight))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -656,6 +614,11 @@ bool TIntermBinary::promote(TInfoSink &infoSink)
|
||||
mLeft->getSecondarySize(), mRight->getSecondarySize());
|
||||
setType(TType(basicType, higherPrecision, EvqTemporary,
|
||||
nominalSize, secondarySize));
|
||||
if (mLeft->isArray())
|
||||
{
|
||||
ASSERT(mLeft->getArraySize() == mRight->getArraySize());
|
||||
mType.setArraySize(mLeft->getArraySize());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -665,11 +628,8 @@ bool TIntermBinary::promote(TInfoSink &infoSink)
|
||||
case EOpGreaterThan:
|
||||
case EOpLessThanEqual:
|
||||
case EOpGreaterThanEqual:
|
||||
if ((mLeft->getNominalSize() != mRight->getNominalSize()) ||
|
||||
(mLeft->getSecondarySize() != mRight->getSecondarySize()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) &&
|
||||
(mLeft->getSecondarySize() == mRight->getSecondarySize()));
|
||||
setType(TType(EbtBool, EbpUndefined));
|
||||
break;
|
||||
|
||||
@ -793,6 +753,7 @@ TIntermTyped *TIntermConstantUnion::fold(
|
||||
break;
|
||||
|
||||
case EOpDiv:
|
||||
case EOpIMod:
|
||||
{
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
@ -810,6 +771,7 @@ TIntermTyped *TIntermConstantUnion::fold(
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(op == EOpDiv);
|
||||
tempConstArray[i].setFConst(
|
||||
unionArray[i].getFConst() /
|
||||
rightUnionArray[i].getFConst());
|
||||
@ -826,9 +788,19 @@ TIntermTyped *TIntermConstantUnion::fold(
|
||||
}
|
||||
else
|
||||
{
|
||||
tempConstArray[i].setIConst(
|
||||
unionArray[i].getIConst() /
|
||||
rightUnionArray[i].getIConst());
|
||||
if (op == EOpDiv)
|
||||
{
|
||||
tempConstArray[i].setIConst(
|
||||
unionArray[i].getIConst() /
|
||||
rightUnionArray[i].getIConst());
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(op == EOpIMod);
|
||||
tempConstArray[i].setIConst(
|
||||
unionArray[i].getIConst() %
|
||||
rightUnionArray[i].getIConst());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -842,9 +814,19 @@ TIntermTyped *TIntermConstantUnion::fold(
|
||||
}
|
||||
else
|
||||
{
|
||||
tempConstArray[i].setUConst(
|
||||
unionArray[i].getUConst() /
|
||||
rightUnionArray[i].getUConst());
|
||||
if (op == EOpDiv)
|
||||
{
|
||||
tempConstArray[i].setUConst(
|
||||
unionArray[i].getUConst() /
|
||||
rightUnionArray[i].getUConst());
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(op == EOpIMod);
|
||||
tempConstArray[i].setUConst(
|
||||
unionArray[i].getUConst() %
|
||||
rightUnionArray[i].getUConst());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -968,6 +950,32 @@ TIntermTyped *TIntermConstantUnion::fold(
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpBitwiseAnd:
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
tempConstArray[i] = unionArray[i] & rightUnionArray[i];
|
||||
break;
|
||||
case EOpBitwiseXor:
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
tempConstArray[i] = unionArray[i] ^ rightUnionArray[i];
|
||||
break;
|
||||
case EOpBitwiseOr:
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
tempConstArray[i] = unionArray[i] | rightUnionArray[i];
|
||||
break;
|
||||
case EOpBitShiftLeft:
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
tempConstArray[i] = unionArray[i] << rightUnionArray[i];
|
||||
break;
|
||||
case EOpBitShiftRight:
|
||||
tempConstArray = new ConstantUnion[objectSize];
|
||||
for (size_t i = 0; i < objectSize; i++)
|
||||
tempConstArray[i] = unionArray[i] >> rightUnionArray[i];
|
||||
break;
|
||||
|
||||
case EOpLessThan:
|
||||
ASSERT(objectSize == 1);
|
||||
tempConstArray = new ConstantUnion[1];
|
||||
@ -1160,6 +1168,23 @@ TIntermTyped *TIntermConstantUnion::fold(
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpBitwiseNot:
|
||||
switch (getType().getBasicType())
|
||||
{
|
||||
case EbtInt:
|
||||
tempConstArray[i].setIConst(~unionArray[i].getIConst());
|
||||
break;
|
||||
case EbtUInt:
|
||||
tempConstArray[i].setUConst(~unionArray[i].getUConst());
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(
|
||||
EPrefixInternalError, getLine(),
|
||||
"Unary operation not folded into constant");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -1181,3 +1206,29 @@ TString TIntermTraverser::hash(const TString &name, ShHashFunction64 hashFunctio
|
||||
TString hashedName = stream.str();
|
||||
return hashedName;
|
||||
}
|
||||
|
||||
void TIntermTraverser::updateTree()
|
||||
{
|
||||
for (size_t ii = 0; ii < mReplacements.size(); ++ii)
|
||||
{
|
||||
const NodeUpdateEntry& entry = mReplacements[ii];
|
||||
ASSERT(entry.parent);
|
||||
bool replaced = entry.parent->replaceChildNode(
|
||||
entry.original, entry.replacement);
|
||||
ASSERT(replaced);
|
||||
|
||||
if (!entry.originalBecomesChildOfReplacement)
|
||||
{
|
||||
// In AST traversing, a parent is visited before its children.
|
||||
// After we replace a node, if an immediate child is to
|
||||
// be replaced, we need to make sure we don't update the replaced
|
||||
// node; instead, we update the replacement node.
|
||||
for (size_t jj = ii + 1; jj < mReplacements.size(); ++jj)
|
||||
{
|
||||
NodeUpdateEntry& entry2 = mReplacements[jj];
|
||||
if (entry2.parent == entry.original)
|
||||
entry2.parent = entry.replacement;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,182 +13,19 @@
|
||||
// each node can have it's own type of list of children.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_TRANSLATOR_INTERMEDIATE_H_
|
||||
#define COMPILER_TRANSLATOR_INTERMEDIATE_H_
|
||||
#ifndef COMPILER_TRANSLATOR_INTERMNODE_H_
|
||||
#define COMPILER_TRANSLATOR_INTERMNODE_H_
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <queue>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/translator/Common.h"
|
||||
#include "compiler/translator/Types.h"
|
||||
#include "compiler/translator/ConstantUnion.h"
|
||||
|
||||
//
|
||||
// Operators used by the high-level (parse tree) representation.
|
||||
//
|
||||
enum TOperator
|
||||
{
|
||||
EOpNull, // if in a node, should only mean a node is still being built
|
||||
EOpSequence, // denotes a list of statements, or parameters, etc.
|
||||
EOpFunctionCall,
|
||||
EOpFunction, // For function definition
|
||||
EOpParameters, // an aggregate listing the parameters to a function
|
||||
|
||||
EOpDeclaration,
|
||||
EOpInvariantDeclaration, // Specialized declarations for attributing invariance
|
||||
EOpPrototype,
|
||||
|
||||
//
|
||||
// Unary operators
|
||||
//
|
||||
|
||||
EOpNegative,
|
||||
EOpPositive,
|
||||
EOpLogicalNot,
|
||||
EOpVectorLogicalNot,
|
||||
|
||||
EOpPostIncrement,
|
||||
EOpPostDecrement,
|
||||
EOpPreIncrement,
|
||||
EOpPreDecrement,
|
||||
|
||||
//
|
||||
// binary operations
|
||||
//
|
||||
|
||||
EOpAdd,
|
||||
EOpSub,
|
||||
EOpMul,
|
||||
EOpDiv,
|
||||
EOpEqual,
|
||||
EOpNotEqual,
|
||||
EOpVectorEqual,
|
||||
EOpVectorNotEqual,
|
||||
EOpLessThan,
|
||||
EOpGreaterThan,
|
||||
EOpLessThanEqual,
|
||||
EOpGreaterThanEqual,
|
||||
EOpComma,
|
||||
|
||||
EOpVectorTimesScalar,
|
||||
EOpVectorTimesMatrix,
|
||||
EOpMatrixTimesVector,
|
||||
EOpMatrixTimesScalar,
|
||||
|
||||
EOpLogicalOr,
|
||||
EOpLogicalXor,
|
||||
EOpLogicalAnd,
|
||||
|
||||
EOpIndexDirect,
|
||||
EOpIndexIndirect,
|
||||
EOpIndexDirectStruct,
|
||||
EOpIndexDirectInterfaceBlock,
|
||||
|
||||
EOpVectorSwizzle,
|
||||
|
||||
//
|
||||
// Built-in functions potentially mapped to operators
|
||||
//
|
||||
|
||||
EOpRadians,
|
||||
EOpDegrees,
|
||||
EOpSin,
|
||||
EOpCos,
|
||||
EOpTan,
|
||||
EOpAsin,
|
||||
EOpAcos,
|
||||
EOpAtan,
|
||||
|
||||
EOpPow,
|
||||
EOpExp,
|
||||
EOpLog,
|
||||
EOpExp2,
|
||||
EOpLog2,
|
||||
EOpSqrt,
|
||||
EOpInverseSqrt,
|
||||
|
||||
EOpAbs,
|
||||
EOpSign,
|
||||
EOpFloor,
|
||||
EOpCeil,
|
||||
EOpFract,
|
||||
EOpMod,
|
||||
EOpMin,
|
||||
EOpMax,
|
||||
EOpClamp,
|
||||
EOpMix,
|
||||
EOpStep,
|
||||
EOpSmoothStep,
|
||||
|
||||
EOpLength,
|
||||
EOpDistance,
|
||||
EOpDot,
|
||||
EOpCross,
|
||||
EOpNormalize,
|
||||
EOpFaceForward,
|
||||
EOpReflect,
|
||||
EOpRefract,
|
||||
|
||||
EOpDFdx, // Fragment only, OES_standard_derivatives extension
|
||||
EOpDFdy, // Fragment only, OES_standard_derivatives extension
|
||||
EOpFwidth, // Fragment only, OES_standard_derivatives extension
|
||||
|
||||
EOpMatrixTimesMatrix,
|
||||
|
||||
EOpAny,
|
||||
EOpAll,
|
||||
|
||||
//
|
||||
// Branch
|
||||
//
|
||||
|
||||
EOpKill, // Fragment only
|
||||
EOpReturn,
|
||||
EOpBreak,
|
||||
EOpContinue,
|
||||
|
||||
//
|
||||
// Constructors
|
||||
//
|
||||
|
||||
EOpConstructInt,
|
||||
EOpConstructUInt,
|
||||
EOpConstructBool,
|
||||
EOpConstructFloat,
|
||||
EOpConstructVec2,
|
||||
EOpConstructVec3,
|
||||
EOpConstructVec4,
|
||||
EOpConstructBVec2,
|
||||
EOpConstructBVec3,
|
||||
EOpConstructBVec4,
|
||||
EOpConstructIVec2,
|
||||
EOpConstructIVec3,
|
||||
EOpConstructIVec4,
|
||||
EOpConstructUVec2,
|
||||
EOpConstructUVec3,
|
||||
EOpConstructUVec4,
|
||||
EOpConstructMat2,
|
||||
EOpConstructMat3,
|
||||
EOpConstructMat4,
|
||||
EOpConstructStruct,
|
||||
|
||||
//
|
||||
// moves
|
||||
//
|
||||
|
||||
EOpAssign,
|
||||
EOpInitialize,
|
||||
EOpAddAssign,
|
||||
EOpSubAssign,
|
||||
EOpMulAssign,
|
||||
EOpVectorTimesMatrixAssign,
|
||||
EOpVectorTimesScalarAssign,
|
||||
EOpMatrixTimesScalarAssign,
|
||||
EOpMatrixTimesMatrixAssign,
|
||||
EOpDivAssign
|
||||
};
|
||||
#include "compiler/translator/Operator.h"
|
||||
|
||||
class TIntermTraverser;
|
||||
class TIntermAggregate;
|
||||
@ -196,10 +33,13 @@ class TIntermBinary;
|
||||
class TIntermUnary;
|
||||
class TIntermConstantUnion;
|
||||
class TIntermSelection;
|
||||
class TIntermSwitch;
|
||||
class TIntermCase;
|
||||
class TIntermTyped;
|
||||
class TIntermSymbol;
|
||||
class TIntermLoop;
|
||||
class TInfoSink;
|
||||
class TInfoSinkBase;
|
||||
class TIntermRaw;
|
||||
|
||||
//
|
||||
@ -228,6 +68,8 @@ class TIntermNode
|
||||
virtual TIntermBinary *getAsBinaryNode() { return 0; }
|
||||
virtual TIntermUnary *getAsUnaryNode() { return 0; }
|
||||
virtual TIntermSelection *getAsSelectionNode() { return 0; }
|
||||
virtual TIntermSwitch *getAsSwitchNode() { return 0; }
|
||||
virtual TIntermCase *getAsCaseNode() { return 0; }
|
||||
virtual TIntermSymbol *getAsSymbolNode() { return 0; }
|
||||
virtual TIntermLoop *getAsLoopNode() { return 0; }
|
||||
virtual TIntermRaw *getAsRawNode() { return 0; }
|
||||
@ -237,10 +79,6 @@ class TIntermNode
|
||||
virtual bool replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement) = 0;
|
||||
|
||||
// For traversing a tree in no particular order, but using
|
||||
// heap memory.
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const = 0;
|
||||
|
||||
protected:
|
||||
TSourceLoc mLine;
|
||||
};
|
||||
@ -331,8 +169,6 @@ class TIntermLoop : public TIntermNode
|
||||
void setUnrollFlag(bool flag) { mUnrollFlag = flag; }
|
||||
bool getUnrollFlag() const { return mUnrollFlag; }
|
||||
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
|
||||
|
||||
protected:
|
||||
TLoopType mType;
|
||||
TIntermNode *mInit; // for-loop initialization
|
||||
@ -360,8 +196,6 @@ class TIntermBranch : public TIntermNode
|
||||
TOperator getFlowOp() { return mFlowOp; }
|
||||
TIntermTyped* getExpression() { return mExpression; }
|
||||
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
|
||||
|
||||
protected:
|
||||
TOperator mFlowOp;
|
||||
TIntermTyped *mExpression; // non-zero except for "return exp;" statements
|
||||
@ -394,8 +228,6 @@ class TIntermSymbol : public TIntermTyped
|
||||
virtual TIntermSymbol *getAsSymbolNode() { return this; }
|
||||
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
|
||||
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
|
||||
|
||||
protected:
|
||||
int mId;
|
||||
TString mSymbol;
|
||||
@ -419,7 +251,6 @@ class TIntermRaw : public TIntermTyped
|
||||
|
||||
virtual TIntermRaw *getAsRawNode() { return this; }
|
||||
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
|
||||
|
||||
protected:
|
||||
TString mRawText;
|
||||
@ -459,8 +290,6 @@ class TIntermConstantUnion : public TIntermTyped
|
||||
|
||||
TIntermTyped *fold(TOperator, TIntermTyped *, TInfoSink &);
|
||||
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
|
||||
|
||||
protected:
|
||||
ConstantUnion *mUnionArrayPointer;
|
||||
};
|
||||
@ -519,8 +348,6 @@ class TIntermBinary : public TIntermOperator
|
||||
void setAddIndexClamp() { mAddIndexClamp = true; }
|
||||
bool getAddIndexClamp() { return mAddIndexClamp; }
|
||||
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
|
||||
|
||||
protected:
|
||||
TIntermTyped* mLeft;
|
||||
TIntermTyped* mRight;
|
||||
@ -556,13 +383,11 @@ class TIntermUnary : public TIntermOperator
|
||||
|
||||
void setOperand(TIntermTyped *operand) { mOperand = operand; }
|
||||
TIntermTyped *getOperand() { return mOperand; }
|
||||
bool promote(TInfoSink &);
|
||||
void promote(const TType *funcReturnType);
|
||||
|
||||
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
|
||||
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
|
||||
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
|
||||
|
||||
protected:
|
||||
TIntermTyped *mOperand;
|
||||
|
||||
@ -613,8 +438,6 @@ class TIntermAggregate : public TIntermOperator
|
||||
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
|
||||
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
|
||||
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
|
||||
|
||||
void setPrecisionFromChildren();
|
||||
void setBuiltInFunctionPrecision();
|
||||
|
||||
@ -634,7 +457,7 @@ class TIntermAggregate : public TIntermOperator
|
||||
};
|
||||
|
||||
//
|
||||
// For if tests. Simplified since there is no switch statement.
|
||||
// For if tests.
|
||||
//
|
||||
class TIntermSelection : public TIntermTyped
|
||||
{
|
||||
@ -664,14 +487,64 @@ class TIntermSelection : public TIntermTyped
|
||||
TIntermNode *getFalseBlock() const { return mFalseBlock; }
|
||||
TIntermSelection *getAsSelectionNode() { return this; }
|
||||
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
|
||||
|
||||
protected:
|
||||
TIntermTyped *mCondition;
|
||||
TIntermNode *mTrueBlock;
|
||||
TIntermNode *mFalseBlock;
|
||||
};
|
||||
|
||||
//
|
||||
// Switch statement.
|
||||
//
|
||||
class TIntermSwitch : public TIntermNode
|
||||
{
|
||||
public:
|
||||
TIntermSwitch(TIntermTyped *init, TIntermAggregate *statementList)
|
||||
: TIntermNode(),
|
||||
mInit(init),
|
||||
mStatementList(statementList)
|
||||
{
|
||||
}
|
||||
|
||||
void traverse(TIntermTraverser *it) override;
|
||||
bool replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement) override;
|
||||
|
||||
TIntermSwitch *getAsSwitchNode() override { return this; }
|
||||
|
||||
TIntermAggregate *getStatementList() { return mStatementList; }
|
||||
void setStatementList(TIntermAggregate *statementList) { mStatementList = statementList; }
|
||||
|
||||
protected:
|
||||
TIntermTyped *mInit;
|
||||
TIntermAggregate *mStatementList;
|
||||
};
|
||||
|
||||
//
|
||||
// Case label.
|
||||
//
|
||||
class TIntermCase : public TIntermNode
|
||||
{
|
||||
public:
|
||||
TIntermCase(TIntermTyped *condition)
|
||||
: TIntermNode(),
|
||||
mCondition(condition)
|
||||
{
|
||||
}
|
||||
|
||||
void traverse(TIntermTraverser *it) override;
|
||||
bool replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement) override;
|
||||
|
||||
TIntermCase *getAsCaseNode() override { return this; }
|
||||
|
||||
bool hasCondition() const { return mCondition != nullptr; }
|
||||
TIntermTyped *getCondition() const { return mCondition; }
|
||||
|
||||
protected:
|
||||
TIntermTyped *mCondition;
|
||||
};
|
||||
|
||||
enum Visit
|
||||
{
|
||||
PreVisit,
|
||||
@ -687,7 +560,7 @@ enum Visit
|
||||
// When using this, just fill in the methods for nodes you want visited.
|
||||
// Return false from a pre-visit to skip visiting that node's subtree.
|
||||
//
|
||||
class TIntermTraverser
|
||||
class TIntermTraverser : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE();
|
||||
@ -708,6 +581,8 @@ class TIntermTraverser
|
||||
virtual bool visitBinary(Visit, TIntermBinary *) { return true; }
|
||||
virtual bool visitUnary(Visit, TIntermUnary *) { return true; }
|
||||
virtual bool visitSelection(Visit, TIntermSelection *) { return true; }
|
||||
virtual bool visitSwitch(Visit, TIntermSwitch *) { return true; }
|
||||
virtual bool visitCase(Visit, TIntermCase *) { return true; }
|
||||
virtual bool visitAggregate(Visit, TIntermAggregate *) { return true; }
|
||||
virtual bool visitLoop(Visit, TIntermLoop *) { return true; }
|
||||
virtual bool visitBranch(Visit, TIntermBranch *) { return true; }
|
||||
@ -741,12 +616,38 @@ class TIntermTraverser
|
||||
const bool postVisit;
|
||||
const bool rightToLeft;
|
||||
|
||||
// If traversers need to replace nodes, they can add the replacements in
|
||||
// mReplacements during traversal and the user of the traverser should call
|
||||
// this function after traversal to perform them.
|
||||
void updateTree();
|
||||
|
||||
protected:
|
||||
int mDepth;
|
||||
int mMaxDepth;
|
||||
|
||||
// All the nodes from root to the current node's parent during traversing.
|
||||
TVector<TIntermNode *> mPath;
|
||||
|
||||
struct NodeUpdateEntry
|
||||
{
|
||||
NodeUpdateEntry(TIntermNode *_parent,
|
||||
TIntermNode *_original,
|
||||
TIntermNode *_replacement,
|
||||
bool _originalBecomesChildOfReplacement)
|
||||
: parent(_parent),
|
||||
original(_original),
|
||||
replacement(_replacement),
|
||||
originalBecomesChildOfReplacement(_originalBecomesChildOfReplacement) {}
|
||||
|
||||
TIntermNode *parent;
|
||||
TIntermNode *original;
|
||||
TIntermNode *replacement;
|
||||
bool originalBecomesChildOfReplacement;
|
||||
};
|
||||
|
||||
// During traversing, save all the changes that need to happen into
|
||||
// mReplacements, then do them by calling updateTree().
|
||||
std::vector<NodeUpdateEntry> mReplacements;
|
||||
};
|
||||
|
||||
//
|
||||
@ -768,10 +669,10 @@ class TMaxDepthTraverser : public TIntermTraverser
|
||||
virtual bool visitLoop(Visit, TIntermLoop *) { return depthCheck(); }
|
||||
virtual bool visitBranch(Visit, TIntermBranch *) { return depthCheck(); }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
bool depthCheck() const { return mMaxDepth < mDepthLimit; }
|
||||
|
||||
int mDepthLimit;
|
||||
};
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_
|
||||
#endif // COMPILER_TRANSLATOR_INTERMNODE_H_
|
||||
|
@ -193,6 +193,60 @@ void TIntermSelection::traverse(TIntermTraverser *it)
|
||||
it->visitSelection(PostVisit, this);
|
||||
}
|
||||
|
||||
//
|
||||
// Traverse a switch node. Same comments in binary node apply here.
|
||||
//
|
||||
void TIntermSwitch::traverse(TIntermTraverser *it)
|
||||
{
|
||||
bool visit = true;
|
||||
|
||||
if (it->preVisit)
|
||||
visit = it->visitSwitch(PreVisit, this);
|
||||
|
||||
if (visit)
|
||||
{
|
||||
it->incrementDepth(this);
|
||||
if (it->rightToLeft)
|
||||
{
|
||||
if (mStatementList)
|
||||
mStatementList->traverse(it);
|
||||
if (it->inVisit)
|
||||
visit = it->visitSwitch(InVisit, this);
|
||||
if (visit)
|
||||
mInit->traverse(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
mInit->traverse(it);
|
||||
if (it->inVisit)
|
||||
visit = it->visitSwitch(InVisit, this);
|
||||
if (visit && mStatementList)
|
||||
mStatementList->traverse(it);
|
||||
}
|
||||
it->decrementDepth();
|
||||
}
|
||||
|
||||
if (visit && it->postVisit)
|
||||
it->visitSwitch(PostVisit, this);
|
||||
}
|
||||
|
||||
//
|
||||
// Traverse a switch node. Same comments in binary node apply here.
|
||||
//
|
||||
void TIntermCase::traverse(TIntermTraverser *it)
|
||||
{
|
||||
bool visit = true;
|
||||
|
||||
if (it->preVisit)
|
||||
visit = it->visitCase(PreVisit, this);
|
||||
|
||||
if (visit && mCondition)
|
||||
mCondition->traverse(it);
|
||||
|
||||
if (visit && it->postVisit)
|
||||
it->visitCase(PostVisit, this);
|
||||
}
|
||||
|
||||
//
|
||||
// Traverse a loop node. Same comments in binary node apply here.
|
||||
//
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "compiler/translator/Intermediate.h"
|
||||
#include "compiler/translator/RemoveTree.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -46,47 +45,6 @@ TIntermSymbol *TIntermediate::addSymbol(
|
||||
TIntermTyped *TIntermediate::addBinaryMath(
|
||||
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case EOpEqual:
|
||||
case EOpNotEqual:
|
||||
if (left->isArray())
|
||||
return NULL;
|
||||
break;
|
||||
case EOpLessThan:
|
||||
case EOpGreaterThan:
|
||||
case EOpLessThanEqual:
|
||||
case EOpGreaterThanEqual:
|
||||
if (left->isMatrix() || left->isArray() || left->isVector() ||
|
||||
left->getBasicType() == EbtStruct)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case EOpLogicalOr:
|
||||
case EOpLogicalXor:
|
||||
case EOpLogicalAnd:
|
||||
if (left->getBasicType() != EbtBool ||
|
||||
left->isMatrix() || left->isArray() || left->isVector())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case EOpAdd:
|
||||
case EOpSub:
|
||||
case EOpDiv:
|
||||
case EOpMul:
|
||||
if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
|
||||
return NULL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (left->getBasicType() != right->getBasicType())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Need a new node holding things together then. Make
|
||||
// one and promote it to the right type.
|
||||
@ -169,45 +127,8 @@ TIntermTyped *TIntermediate::addIndex(
|
||||
// Returns the added node.
|
||||
//
|
||||
TIntermTyped *TIntermediate::addUnaryMath(
|
||||
TOperator op, TIntermNode *childNode, const TSourceLoc &line)
|
||||
TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType)
|
||||
{
|
||||
TIntermUnary *node;
|
||||
TIntermTyped *child = childNode->getAsTyped();
|
||||
|
||||
if (child == NULL)
|
||||
{
|
||||
mInfoSink.info.message(EPrefixInternalError, line,
|
||||
"Bad type in AddUnaryMath");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case EOpLogicalNot:
|
||||
if (child->getType().getBasicType() != EbtBool ||
|
||||
child->getType().isMatrix() ||
|
||||
child->getType().isArray() ||
|
||||
child->getType().isVector())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpPostIncrement:
|
||||
case EOpPreIncrement:
|
||||
case EOpPostDecrement:
|
||||
case EOpPreDecrement:
|
||||
case EOpNegative:
|
||||
case EOpPositive:
|
||||
if (child->getType().getBasicType() == EbtStruct ||
|
||||
child->getType().isArray())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
TIntermConstantUnion *childTempConstant = 0;
|
||||
if (child->getAsConstantUnion())
|
||||
childTempConstant = child->getAsConstantUnion();
|
||||
@ -215,12 +136,10 @@ TIntermTyped *TIntermediate::addUnaryMath(
|
||||
//
|
||||
// Make a new node for the operator.
|
||||
//
|
||||
node = new TIntermUnary(op);
|
||||
TIntermUnary *node = new TIntermUnary(op);
|
||||
node->setLine(line);
|
||||
node->setOperand(child);
|
||||
|
||||
if (!node->promote(mInfoSink))
|
||||
return 0;
|
||||
node->promote(funcReturnType);
|
||||
|
||||
if (childTempConstant)
|
||||
{
|
||||
@ -423,6 +342,24 @@ TIntermTyped *TIntermediate::addSelection(
|
||||
return node;
|
||||
}
|
||||
|
||||
TIntermSwitch *TIntermediate::addSwitch(
|
||||
TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line)
|
||||
{
|
||||
TIntermSwitch *node = new TIntermSwitch(init, statementList);
|
||||
node->setLine(line);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
TIntermCase *TIntermediate::addCase(
|
||||
TIntermTyped *condition, const TSourceLoc &line)
|
||||
{
|
||||
TIntermCase *node = new TIntermCase(condition);
|
||||
node->setLine(line);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
//
|
||||
// Constant terminal nodes. Has a union that contains bool, float or int constants
|
||||
//
|
||||
@ -510,12 +447,3 @@ bool TIntermediate::postProcess(TIntermNode *root)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// This deletes the tree.
|
||||
//
|
||||
void TIntermediate::remove(TIntermNode *root)
|
||||
{
|
||||
if (root)
|
||||
RemoveAllTreeNodes(root);
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
|
||||
#define COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
|
||||
#ifndef COMPILER_TRANSLATOR_INTERMEDIATE_H_
|
||||
#define COMPILER_TRANSLATOR_INTERMEDIATE_H_
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
@ -35,7 +35,7 @@ class TIntermediate
|
||||
TIntermTyped *addIndex(
|
||||
TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &);
|
||||
TIntermTyped *addUnaryMath(
|
||||
TOperator op, TIntermNode *child, const TSourceLoc &);
|
||||
TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType);
|
||||
TIntermAggregate *growAggregate(
|
||||
TIntermNode *left, TIntermNode *right, const TSourceLoc &);
|
||||
TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &);
|
||||
@ -43,6 +43,10 @@ class TIntermediate
|
||||
TIntermNode *addSelection(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &);
|
||||
TIntermTyped *addSelection(
|
||||
TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &);
|
||||
TIntermSwitch *addSwitch(
|
||||
TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line);
|
||||
TIntermCase *addCase(
|
||||
TIntermTyped *condition, const TSourceLoc &line);
|
||||
TIntermTyped *addComma(
|
||||
TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
|
||||
TIntermConstantUnion *addConstantUnion(ConstantUnion *, const TType &, const TSourceLoc &);
|
||||
@ -55,8 +59,8 @@ class TIntermediate
|
||||
TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &);
|
||||
TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &);
|
||||
bool postProcess(TIntermNode *);
|
||||
void remove(TIntermNode *);
|
||||
void outputTree(TIntermNode *);
|
||||
|
||||
static void outputTree(TIntermNode *, TInfoSinkBase &);
|
||||
|
||||
private:
|
||||
void operator=(TIntermediate &); // prevent assignments
|
||||
@ -64,4 +68,4 @@ class TIntermediate
|
||||
TInfoSink & mInfoSink;
|
||||
};
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
|
||||
#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_TRANSLATOR_LOOP_INFO_H_
|
||||
#define COMPILER_TRANSLATOR_LOOP_INFO_H_
|
||||
#ifndef COMPILER_TRANSLATOR_LOOPINFO_H_
|
||||
#define COMPILER_TRANSLATOR_LOOPINFO_H_
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
@ -76,5 +76,5 @@ class TLoopStack : public TVector<TLoopInfo>
|
||||
void pop();
|
||||
};
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_LOOP_INDEX_H_
|
||||
#endif // COMPILER_TRANSLATOR_LOOPINFO_H_
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _MMAP_INCLUDED_
|
||||
#define _MMAP_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_MMAP_H_
|
||||
#define COMPILER_TRANSLATOR_MMAP_H_
|
||||
|
||||
//
|
||||
// Encapsulate memory mapped files
|
||||
@ -53,4 +53,4 @@ private:
|
||||
char* fBuff; // the actual data;
|
||||
};
|
||||
|
||||
#endif // _MMAP_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_MMAP_H_
|
||||
|
@ -6,8 +6,8 @@
|
||||
// NodeSearch.h: Utilities for searching translator node graphs
|
||||
//
|
||||
|
||||
#ifndef TRANSLATOR_NODESEARCH_H_
|
||||
#define TRANSLATOR_NODESEARCH_H_
|
||||
#ifndef COMPILER_TRANSLATOR_NODESEARCH_H_
|
||||
#define COMPILER_TRANSLATOR_NODESEARCH_H_
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
@ -77,4 +77,4 @@ class FindSideEffectRewriting : public NodeSearchTraverser<FindSideEffectRewriti
|
||||
|
||||
}
|
||||
|
||||
#endif // TRANSLATOR_NODESEARCH_H_
|
||||
#endif // COMPILER_TRANSLATOR_NODESEARCH_H_
|
||||
|
195
src/3rdparty/angle/src/compiler/translator/Operator.cpp
vendored
Normal file
195
src/3rdparty/angle/src/compiler/translator/Operator.cpp
vendored
Normal file
@ -0,0 +1,195 @@
|
||||
//
|
||||
// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/translator/Operator.h"
|
||||
|
||||
const char *GetOperatorString(TOperator op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
// Note: ops from EOpNull to EOpPrototype can't be handled here.
|
||||
|
||||
case EOpNegative: return "-";
|
||||
case EOpPositive: return "+";
|
||||
case EOpLogicalNot: return "!";
|
||||
case EOpVectorLogicalNot: return "not";
|
||||
case EOpBitwiseNot: return "~";
|
||||
|
||||
case EOpPostIncrement: return "++";
|
||||
case EOpPostDecrement: return "--";
|
||||
case EOpPreIncrement: return "++";
|
||||
case EOpPreDecrement: return "--";
|
||||
|
||||
case EOpAdd: return "+";
|
||||
case EOpSub: return "-";
|
||||
case EOpMul: return "*";
|
||||
case EOpDiv: return "/";
|
||||
case EOpIMod: return "%";
|
||||
case EOpEqual: return "==";
|
||||
case EOpNotEqual: return "!=";
|
||||
case EOpVectorEqual: return "equal";
|
||||
case EOpVectorNotEqual: return "notEqual";
|
||||
case EOpLessThan: return "<";
|
||||
case EOpGreaterThan: return ">";
|
||||
case EOpLessThanEqual: return "<=";
|
||||
case EOpGreaterThanEqual: return ">=";
|
||||
case EOpComma: return ",";
|
||||
|
||||
// Fall-through.
|
||||
case EOpVectorTimesScalar:
|
||||
case EOpVectorTimesMatrix:
|
||||
case EOpMatrixTimesVector:
|
||||
case EOpMatrixTimesScalar: return "*";
|
||||
|
||||
case EOpLogicalOr: return "||";
|
||||
case EOpLogicalXor: return "^^";
|
||||
case EOpLogicalAnd: return "&&";
|
||||
|
||||
case EOpBitShiftLeft: return "<<";
|
||||
case EOpBitShiftRight: return ">>";
|
||||
|
||||
case EOpBitwiseAnd: return "&";
|
||||
case EOpBitwiseXor: return "^";
|
||||
case EOpBitwiseOr: return "|";
|
||||
|
||||
// Fall-through.
|
||||
case EOpIndexDirect:
|
||||
case EOpIndexIndirect: return "[]";
|
||||
|
||||
case EOpIndexDirectStruct:
|
||||
case EOpIndexDirectInterfaceBlock: return ".";
|
||||
|
||||
case EOpVectorSwizzle: return ".";
|
||||
|
||||
case EOpRadians: return "radians";
|
||||
case EOpDegrees: return "degrees";
|
||||
case EOpSin: return "sin";
|
||||
case EOpCos: return "cos";
|
||||
case EOpTan: return "tan";
|
||||
case EOpAsin: return "asin";
|
||||
case EOpAcos: return "acos";
|
||||
case EOpAtan: return "atan";
|
||||
|
||||
case EOpSinh: return "sinh";
|
||||
case EOpCosh: return "cosh";
|
||||
case EOpTanh: return "tanh";
|
||||
case EOpAsinh: return "asinh";
|
||||
case EOpAcosh: return "acosh";
|
||||
case EOpAtanh: return "atanh";
|
||||
|
||||
case EOpPow: return "pow";
|
||||
case EOpExp: return "exp";
|
||||
case EOpLog: return "log";
|
||||
case EOpExp2: return "exp2";
|
||||
case EOpLog2: return "log2";
|
||||
case EOpSqrt: return "sqrt";
|
||||
case EOpInverseSqrt: return "inversesqrt";
|
||||
|
||||
case EOpAbs: return "abs";
|
||||
case EOpSign: return "sign";
|
||||
case EOpFloor: return "floor";
|
||||
case EOpTrunc: return "trunc";
|
||||
case EOpRound: return "round";
|
||||
case EOpRoundEven: return "roundEven";
|
||||
case EOpCeil: return "ceil";
|
||||
case EOpFract: return "fract";
|
||||
case EOpMod: return "mod";
|
||||
case EOpModf: return "modf";
|
||||
case EOpMin: return "min";
|
||||
case EOpMax: return "max";
|
||||
case EOpClamp: return "clamp";
|
||||
case EOpMix: return "mix";
|
||||
case EOpStep: return "step";
|
||||
case EOpSmoothStep: return "smoothstep";
|
||||
case EOpIsNan: return "isnan";
|
||||
case EOpIsInf: return "isinf";
|
||||
|
||||
case EOpFloatBitsToInt: return "floatBitsToInt";
|
||||
case EOpFloatBitsToUint: return "floatBitsToUint";
|
||||
case EOpIntBitsToFloat: return "intBitsToFloat";
|
||||
case EOpUintBitsToFloat: return "uintBitsToFloat";
|
||||
|
||||
case EOpPackSnorm2x16: return "packSnorm2x16";
|
||||
case EOpPackUnorm2x16: return "packUnorm2x16";
|
||||
case EOpPackHalf2x16: return "packHalf2x16";
|
||||
case EOpUnpackSnorm2x16: return "unpackSnorm2x16";
|
||||
case EOpUnpackUnorm2x16: return "unpackUnorm2x16";
|
||||
case EOpUnpackHalf2x16: return "unpackHalf2x16";
|
||||
|
||||
case EOpLength: return "length";
|
||||
case EOpDistance: return "distance";
|
||||
case EOpDot: return "dot";
|
||||
case EOpCross: return "cross";
|
||||
case EOpNormalize: return "normalize";
|
||||
case EOpFaceForward: return "faceforward";
|
||||
case EOpReflect: return "reflect";
|
||||
case EOpRefract: return "refract";
|
||||
|
||||
case EOpDFdx: return "dFdx";
|
||||
case EOpDFdy: return "dFdy";
|
||||
case EOpFwidth: return "fwidth";
|
||||
|
||||
case EOpMatrixTimesMatrix: return "*";
|
||||
|
||||
case EOpOuterProduct: return "outerProduct";
|
||||
case EOpTranspose: return "transpose";
|
||||
case EOpDeterminant: return "determinant";
|
||||
case EOpInverse: return "inverse";
|
||||
|
||||
case EOpAny: return "any";
|
||||
case EOpAll: return "all";
|
||||
|
||||
case EOpKill: return "kill";
|
||||
case EOpReturn: return "return";
|
||||
case EOpBreak: return "break";
|
||||
case EOpContinue: return "continue";
|
||||
|
||||
case EOpConstructInt: return "int";
|
||||
case EOpConstructUInt: return "uint";
|
||||
case EOpConstructBool: return "bool";
|
||||
case EOpConstructFloat: return "float";
|
||||
case EOpConstructVec2: return "vec2";
|
||||
case EOpConstructVec3: return "vec3";
|
||||
case EOpConstructVec4: return "vec4";
|
||||
case EOpConstructBVec2: return "bvec2";
|
||||
case EOpConstructBVec3: return "bvec3";
|
||||
case EOpConstructBVec4: return "bvec4";
|
||||
case EOpConstructIVec2: return "ivec2";
|
||||
case EOpConstructIVec3: return "ivec3";
|
||||
case EOpConstructIVec4: return "ivec4";
|
||||
case EOpConstructUVec2: return "uvec2";
|
||||
case EOpConstructUVec3: return "uvec3";
|
||||
case EOpConstructUVec4: return "uvec4";
|
||||
case EOpConstructMat2: return "mat2";
|
||||
case EOpConstructMat3: return "mat3";
|
||||
case EOpConstructMat4: return "mat4";
|
||||
// Note: EOpConstructStruct can't be handled here
|
||||
|
||||
case EOpAssign: return "=";
|
||||
case EOpInitialize: return "=";
|
||||
case EOpAddAssign: return "+=";
|
||||
case EOpSubAssign: return "-=";
|
||||
|
||||
// Fall-through.
|
||||
case EOpMulAssign:
|
||||
case EOpVectorTimesMatrixAssign:
|
||||
case EOpVectorTimesScalarAssign:
|
||||
case EOpMatrixTimesScalarAssign:
|
||||
case EOpMatrixTimesMatrixAssign: return "*=";
|
||||
|
||||
case EOpDivAssign: return "/=";
|
||||
case EOpIModAssign: return "%=";
|
||||
case EOpBitShiftLeftAssign: return "<<=";
|
||||
case EOpBitShiftRightAssign: return ">>=";
|
||||
case EOpBitwiseAndAssign: return "&=";
|
||||
case EOpBitwiseXorAssign: return "^=";
|
||||
case EOpBitwiseOrAssign: return "|=";
|
||||
|
||||
default: break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
226
src/3rdparty/angle/src/compiler/translator/Operator.h
vendored
Normal file
226
src/3rdparty/angle/src/compiler/translator/Operator.h
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
//
|
||||
// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_TRANSLATOR_OPERATOR_H_
|
||||
#define COMPILER_TRANSLATOR_OPERATOR_H_
|
||||
|
||||
//
|
||||
// Operators used by the high-level (parse tree) representation.
|
||||
//
|
||||
enum TOperator
|
||||
{
|
||||
EOpNull, // if in a node, should only mean a node is still being built
|
||||
EOpSequence, // denotes a list of statements, or parameters, etc.
|
||||
EOpFunctionCall,
|
||||
EOpInternalFunctionCall, // Call to an internal helper function
|
||||
EOpFunction, // For function definition
|
||||
EOpParameters, // an aggregate listing the parameters to a function
|
||||
|
||||
EOpDeclaration,
|
||||
EOpInvariantDeclaration, // Specialized declarations for attributing invariance
|
||||
EOpPrototype,
|
||||
|
||||
//
|
||||
// Unary operators
|
||||
//
|
||||
|
||||
EOpNegative,
|
||||
EOpPositive,
|
||||
EOpLogicalNot,
|
||||
EOpVectorLogicalNot,
|
||||
EOpBitwiseNot,
|
||||
|
||||
EOpPostIncrement,
|
||||
EOpPostDecrement,
|
||||
EOpPreIncrement,
|
||||
EOpPreDecrement,
|
||||
|
||||
//
|
||||
// binary operations
|
||||
//
|
||||
|
||||
EOpAdd,
|
||||
EOpSub,
|
||||
EOpMul,
|
||||
EOpDiv,
|
||||
EOpIMod,
|
||||
EOpEqual,
|
||||
EOpNotEqual,
|
||||
EOpVectorEqual,
|
||||
EOpVectorNotEqual,
|
||||
EOpLessThan,
|
||||
EOpGreaterThan,
|
||||
EOpLessThanEqual,
|
||||
EOpGreaterThanEqual,
|
||||
EOpComma,
|
||||
|
||||
EOpVectorTimesScalar,
|
||||
EOpVectorTimesMatrix,
|
||||
EOpMatrixTimesVector,
|
||||
EOpMatrixTimesScalar,
|
||||
|
||||
EOpLogicalOr,
|
||||
EOpLogicalXor,
|
||||
EOpLogicalAnd,
|
||||
|
||||
EOpBitShiftLeft,
|
||||
EOpBitShiftRight,
|
||||
|
||||
EOpBitwiseAnd,
|
||||
EOpBitwiseXor,
|
||||
EOpBitwiseOr,
|
||||
|
||||
EOpIndexDirect,
|
||||
EOpIndexIndirect,
|
||||
EOpIndexDirectStruct,
|
||||
EOpIndexDirectInterfaceBlock,
|
||||
|
||||
EOpVectorSwizzle,
|
||||
|
||||
//
|
||||
// Built-in functions potentially mapped to operators
|
||||
//
|
||||
|
||||
EOpRadians,
|
||||
EOpDegrees,
|
||||
EOpSin,
|
||||
EOpCos,
|
||||
EOpTan,
|
||||
EOpAsin,
|
||||
EOpAcos,
|
||||
EOpAtan,
|
||||
|
||||
EOpSinh,
|
||||
EOpCosh,
|
||||
EOpTanh,
|
||||
EOpAsinh,
|
||||
EOpAcosh,
|
||||
EOpAtanh,
|
||||
|
||||
EOpPow,
|
||||
EOpExp,
|
||||
EOpLog,
|
||||
EOpExp2,
|
||||
EOpLog2,
|
||||
EOpSqrt,
|
||||
EOpInverseSqrt,
|
||||
|
||||
EOpAbs,
|
||||
EOpSign,
|
||||
EOpFloor,
|
||||
EOpTrunc,
|
||||
EOpRound,
|
||||
EOpRoundEven,
|
||||
EOpCeil,
|
||||
EOpFract,
|
||||
EOpMod,
|
||||
EOpModf,
|
||||
EOpMin,
|
||||
EOpMax,
|
||||
EOpClamp,
|
||||
EOpMix,
|
||||
EOpStep,
|
||||
EOpSmoothStep,
|
||||
EOpIsNan,
|
||||
EOpIsInf,
|
||||
|
||||
EOpFloatBitsToInt,
|
||||
EOpFloatBitsToUint,
|
||||
EOpIntBitsToFloat,
|
||||
EOpUintBitsToFloat,
|
||||
|
||||
EOpPackSnorm2x16,
|
||||
EOpPackUnorm2x16,
|
||||
EOpPackHalf2x16,
|
||||
EOpUnpackSnorm2x16,
|
||||
EOpUnpackUnorm2x16,
|
||||
EOpUnpackHalf2x16,
|
||||
|
||||
EOpLength,
|
||||
EOpDistance,
|
||||
EOpDot,
|
||||
EOpCross,
|
||||
EOpNormalize,
|
||||
EOpFaceForward,
|
||||
EOpReflect,
|
||||
EOpRefract,
|
||||
|
||||
EOpDFdx, // Fragment only, OES_standard_derivatives extension
|
||||
EOpDFdy, // Fragment only, OES_standard_derivatives extension
|
||||
EOpFwidth, // Fragment only, OES_standard_derivatives extension
|
||||
|
||||
EOpMatrixTimesMatrix,
|
||||
|
||||
EOpOuterProduct,
|
||||
EOpTranspose,
|
||||
EOpDeterminant,
|
||||
EOpInverse,
|
||||
|
||||
EOpAny,
|
||||
EOpAll,
|
||||
|
||||
//
|
||||
// Branch
|
||||
//
|
||||
|
||||
EOpKill, // Fragment only
|
||||
EOpReturn,
|
||||
EOpBreak,
|
||||
EOpContinue,
|
||||
|
||||
//
|
||||
// Constructors
|
||||
//
|
||||
|
||||
EOpConstructInt,
|
||||
EOpConstructUInt,
|
||||
EOpConstructBool,
|
||||
EOpConstructFloat,
|
||||
EOpConstructVec2,
|
||||
EOpConstructVec3,
|
||||
EOpConstructVec4,
|
||||
EOpConstructBVec2,
|
||||
EOpConstructBVec3,
|
||||
EOpConstructBVec4,
|
||||
EOpConstructIVec2,
|
||||
EOpConstructIVec3,
|
||||
EOpConstructIVec4,
|
||||
EOpConstructUVec2,
|
||||
EOpConstructUVec3,
|
||||
EOpConstructUVec4,
|
||||
EOpConstructMat2,
|
||||
EOpConstructMat3,
|
||||
EOpConstructMat4,
|
||||
EOpConstructStruct,
|
||||
|
||||
//
|
||||
// moves
|
||||
//
|
||||
|
||||
EOpAssign,
|
||||
EOpInitialize,
|
||||
EOpAddAssign,
|
||||
EOpSubAssign,
|
||||
|
||||
EOpMulAssign,
|
||||
EOpVectorTimesMatrixAssign,
|
||||
EOpVectorTimesScalarAssign,
|
||||
EOpMatrixTimesScalarAssign,
|
||||
EOpMatrixTimesMatrixAssign,
|
||||
|
||||
EOpDivAssign,
|
||||
EOpIModAssign,
|
||||
EOpBitShiftLeftAssign,
|
||||
EOpBitShiftRightAssign,
|
||||
EOpBitwiseAndAssign,
|
||||
EOpBitwiseXorAssign,
|
||||
EOpBitwiseOrAssign
|
||||
};
|
||||
|
||||
// Returns the string corresponding to the operator in GLSL
|
||||
const char* GetOperatorString(TOperator op);
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_OPERATOR_H_
|
@ -6,13 +6,21 @@
|
||||
|
||||
#include "compiler/translator/OutputESSL.h"
|
||||
|
||||
TOutputESSL::TOutputESSL(TInfoSinkBase& objSink,
|
||||
TOutputESSL::TOutputESSL(TInfoSinkBase &objSink,
|
||||
ShArrayIndexClampingStrategy clampingStrategy,
|
||||
ShHashFunction64 hashFunction,
|
||||
NameMap& nameMap,
|
||||
TSymbolTable& symbolTable,
|
||||
int shaderVersion)
|
||||
: TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable, shaderVersion)
|
||||
NameMap &nameMap,
|
||||
TSymbolTable &symbolTable,
|
||||
int shaderVersion,
|
||||
bool forceHighp)
|
||||
: TOutputGLSLBase(objSink,
|
||||
clampingStrategy,
|
||||
hashFunction,
|
||||
nameMap,
|
||||
symbolTable,
|
||||
shaderVersion,
|
||||
SH_ESSL_OUTPUT),
|
||||
mForceHighp(forceHighp)
|
||||
{
|
||||
}
|
||||
|
||||
@ -22,6 +30,9 @@ bool TOutputESSL::writeVariablePrecision(TPrecision precision)
|
||||
return false;
|
||||
|
||||
TInfoSinkBase& out = objSink();
|
||||
out << getPrecisionString(precision);
|
||||
if (mForceHighp)
|
||||
out << getPrecisionString(EbpHigh);
|
||||
else
|
||||
out << getPrecisionString(precision);
|
||||
return true;
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef CROSSCOMPILERGLSL_OUTPUTESSL_H_
|
||||
#define CROSSCOMPILERGLSL_OUTPUTESSL_H_
|
||||
#ifndef COMPILER_TRANSLATOR_OUTPUTESSL_H_
|
||||
#define COMPILER_TRANSLATOR_OUTPUTESSL_H_
|
||||
|
||||
#include "compiler/translator/OutputGLSLBase.h"
|
||||
|
||||
@ -17,10 +17,13 @@ public:
|
||||
ShHashFunction64 hashFunction,
|
||||
NameMap& nameMap,
|
||||
TSymbolTable& symbolTable,
|
||||
int shaderVersion);
|
||||
int shaderVersion,
|
||||
bool forceHighp);
|
||||
|
||||
protected:
|
||||
virtual bool writeVariablePrecision(TPrecision precision);
|
||||
private:
|
||||
bool mForceHighp;
|
||||
};
|
||||
|
||||
#endif // CROSSCOMPILERGLSL_OUTPUTESSL_H_
|
||||
#endif // COMPILER_TRANSLATOR_OUTPUTESSL_H_
|
||||
|
@ -11,8 +11,15 @@ TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink,
|
||||
ShHashFunction64 hashFunction,
|
||||
NameMap& nameMap,
|
||||
TSymbolTable& symbolTable,
|
||||
int shaderVersion)
|
||||
: TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable, shaderVersion)
|
||||
int shaderVersion,
|
||||
ShShaderOutput output)
|
||||
: TOutputGLSLBase(objSink,
|
||||
clampingStrategy,
|
||||
hashFunction,
|
||||
nameMap,
|
||||
symbolTable,
|
||||
shaderVersion,
|
||||
output)
|
||||
{
|
||||
}
|
||||
|
||||
@ -21,21 +28,30 @@ bool TOutputGLSL::writeVariablePrecision(TPrecision)
|
||||
return false;
|
||||
}
|
||||
|
||||
void TOutputGLSL::visitSymbol(TIntermSymbol* node)
|
||||
void TOutputGLSL::visitSymbol(TIntermSymbol *node)
|
||||
{
|
||||
TInfoSinkBase& out = objSink();
|
||||
|
||||
if (node->getSymbol() == "gl_FragDepthEXT")
|
||||
const TString &symbol = node->getSymbol();
|
||||
if (symbol == "gl_FragDepthEXT")
|
||||
{
|
||||
out << "gl_FragDepth";
|
||||
}
|
||||
else if (symbol == "gl_FragColor" && getShaderOutput() == SH_GLSL_CORE_OUTPUT)
|
||||
{
|
||||
out << "webgl_FragColor";
|
||||
}
|
||||
else if (symbol == "gl_FragData" && getShaderOutput() == SH_GLSL_CORE_OUTPUT)
|
||||
{
|
||||
out << "webgl_FragData";
|
||||
}
|
||||
else
|
||||
{
|
||||
TOutputGLSLBase::visitSymbol(node);
|
||||
}
|
||||
}
|
||||
|
||||
TString TOutputGLSL::translateTextureFunction(TString& name)
|
||||
TString TOutputGLSL::translateTextureFunction(TString &name)
|
||||
{
|
||||
static const char *simpleRename[] = {
|
||||
"texture2DLodEXT", "texture2DLod",
|
||||
@ -46,10 +62,30 @@ TString TOutputGLSL::translateTextureFunction(TString& name)
|
||||
"textureCubeGradEXT", "textureCubeGradARB",
|
||||
NULL, NULL
|
||||
};
|
||||
static const char *legacyToCoreRename[] = {
|
||||
"texture2D", "texture",
|
||||
"texture2DProj", "textureProj",
|
||||
"texture2DLod", "textureLod",
|
||||
"texture2DProjLod", "textureProjLod",
|
||||
"textureCube", "texture",
|
||||
"textureCubeLod", "textureLod",
|
||||
// Extensions
|
||||
"texture2DLodEXT", "textureLod",
|
||||
"texture2DProjLodEXT", "textureProjLod",
|
||||
"textureCubeLodEXT", "textureLod",
|
||||
"texture2DGradEXT", "textureGrad",
|
||||
"texture2DProjGradEXT", "textureProjGrad",
|
||||
"textureCubeGradEXT", "textureGrad",
|
||||
NULL, NULL
|
||||
};
|
||||
const char **mapping = (getShaderOutput() == SH_GLSL_CORE_OUTPUT) ?
|
||||
legacyToCoreRename : simpleRename;
|
||||
|
||||
for (int i = 0; simpleRename[i] != NULL; i += 2) {
|
||||
if (name == simpleRename[i]) {
|
||||
return simpleRename[i+1];
|
||||
for (int i = 0; mapping[i] != NULL; i += 2)
|
||||
{
|
||||
if (name == mapping[i])
|
||||
{
|
||||
return mapping[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,25 +4,26 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef CROSSCOMPILERGLSL_OUTPUTGLSL_H_
|
||||
#define CROSSCOMPILERGLSL_OUTPUTGLSL_H_
|
||||
#ifndef COMPILER_TRANSLATOR_OUTPUTGLSL_H_
|
||||
#define COMPILER_TRANSLATOR_OUTPUTGLSL_H_
|
||||
|
||||
#include "compiler/translator/OutputGLSLBase.h"
|
||||
|
||||
class TOutputGLSL : public TOutputGLSLBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
TOutputGLSL(TInfoSinkBase& objSink,
|
||||
ShArrayIndexClampingStrategy clampingStrategy,
|
||||
ShHashFunction64 hashFunction,
|
||||
NameMap& nameMap,
|
||||
TSymbolTable& symbolTable,
|
||||
int shaderVersion);
|
||||
int shaderVersion,
|
||||
ShShaderOutput output);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
virtual bool writeVariablePrecision(TPrecision);
|
||||
virtual void visitSymbol(TIntermSymbol* node);
|
||||
virtual TString translateTextureFunction(TString& name);
|
||||
};
|
||||
|
||||
#endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
|
||||
#endif // COMPILER_TRANSLATOR_OUTPUTGLSL_H_
|
||||
|
@ -36,8 +36,17 @@ bool isSingleStatement(TIntermNode *node)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (node->getAsSwitchNode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (node->getAsCaseNode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
|
||||
@ -45,7 +54,8 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
|
||||
ShHashFunction64 hashFunction,
|
||||
NameMap &nameMap,
|
||||
TSymbolTable &symbolTable,
|
||||
int shaderVersion)
|
||||
int shaderVersion,
|
||||
ShShaderOutput output)
|
||||
: TIntermTraverser(true, true, true),
|
||||
mObjSink(objSink),
|
||||
mDeclaringVariables(false),
|
||||
@ -53,7 +63,8 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
|
||||
mHashFunction(hashFunction),
|
||||
mNameMap(nameMap),
|
||||
mSymbolTable(symbolTable),
|
||||
mShaderVersion(shaderVersion)
|
||||
mShaderVersion(shaderVersion),
|
||||
mOutput(output)
|
||||
{
|
||||
}
|
||||
|
||||
@ -83,7 +94,34 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
|
||||
TQualifier qualifier = type.getQualifier();
|
||||
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
|
||||
{
|
||||
out << type.getQualifierString() << " ";
|
||||
if (mOutput == SH_GLSL_CORE_OUTPUT)
|
||||
{
|
||||
switch (qualifier)
|
||||
{
|
||||
case EvqAttribute:
|
||||
out << "in" << " ";
|
||||
break;
|
||||
case EvqVaryingIn:
|
||||
out << "in" << " ";
|
||||
break;
|
||||
case EvqVaryingOut:
|
||||
out << "out" << " ";
|
||||
break;
|
||||
case EvqInvariantVaryingIn:
|
||||
out << "invariant in" << " ";
|
||||
break;
|
||||
case EvqInvariantVaryingOut:
|
||||
out << "invariant out" << " ";
|
||||
break;
|
||||
default:
|
||||
out << type.getQualifierString() << " ";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out << type.getQualifierString() << " ";
|
||||
}
|
||||
}
|
||||
// Declare the struct if we have not done so already.
|
||||
if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
|
||||
@ -166,6 +204,9 @@ const ConstantUnion *TOutputGLSLBase::writeConstantUnion(
|
||||
case EbtInt:
|
||||
out << pConstUnion->getIConst();
|
||||
break;
|
||||
case EbtUInt:
|
||||
out << pConstUnion->getUConst() << "u";
|
||||
break;
|
||||
case EbtBool:
|
||||
out << pConstUnion->getBConst();
|
||||
break;
|
||||
@ -223,6 +264,9 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
|
||||
case EOpDivAssign:
|
||||
writeTriplet(visit, "(", " /= ", ")");
|
||||
break;
|
||||
case EOpIModAssign:
|
||||
writeTriplet(visit, "(", " %= ", ")");
|
||||
break;
|
||||
// Notice the fall-through.
|
||||
case EOpMulAssign:
|
||||
case EOpVectorTimesMatrixAssign:
|
||||
@ -231,6 +275,21 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
|
||||
case EOpMatrixTimesMatrixAssign:
|
||||
writeTriplet(visit, "(", " *= ", ")");
|
||||
break;
|
||||
case EOpBitShiftLeftAssign:
|
||||
writeTriplet(visit, "(", " <<= ", ")");
|
||||
break;
|
||||
case EOpBitShiftRightAssign:
|
||||
writeTriplet(visit, "(", " >>= ", ")");
|
||||
break;
|
||||
case EOpBitwiseAndAssign:
|
||||
writeTriplet(visit, "(", " &= ", ")");
|
||||
break;
|
||||
case EOpBitwiseXorAssign:
|
||||
writeTriplet(visit, "(", " ^= ", ")");
|
||||
break;
|
||||
case EOpBitwiseOrAssign:
|
||||
writeTriplet(visit, "(", " |= ", ")");
|
||||
break;
|
||||
|
||||
case EOpIndexDirect:
|
||||
writeTriplet(visit, NULL, "[", "]");
|
||||
@ -340,9 +399,25 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
|
||||
case EOpDiv:
|
||||
writeTriplet(visit, "(", " / ", ")");
|
||||
break;
|
||||
case EOpMod:
|
||||
UNIMPLEMENTED();
|
||||
case EOpIMod:
|
||||
writeTriplet(visit, "(", " % ", ")");
|
||||
break;
|
||||
case EOpBitShiftLeft:
|
||||
writeTriplet(visit, "(", " << ", ")");
|
||||
break;
|
||||
case EOpBitShiftRight:
|
||||
writeTriplet(visit, "(", " >> ", ")");
|
||||
break;
|
||||
case EOpBitwiseAnd:
|
||||
writeTriplet(visit, "(", " & ", ")");
|
||||
break;
|
||||
case EOpBitwiseXor:
|
||||
writeTriplet(visit, "(", " ^ ", ")");
|
||||
break;
|
||||
case EOpBitwiseOr:
|
||||
writeTriplet(visit, "(", " | ", ")");
|
||||
break;
|
||||
|
||||
case EOpEqual:
|
||||
writeTriplet(visit, "(", " == ", ")");
|
||||
break;
|
||||
@ -398,6 +473,7 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
|
||||
case EOpPositive: preString = "(+"; break;
|
||||
case EOpVectorLogicalNot: preString = "not("; break;
|
||||
case EOpLogicalNot: preString = "(!"; break;
|
||||
case EOpBitwiseNot: preString = "(~"; break;
|
||||
|
||||
case EOpPostIncrement: preString = "("; postString = "++)"; break;
|
||||
case EOpPostDecrement: preString = "("; postString = "--)"; break;
|
||||
@ -429,6 +505,25 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
|
||||
preString = "atan(";
|
||||
break;
|
||||
|
||||
case EOpSinh:
|
||||
preString = "sinh(";
|
||||
break;
|
||||
case EOpCosh:
|
||||
preString = "cosh(";
|
||||
break;
|
||||
case EOpTanh:
|
||||
preString = "tanh(";
|
||||
break;
|
||||
case EOpAsinh:
|
||||
preString = "asinh(";
|
||||
break;
|
||||
case EOpAcosh:
|
||||
preString = "acosh(";
|
||||
break;
|
||||
case EOpAtanh:
|
||||
preString = "atanh(";
|
||||
break;
|
||||
|
||||
case EOpExp:
|
||||
preString = "exp(";
|
||||
break;
|
||||
@ -457,12 +552,59 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
|
||||
case EOpFloor:
|
||||
preString = "floor(";
|
||||
break;
|
||||
case EOpTrunc:
|
||||
preString = "trunc(";
|
||||
break;
|
||||
case EOpRound:
|
||||
preString = "round(";
|
||||
break;
|
||||
case EOpRoundEven:
|
||||
preString = "roundEven(";
|
||||
break;
|
||||
case EOpCeil:
|
||||
preString = "ceil(";
|
||||
break;
|
||||
case EOpFract:
|
||||
preString = "fract(";
|
||||
break;
|
||||
case EOpIsNan:
|
||||
preString = "isnan(";
|
||||
break;
|
||||
case EOpIsInf:
|
||||
preString = "isinf(";
|
||||
break;
|
||||
|
||||
case EOpFloatBitsToInt:
|
||||
preString = "floatBitsToInt(";
|
||||
break;
|
||||
case EOpFloatBitsToUint:
|
||||
preString = "floatBitsToUint(";
|
||||
break;
|
||||
case EOpIntBitsToFloat:
|
||||
preString = "intBitsToFloat(";
|
||||
break;
|
||||
case EOpUintBitsToFloat:
|
||||
preString = "uintBitsToFloat(";
|
||||
break;
|
||||
|
||||
case EOpPackSnorm2x16:
|
||||
preString = "packSnorm2x16(";
|
||||
break;
|
||||
case EOpPackUnorm2x16:
|
||||
preString = "packUnorm2x16(";
|
||||
break;
|
||||
case EOpPackHalf2x16:
|
||||
preString = "packHalf2x16(";
|
||||
break;
|
||||
case EOpUnpackSnorm2x16:
|
||||
preString = "unpackSnorm2x16(";
|
||||
break;
|
||||
case EOpUnpackUnorm2x16:
|
||||
preString = "unpackUnorm2x16(";
|
||||
break;
|
||||
case EOpUnpackHalf2x16:
|
||||
preString = "unpackHalf2x16(";
|
||||
break;
|
||||
|
||||
case EOpLength:
|
||||
preString = "length(";
|
||||
@ -481,6 +623,16 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
|
||||
preString = "fwidth(";
|
||||
break;
|
||||
|
||||
case EOpTranspose:
|
||||
preString = "transpose(";
|
||||
break;
|
||||
case EOpDeterminant:
|
||||
preString = "determinant(";
|
||||
break;
|
||||
case EOpInverse:
|
||||
preString = "inverse(";
|
||||
break;
|
||||
|
||||
case EOpAny:
|
||||
preString = "any(";
|
||||
break;
|
||||
@ -536,6 +688,36 @@ bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection *node)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TOutputGLSLBase::visitSwitch(Visit visit, TIntermSwitch *node)
|
||||
{
|
||||
if (node->getStatementList())
|
||||
{
|
||||
writeTriplet(visit, "switch (", ") ", nullptr);
|
||||
// The curly braces get written when visiting the statementList aggregate
|
||||
}
|
||||
else
|
||||
{
|
||||
// No statementList, so it won't output curly braces
|
||||
writeTriplet(visit, "switch (", ") {", "}\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TOutputGLSLBase::visitCase(Visit visit, TIntermCase *node)
|
||||
{
|
||||
if (node->hasCondition())
|
||||
{
|
||||
writeTriplet(visit, "case (", nullptr, "):\n");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
TInfoSinkBase &out = objSink();
|
||||
out << "default:\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
{
|
||||
bool visitChildren = true;
|
||||
@ -555,11 +737,11 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
|
||||
iter != node->getSequence()->end(); ++iter)
|
||||
{
|
||||
TIntermNode *node = *iter;
|
||||
ASSERT(node != NULL);
|
||||
node->traverse(this);
|
||||
TIntermNode *curNode = *iter;
|
||||
ASSERT(curNode != NULL);
|
||||
curNode->traverse(this);
|
||||
|
||||
if (isSingleStatement(node))
|
||||
if (isSingleStatement(curNode))
|
||||
out << ";\n";
|
||||
}
|
||||
decrementDepth();
|
||||
@ -622,6 +804,15 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
else
|
||||
out << ")";
|
||||
break;
|
||||
case EOpInternalFunctionCall:
|
||||
// Function call to an internal helper function.
|
||||
if (visit == PreVisit)
|
||||
out << node->getName() << "(";
|
||||
else if (visit == InVisit)
|
||||
out << ", ";
|
||||
else
|
||||
out << ")";
|
||||
break;
|
||||
case EOpParameters:
|
||||
// Function parameters.
|
||||
ASSERT(visit == PreVisit);
|
||||
@ -724,6 +915,10 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpOuterProduct:
|
||||
writeBuiltInFunctionTriplet(visit, "outerProduct(", useEmulatedFunction);
|
||||
break;
|
||||
|
||||
case EOpLessThan:
|
||||
writeBuiltInFunctionTriplet(visit, "lessThan(", useEmulatedFunction);
|
||||
break;
|
||||
@ -749,6 +944,9 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
case EOpMod:
|
||||
writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction);
|
||||
break;
|
||||
case EOpModf:
|
||||
writeBuiltInFunctionTriplet(visit, "modf(", useEmulatedFunction);
|
||||
break;
|
||||
case EOpPow:
|
||||
writeBuiltInFunctionTriplet(visit, "pow(", useEmulatedFunction);
|
||||
break;
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
|
||||
#define CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
|
||||
#ifndef COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
|
||||
#define COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
|
||||
|
||||
#include <set>
|
||||
|
||||
@ -21,7 +21,13 @@ class TOutputGLSLBase : public TIntermTraverser
|
||||
ShHashFunction64 hashFunction,
|
||||
NameMap &nameMap,
|
||||
TSymbolTable& symbolTable,
|
||||
int shaderVersion);
|
||||
int shaderVersion,
|
||||
ShShaderOutput output);
|
||||
|
||||
ShShaderOutput getShaderOutput() const
|
||||
{
|
||||
return mOutput;
|
||||
}
|
||||
|
||||
protected:
|
||||
TInfoSinkBase &objSink() { return mObjSink; }
|
||||
@ -37,6 +43,8 @@ class TOutputGLSLBase : public TIntermTraverser
|
||||
virtual bool visitBinary(Visit visit, TIntermBinary *node);
|
||||
virtual bool visitUnary(Visit visit, TIntermUnary *node);
|
||||
virtual bool visitSelection(Visit visit, TIntermSelection *node);
|
||||
virtual bool visitSwitch(Visit visit, TIntermSwitch *node);
|
||||
virtual bool visitCase(Visit visit, TIntermCase *node);
|
||||
virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
|
||||
virtual bool visitLoop(Visit visit, TIntermLoop *node);
|
||||
virtual bool visitBranch(Visit visit, TIntermBranch *node);
|
||||
@ -78,6 +86,8 @@ class TOutputGLSLBase : public TIntermTraverser
|
||||
TSymbolTable &mSymbolTable;
|
||||
|
||||
const int mShaderVersion;
|
||||
|
||||
ShShaderOutput mOutput;
|
||||
};
|
||||
|
||||
#endif // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
|
||||
#endif // COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,18 +4,20 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_OUTPUTHLSL_H_
|
||||
#define COMPILER_OUTPUTHLSL_H_
|
||||
#ifndef COMPILER_TRANSLATOR_OUTPUTHLSL_H_
|
||||
#define COMPILER_TRANSLATOR_OUTPUTHLSL_H_
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
||||
#include "angle_gl.h"
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
#include "compiler/translator/ParseContext.h"
|
||||
|
||||
class BuiltInFunctionEmulator;
|
||||
|
||||
namespace sh
|
||||
{
|
||||
class UnfoldShortCircuit;
|
||||
@ -27,20 +29,25 @@ typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
|
||||
class OutputHLSL : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator);
|
||||
OutputHLSL(sh::GLenum shaderType, int shaderVersion,
|
||||
const TExtensionBehavior &extensionBehavior,
|
||||
const char *sourcePath, ShShaderOutput outputType,
|
||||
int numRenderTargets, const std::vector<Uniform> &uniforms,
|
||||
int compileOptions);
|
||||
|
||||
~OutputHLSL();
|
||||
|
||||
void output();
|
||||
|
||||
TInfoSinkBase &getBodyStream();
|
||||
void output(TIntermNode *treeRoot, TInfoSinkBase &objSink);
|
||||
|
||||
const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const;
|
||||
const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
|
||||
|
||||
static TString initializer(const TType &type);
|
||||
|
||||
TInfoSinkBase &getInfoSink() { ASSERT(!mInfoSinkStack.empty()); return *mInfoSinkStack.top(); }
|
||||
|
||||
protected:
|
||||
void header();
|
||||
void header(const BuiltInFunctionEmulator *builtInFunctionEmulator);
|
||||
|
||||
// Visit AST nodes and output their code to the body stream
|
||||
void visitSymbol(TIntermSymbol*);
|
||||
@ -49,6 +56,8 @@ class OutputHLSL : public TIntermTraverser
|
||||
bool visitBinary(Visit visit, TIntermBinary*);
|
||||
bool visitUnary(Visit visit, TIntermUnary*);
|
||||
bool visitSelection(Visit visit, TIntermSelection*);
|
||||
bool visitSwitch(Visit visit, TIntermSwitch *);
|
||||
bool visitCase(Visit visit, TIntermCase *);
|
||||
bool visitAggregate(Visit visit, TIntermAggregate*);
|
||||
bool visitLoop(Visit visit, TIntermLoop*);
|
||||
bool visitBranch(Visit visit, TIntermBranch*);
|
||||
@ -56,16 +65,39 @@ class OutputHLSL : public TIntermTraverser
|
||||
void traverseStatements(TIntermNode *node);
|
||||
bool isSingleStatement(TIntermNode *node);
|
||||
bool handleExcessiveLoop(TIntermLoop *node);
|
||||
void outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString);
|
||||
|
||||
// Emit one of three strings depending on traverse phase. Called with literal strings so using const char* instead of TString.
|
||||
void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString, TInfoSinkBase &out);
|
||||
void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString);
|
||||
void outputLineDirective(int line);
|
||||
TString argumentString(const TIntermSymbol *symbol);
|
||||
int vectorSize(const TType &type) const;
|
||||
|
||||
void outputConstructor(Visit visit, const TType &type, const TString &name, const TIntermSequence *parameters);
|
||||
// Emit constructor. Called with literal names so using const char* instead of TString.
|
||||
void outputConstructor(Visit visit, const TType &type, const char *name, const TIntermSequence *parameters);
|
||||
const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *constUnion);
|
||||
|
||||
TParseContext &mContext;
|
||||
void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out);
|
||||
|
||||
void writeEmulatedFunctionTriplet(Visit visit, const char *preStr);
|
||||
void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs);
|
||||
|
||||
// Returns true if it found a 'same symbol' initializer (initializer that references the variable it's initting)
|
||||
bool writeSameSymbolInitializer(TInfoSinkBase &out, TIntermSymbol *symbolNode, TIntermTyped *expression);
|
||||
void writeDeferredGlobalInitializers(TInfoSinkBase &out);
|
||||
|
||||
// Returns the function name
|
||||
TString addStructEqualityFunction(const TStructure &structure);
|
||||
TString addArrayEqualityFunction(const TType &type);
|
||||
TString addArrayAssignmentFunction(const TType &type);
|
||||
|
||||
sh::GLenum mShaderType;
|
||||
int mShaderVersion;
|
||||
const TExtensionBehavior &mExtensionBehavior;
|
||||
const char *mSourcePath;
|
||||
const ShShaderOutput mOutputType;
|
||||
int mCompileOptions;
|
||||
|
||||
UnfoldShortCircuit *mUnfoldShortCircuit;
|
||||
bool mInsideFunction;
|
||||
|
||||
@ -74,6 +106,11 @@ class OutputHLSL : public TIntermTraverser
|
||||
TInfoSinkBase mBody;
|
||||
TInfoSinkBase mFooter;
|
||||
|
||||
// A stack is useful when we want to traverse in the header, or in helper functions, but not always
|
||||
// write to the body. Instead use an InfoSink stack to keep our current state intact.
|
||||
// TODO (jmadill): Just passing an InfoSink in function parameters would be simpler.
|
||||
std::stack<TInfoSinkBase *> mInfoSinkStack;
|
||||
|
||||
ReferencedSymbols mReferencedUniforms;
|
||||
ReferencedSymbols mReferencedInterfaceBlocks;
|
||||
ReferencedSymbols mReferencedAttributes;
|
||||
@ -119,25 +156,13 @@ class OutputHLSL : public TIntermTraverser
|
||||
bool mUsesPointCoord;
|
||||
bool mUsesFrontFacing;
|
||||
bool mUsesPointSize;
|
||||
bool mUsesInstanceID;
|
||||
bool mUsesFragDepth;
|
||||
bool mUsesXor;
|
||||
bool mUsesMod1;
|
||||
bool mUsesMod2v;
|
||||
bool mUsesMod2f;
|
||||
bool mUsesMod3v;
|
||||
bool mUsesMod3f;
|
||||
bool mUsesMod4v;
|
||||
bool mUsesMod4f;
|
||||
bool mUsesFaceforward1;
|
||||
bool mUsesFaceforward2;
|
||||
bool mUsesFaceforward3;
|
||||
bool mUsesFaceforward4;
|
||||
bool mUsesAtan2_1;
|
||||
bool mUsesAtan2_2;
|
||||
bool mUsesAtan2_3;
|
||||
bool mUsesAtan2_4;
|
||||
bool mUsesDiscardRewriting;
|
||||
bool mUsesNestedBreak;
|
||||
bool mRequiresIEEEStrictCompiling;
|
||||
|
||||
|
||||
int mNumRenderTargets;
|
||||
|
||||
@ -156,9 +181,41 @@ class OutputHLSL : public TIntermTraverser
|
||||
std::map<TIntermTyped*, TString> mFlaggedStructMappedNames;
|
||||
std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames;
|
||||
|
||||
void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs);
|
||||
// Some initializers use varyings, uniforms or attributes, thus we can't evaluate some variables
|
||||
// at global static scope in HLSL. These variables depend on values which we retrieve from the
|
||||
// shader input structure, which we set in the D3D main function. Instead, we can initialize
|
||||
// these static globals after we initialize our other globals.
|
||||
std::vector<std::pair<TIntermSymbol*, TIntermTyped*>> mDeferredGlobalInitializers;
|
||||
|
||||
struct HelperFunction
|
||||
{
|
||||
TString functionName;
|
||||
TString functionDefinition;
|
||||
|
||||
virtual ~HelperFunction() {}
|
||||
};
|
||||
|
||||
// A list of all equality comparison functions. It's important to preserve the order at
|
||||
// which we add the functions, since nested structures call each other recursively, and
|
||||
// structure equality functions may need to call array equality functions and vice versa.
|
||||
// The ownership of the pointers is maintained by the type-specific arrays.
|
||||
std::vector<HelperFunction*> mEqualityFunctions;
|
||||
|
||||
struct StructEqualityFunction : public HelperFunction
|
||||
{
|
||||
const TStructure *structure;
|
||||
};
|
||||
std::vector<StructEqualityFunction*> mStructEqualityFunctions;
|
||||
|
||||
struct ArrayHelperFunction : public HelperFunction
|
||||
{
|
||||
TType type;
|
||||
};
|
||||
std::vector<ArrayHelperFunction*> mArrayEqualityFunctions;
|
||||
|
||||
std::vector<ArrayHelperFunction> mArrayAssignmentFunctions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // COMPILER_OUTPUTHLSL_H_
|
||||
#endif // COMPILER_TRANSLATOR_OUTPUTHLSL_H_
|
||||
|
@ -9,8 +9,9 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "compiler/translator/glslang.h"
|
||||
#include "compiler/preprocessor/SourceLocation.h"
|
||||
#include "compiler/translator/glslang.h"
|
||||
#include "compiler/translator/ValidateSwitch.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -796,9 +797,24 @@ bool TParseContext::arrayErrorCheck(const TSourceLoc& line, const TString& ident
|
||||
bool sameScope = false;
|
||||
TSymbol* symbol = symbolTable.find(identifier, 0, &builtIn, &sameScope);
|
||||
if (symbol == 0 || !sameScope) {
|
||||
if (reservedErrorCheck(line, identifier))
|
||||
return true;
|
||||
|
||||
bool needsReservedErrorCheck = true;
|
||||
|
||||
// gl_LastFragData may be redeclared with a new precision qualifier
|
||||
if (identifier.compare(0, 15, "gl_LastFragData") == 0) {
|
||||
if (type.arraySize == static_cast<const TVariable*>(symbolTable.findBuiltIn("gl_MaxDrawBuffers", shaderVersion))->getConstPointer()->getIConst()) {
|
||||
if (TSymbol* builtInSymbol = symbolTable.findBuiltIn(identifier, shaderVersion)) {
|
||||
needsReservedErrorCheck = extensionErrorCheck(line, builtInSymbol->getExtension());
|
||||
}
|
||||
} else {
|
||||
error(line, "redeclaration of array with size != gl_MaxDrawBuffers", identifier.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsReservedErrorCheck)
|
||||
if (reservedErrorCheck(line, identifier))
|
||||
return true;
|
||||
|
||||
variable = new TVariable(&identifier, TType(type));
|
||||
|
||||
if (type.arraySize)
|
||||
@ -976,6 +992,26 @@ bool TParseContext::layoutLocationErrorCheck(const TSourceLoc& location, const T
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *aggregate)
|
||||
{
|
||||
for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
|
||||
{
|
||||
TQualifier qual = fnCandidate->getParam(i).type->getQualifier();
|
||||
if (qual == EvqOut || qual == EvqInOut)
|
||||
{
|
||||
TIntermTyped *node = (*(aggregate->getSequence()))[i]->getAsTyped();
|
||||
if (lValueErrorCheck(node->getLine(), "assign", node))
|
||||
{
|
||||
error(node->getLine(),
|
||||
"Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
|
||||
recover();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TParseContext::supportsExtension(const char* extension)
|
||||
{
|
||||
const TExtensionBehavior& extbehavior = extensionBehavior();
|
||||
@ -1062,14 +1098,14 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
|
||||
//
|
||||
// Return the function symbol if found, otherwise 0.
|
||||
//
|
||||
const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, int shaderVersion, bool *builtIn)
|
||||
const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, int inputShaderVersion, bool *builtIn)
|
||||
{
|
||||
// First find by unmangled name to check whether the function name has been
|
||||
// hidden by a variable name or struct typename.
|
||||
// If a function is found, check for one with a matching argument list.
|
||||
const TSymbol* symbol = symbolTable.find(call->getName(), shaderVersion, builtIn);
|
||||
const TSymbol* symbol = symbolTable.find(call->getName(), inputShaderVersion, builtIn);
|
||||
if (symbol == 0 || symbol->isFunction()) {
|
||||
symbol = symbolTable.find(call->getMangledName(), shaderVersion, builtIn);
|
||||
symbol = symbolTable.find(call->getMangledName(), inputShaderVersion, builtIn);
|
||||
}
|
||||
|
||||
if (symbol == 0) {
|
||||
@ -1162,7 +1198,7 @@ bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& id
|
||||
|
||||
if (qualifier != EvqConst) {
|
||||
TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
|
||||
intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
|
||||
intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
|
||||
if (intermNode == 0) {
|
||||
assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
|
||||
return true;
|
||||
@ -1375,7 +1411,7 @@ TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &inv
|
||||
recover();
|
||||
return NULL;
|
||||
}
|
||||
symbolTable.addInvariantVarying(*identifier);
|
||||
symbolTable.addInvariantVarying(std::string(identifier->c_str()));
|
||||
const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
|
||||
ASSERT(variable);
|
||||
const TType &type = variable->getType();
|
||||
@ -1605,7 +1641,7 @@ TFunction *TParseContext::addConstructorFunc(TPublicType publicType)
|
||||
//
|
||||
// Returns 0 for an error or the constructed node (aggregate or typed) for no error.
|
||||
//
|
||||
TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, const TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line)
|
||||
TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line)
|
||||
{
|
||||
TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
|
||||
|
||||
@ -1633,13 +1669,21 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, const TType
|
||||
}
|
||||
|
||||
// Turn the argument list itself into a constructor
|
||||
TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
|
||||
TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
|
||||
TIntermAggregate *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
|
||||
TIntermTyped *constConstructor = foldConstConstructor(constructor, *type);
|
||||
if (constConstructor)
|
||||
{
|
||||
return constConstructor;
|
||||
}
|
||||
|
||||
// Structs should not be precision qualified, the individual members may be.
|
||||
// Built-in types on the other hand should be precision qualified.
|
||||
if (op != EOpConstructStruct)
|
||||
{
|
||||
constructor->setPrecisionFromChildren();
|
||||
type->setPrecision(constructor->getPrecision());
|
||||
}
|
||||
|
||||
return constructor;
|
||||
}
|
||||
|
||||
@ -2028,9 +2072,11 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
|
||||
recover();
|
||||
}
|
||||
|
||||
if (indexExpression->getQualifier() == EvqConst)
|
||||
TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
|
||||
|
||||
if (indexExpression->getQualifier() == EvqConst && indexConstantUnion)
|
||||
{
|
||||
int index = indexExpression->getAsConstantUnion()->getIConst(0);
|
||||
int index = indexConstantUnion->getIConst(0);
|
||||
if (index < 0)
|
||||
{
|
||||
std::stringstream infoStream;
|
||||
@ -2091,7 +2137,7 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
|
||||
index = baseExpression->getType().getNominalSize() - 1;
|
||||
}
|
||||
|
||||
indexExpression->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index);
|
||||
indexConstantUnion->getUnionArrayPointer()->setIConst(index);
|
||||
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
|
||||
}
|
||||
}
|
||||
@ -2520,7 +2566,10 @@ TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSou
|
||||
TStructure* structure = new TStructure(structName, fieldList);
|
||||
TType* structureType = new TType(structure);
|
||||
|
||||
// Store a bool in the struct if we're at global scope, to allow us to
|
||||
// skip the local struct scoping workaround in HLSL.
|
||||
structure->setUniqueId(TSymbolTable::nextUniqueId());
|
||||
structure->setAtGlobalScope(symbolTable.atGlobalLevel());
|
||||
|
||||
if (!structName->empty())
|
||||
{
|
||||
@ -2560,6 +2609,553 @@ TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSou
|
||||
return publicType;
|
||||
}
|
||||
|
||||
TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc)
|
||||
{
|
||||
TBasicType switchType = init->getBasicType();
|
||||
if ((switchType != EbtInt && switchType != EbtUInt) ||
|
||||
init->isMatrix() ||
|
||||
init->isArray() ||
|
||||
init->isVector())
|
||||
{
|
||||
error(init->getLine(), "init-expression in a switch statement must be a scalar integer", "switch");
|
||||
recover();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (statementList)
|
||||
{
|
||||
if (!ValidateSwitch::validate(switchType, this, statementList, loc))
|
||||
{
|
||||
recover();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc);
|
||||
if (node == nullptr)
|
||||
{
|
||||
error(loc, "erroneous switch statement", "switch");
|
||||
recover();
|
||||
return nullptr;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
|
||||
{
|
||||
if (mSwitchNestingLevel == 0)
|
||||
{
|
||||
error(loc, "case labels need to be inside switch statements", "case");
|
||||
recover();
|
||||
return nullptr;
|
||||
}
|
||||
if (condition == nullptr)
|
||||
{
|
||||
error(loc, "case label must have a condition", "case");
|
||||
recover();
|
||||
return nullptr;
|
||||
}
|
||||
if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
|
||||
condition->isMatrix() ||
|
||||
condition->isArray() ||
|
||||
condition->isVector())
|
||||
{
|
||||
error(condition->getLine(), "case label must be a scalar integer", "case");
|
||||
recover();
|
||||
}
|
||||
TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
|
||||
if (conditionConst == nullptr)
|
||||
{
|
||||
error(condition->getLine(), "case label must be constant", "case");
|
||||
recover();
|
||||
}
|
||||
TIntermCase *node = intermediate.addCase(condition, loc);
|
||||
if (node == nullptr)
|
||||
{
|
||||
error(loc, "erroneous case statement", "case");
|
||||
recover();
|
||||
return nullptr;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
|
||||
{
|
||||
if (mSwitchNestingLevel == 0)
|
||||
{
|
||||
error(loc, "default labels need to be inside switch statements", "default");
|
||||
recover();
|
||||
return nullptr;
|
||||
}
|
||||
TIntermCase *node = intermediate.addCase(nullptr, loc);
|
||||
if (node == nullptr)
|
||||
{
|
||||
error(loc, "erroneous default statement", "default");
|
||||
recover();
|
||||
return nullptr;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc,
|
||||
const TType *funcReturnType)
|
||||
{
|
||||
if (child == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case EOpLogicalNot:
|
||||
if (child->getBasicType() != EbtBool ||
|
||||
child->isMatrix() ||
|
||||
child->isArray() ||
|
||||
child->isVector())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case EOpBitwiseNot:
|
||||
if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
|
||||
child->isMatrix() ||
|
||||
child->isArray())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case EOpPostIncrement:
|
||||
case EOpPreIncrement:
|
||||
case EOpPostDecrement:
|
||||
case EOpPreDecrement:
|
||||
case EOpNegative:
|
||||
case EOpPositive:
|
||||
if (child->getBasicType() == EbtStruct ||
|
||||
child->getBasicType() == EbtBool ||
|
||||
child->isArray())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
// Operators for built-ins are already type checked against their prototype.
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return intermediate.addUnaryMath(op, child, loc, funcReturnType);
|
||||
}
|
||||
|
||||
TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
|
||||
{
|
||||
TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
|
||||
if (node == nullptr)
|
||||
{
|
||||
unaryOpError(loc, GetOperatorString(op), child->getCompleteString());
|
||||
recover();
|
||||
return child;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
|
||||
{
|
||||
if (lValueErrorCheck(loc, GetOperatorString(op), child))
|
||||
recover();
|
||||
return addUnaryMath(op, child, loc);
|
||||
}
|
||||
|
||||
bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &loc)
|
||||
{
|
||||
if (left->isArray() || right->isArray())
|
||||
{
|
||||
if (shaderVersion < 300)
|
||||
{
|
||||
error(loc, "Invalid operation for arrays", GetOperatorString(op));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (left->isArray() != right->isArray())
|
||||
{
|
||||
error(loc, "array / non-array mismatch", GetOperatorString(op));
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case EOpEqual:
|
||||
case EOpNotEqual:
|
||||
case EOpAssign:
|
||||
case EOpInitialize:
|
||||
break;
|
||||
default:
|
||||
error(loc, "Invalid operation for arrays", GetOperatorString(op));
|
||||
return false;
|
||||
}
|
||||
if (left->getArraySize() != right->getArraySize())
|
||||
{
|
||||
error(loc, "array size mismatch", GetOperatorString(op));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check ops which require integer / ivec parameters
|
||||
bool isBitShift = false;
|
||||
switch (op)
|
||||
{
|
||||
case EOpBitShiftLeft:
|
||||
case EOpBitShiftRight:
|
||||
case EOpBitShiftLeftAssign:
|
||||
case EOpBitShiftRightAssign:
|
||||
// Unsigned can be bit-shifted by signed and vice versa, but we need to
|
||||
// check that the basic type is an integer type.
|
||||
isBitShift = true;
|
||||
if (!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case EOpBitwiseAnd:
|
||||
case EOpBitwiseXor:
|
||||
case EOpBitwiseOr:
|
||||
case EOpBitwiseAndAssign:
|
||||
case EOpBitwiseXorAssign:
|
||||
case EOpBitwiseOrAssign:
|
||||
// It is enough to check the type of only one operand, since later it
|
||||
// is checked that the operand types match.
|
||||
if (!IsInteger(left->getBasicType()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// GLSL ES 1.00 and 3.00 do not support implicit type casting.
|
||||
// So the basic type should usually match.
|
||||
if (!isBitShift && left->getBasicType() != right->getBasicType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that type sizes match exactly on ops that require that.
|
||||
// Also check restrictions for structs that contain arrays or samplers.
|
||||
switch(op)
|
||||
{
|
||||
case EOpAssign:
|
||||
case EOpInitialize:
|
||||
case EOpEqual:
|
||||
case EOpNotEqual:
|
||||
// ESSL 1.00 sections 5.7, 5.8, 5.9
|
||||
if (shaderVersion < 300 && left->getType().isStructureContainingArrays())
|
||||
{
|
||||
error(loc, "undefined operation for structs containing arrays", GetOperatorString(op));
|
||||
return false;
|
||||
}
|
||||
// Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7,
|
||||
// we interpret the spec so that this extends to structs containing samplers,
|
||||
// similarly to ESSL 1.00 spec.
|
||||
if ((shaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
|
||||
left->getType().isStructureContainingSamplers())
|
||||
{
|
||||
error(loc, "undefined operation for structs containing samplers", GetOperatorString(op));
|
||||
return false;
|
||||
}
|
||||
case EOpLessThan:
|
||||
case EOpGreaterThan:
|
||||
case EOpLessThanEqual:
|
||||
case EOpGreaterThanEqual:
|
||||
if ((left->getNominalSize() != right->getNominalSize()) ||
|
||||
(left->getSecondarySize() != right->getSecondarySize()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &loc)
|
||||
{
|
||||
if (!binaryOpCommonCheck(op, left, right, loc))
|
||||
return nullptr;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case EOpEqual:
|
||||
case EOpNotEqual:
|
||||
break;
|
||||
case EOpLessThan:
|
||||
case EOpGreaterThan:
|
||||
case EOpLessThanEqual:
|
||||
case EOpGreaterThanEqual:
|
||||
ASSERT(!left->isArray() && !right->isArray());
|
||||
if (left->isMatrix() || left->isVector() ||
|
||||
left->getBasicType() == EbtStruct)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case EOpLogicalOr:
|
||||
case EOpLogicalXor:
|
||||
case EOpLogicalAnd:
|
||||
ASSERT(!left->isArray() && !right->isArray());
|
||||
if (left->getBasicType() != EbtBool ||
|
||||
left->isMatrix() || left->isVector())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case EOpAdd:
|
||||
case EOpSub:
|
||||
case EOpDiv:
|
||||
case EOpMul:
|
||||
ASSERT(!left->isArray() && !right->isArray());
|
||||
if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case EOpIMod:
|
||||
ASSERT(!left->isArray() && !right->isArray());
|
||||
// Note that this is only for the % operator, not for mod()
|
||||
if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
// Note that for bitwise ops, type checking is done in promote() to
|
||||
// share code between ops and compound assignment
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return intermediate.addBinaryMath(op, left, right, loc);
|
||||
}
|
||||
|
||||
TIntermTyped *TParseContext::addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &loc)
|
||||
{
|
||||
TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
|
||||
if (node == 0)
|
||||
{
|
||||
binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString());
|
||||
recover();
|
||||
return left;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &loc)
|
||||
{
|
||||
TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
|
||||
if (node == 0)
|
||||
{
|
||||
binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString());
|
||||
recover();
|
||||
ConstantUnion *unionArray = new ConstantUnion[1];
|
||||
unionArray->setBConst(false);
|
||||
return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), loc);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
TIntermTyped *TParseContext::createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &loc)
|
||||
{
|
||||
if (binaryOpCommonCheck(op, left, right, loc))
|
||||
{
|
||||
return intermediate.addAssign(op, left, right, loc);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TIntermTyped *TParseContext::addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &loc)
|
||||
{
|
||||
TIntermTyped *node = createAssign(op, left, right, loc);
|
||||
if (node == nullptr)
|
||||
{
|
||||
assignError(loc, "assign", left->getCompleteString(), right->getCompleteString());
|
||||
recover();
|
||||
return left;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case EOpContinue:
|
||||
if (mLoopNestingLevel <= 0)
|
||||
{
|
||||
error(loc, "continue statement only allowed in loops", "");
|
||||
recover();
|
||||
}
|
||||
break;
|
||||
case EOpBreak:
|
||||
if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
|
||||
{
|
||||
error(loc, "break statement only allowed in loops and switch statements", "");
|
||||
recover();
|
||||
}
|
||||
break;
|
||||
case EOpReturn:
|
||||
if (currentFunctionType->getBasicType() != EbtVoid)
|
||||
{
|
||||
error(loc, "non-void function must return a value", "return");
|
||||
recover();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// No checks for discard
|
||||
break;
|
||||
}
|
||||
return intermediate.addBranch(op, loc);
|
||||
}
|
||||
|
||||
TIntermBranch *TParseContext::addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc)
|
||||
{
|
||||
ASSERT(op == EOpReturn);
|
||||
mFunctionReturnsValue = true;
|
||||
if (currentFunctionType->getBasicType() == EbtVoid)
|
||||
{
|
||||
error(loc, "void function cannot return a value", "return");
|
||||
recover();
|
||||
}
|
||||
else if (*currentFunctionType != returnValue->getType())
|
||||
{
|
||||
error(loc, "function return is not matching type:", "return");
|
||||
recover();
|
||||
}
|
||||
return intermediate.addBranch(op, returnValue, loc);
|
||||
}
|
||||
|
||||
TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *node,
|
||||
const TSourceLoc &loc, bool *fatalError)
|
||||
{
|
||||
*fatalError = false;
|
||||
TOperator op = fnCall->getBuiltInOp();
|
||||
TIntermTyped *callNode = nullptr;
|
||||
|
||||
if (op != EOpNull)
|
||||
{
|
||||
//
|
||||
// Then this should be a constructor.
|
||||
// Don't go through the symbol table for constructors.
|
||||
// Their parameters will be verified algorithmically.
|
||||
//
|
||||
TType type(EbtVoid, EbpUndefined); // use this to get the type back
|
||||
if (!constructorErrorCheck(loc, node, *fnCall, op, &type))
|
||||
{
|
||||
//
|
||||
// It's a constructor, of type 'type'.
|
||||
//
|
||||
callNode = addConstructor(node, &type, op, fnCall, loc);
|
||||
}
|
||||
|
||||
if (callNode == nullptr)
|
||||
{
|
||||
recover();
|
||||
callNode = intermediate.setAggregateOperator(nullptr, op, loc);
|
||||
}
|
||||
callNode->setType(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Not a constructor. Find it in the symbol table.
|
||||
//
|
||||
const TFunction* fnCandidate;
|
||||
bool builtIn;
|
||||
fnCandidate = findFunction(loc, fnCall, shaderVersion, &builtIn);
|
||||
if (fnCandidate)
|
||||
{
|
||||
//
|
||||
// A declared function.
|
||||
//
|
||||
if (builtIn && !fnCandidate->getExtension().empty() &&
|
||||
extensionErrorCheck(loc, fnCandidate->getExtension()))
|
||||
{
|
||||
recover();
|
||||
}
|
||||
op = fnCandidate->getBuiltInOp();
|
||||
if (builtIn && op != EOpNull)
|
||||
{
|
||||
//
|
||||
// A function call mapped to a built-in operation.
|
||||
//
|
||||
if (fnCandidate->getParamCount() == 1)
|
||||
{
|
||||
//
|
||||
// Treat it like a built-in unary operator.
|
||||
//
|
||||
callNode = createUnaryMath(op, node->getAsTyped(), loc, &fnCandidate->getReturnType());
|
||||
if (callNode == nullptr)
|
||||
{
|
||||
std::stringstream extraInfoStream;
|
||||
extraInfoStream << "built in unary operator function. Type: "
|
||||
<< static_cast<TIntermTyped*>(node)->getCompleteString();
|
||||
std::string extraInfo = extraInfoStream.str();
|
||||
error(node->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
|
||||
*fatalError = true;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TIntermAggregate *aggregate = intermediate.setAggregateOperator(node, op, loc);
|
||||
aggregate->setType(fnCandidate->getReturnType());
|
||||
aggregate->setPrecisionFromChildren();
|
||||
callNode = aggregate;
|
||||
|
||||
// Some built-in functions have out parameters too.
|
||||
functionCallLValueErrorCheck(fnCandidate, aggregate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a real function call
|
||||
|
||||
TIntermAggregate *aggregate = intermediate.setAggregateOperator(node, EOpFunctionCall, loc);
|
||||
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)
|
||||
aggregate->setUserDefined();
|
||||
aggregate->setName(fnCandidate->getMangledName());
|
||||
|
||||
// This needs to happen after the name is set
|
||||
if (builtIn)
|
||||
aggregate->setBuiltInFunctionPrecision();
|
||||
|
||||
callNode = aggregate;
|
||||
|
||||
functionCallLValueErrorCheck(fnCandidate, aggregate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// error message was put out by findFunction()
|
||||
// Put on a dummy node for error recovery
|
||||
ConstantUnion *unionArray = new ConstantUnion[1];
|
||||
unionArray->setFConst(0.0f);
|
||||
callNode = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), loc);
|
||||
recover();
|
||||
}
|
||||
}
|
||||
delete fnCall;
|
||||
return callNode;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Parse an array of strings using yyparse.
|
||||
//
|
||||
|
@ -3,8 +3,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
#ifndef _PARSER_HELPER_INCLUDED_
|
||||
#define _PARSER_HELPER_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_PARSECONTEXT_H_
|
||||
#define COMPILER_TRANSLATOR_PARSECONTEXT_H_
|
||||
|
||||
#include "compiler/translator/Compiler.h"
|
||||
#include "compiler/translator/Diagnostics.h"
|
||||
@ -25,24 +25,25 @@ struct TMatrixFields {
|
||||
// they can be passed to the parser without needing a global.
|
||||
//
|
||||
struct TParseContext {
|
||||
TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, sh::GLenum type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
|
||||
TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, sh::GLenum type, ShShaderSpec spec, int options, bool checksPrecErrors, TInfoSink& is, bool debugShaderPrecisionSupported) :
|
||||
intermediate(interm),
|
||||
symbolTable(symt),
|
||||
shaderType(type),
|
||||
shaderSpec(spec),
|
||||
compileOptions(options),
|
||||
sourcePath(sourcePath),
|
||||
treeRoot(0),
|
||||
loopNestingLevel(0),
|
||||
mLoopNestingLevel(0),
|
||||
structNestingLevel(0),
|
||||
mSwitchNestingLevel(0),
|
||||
currentFunctionType(NULL),
|
||||
functionReturnsValue(false),
|
||||
mFunctionReturnsValue(false),
|
||||
checksPrecisionErrors(checksPrecErrors),
|
||||
fragmentPrecisionHigh(false),
|
||||
defaultMatrixPacking(EmpColumnMajor),
|
||||
defaultBlockStorage(EbsShared),
|
||||
diagnostics(is),
|
||||
shaderVersion(100),
|
||||
directiveHandler(ext, diagnostics, shaderVersion),
|
||||
directiveHandler(ext, diagnostics, shaderVersion, debugShaderPrecisionSupported),
|
||||
preprocessor(&diagnostics, &directiveHandler),
|
||||
scanner(NULL) { }
|
||||
TIntermediate& intermediate; // to hold and build a parse tree
|
||||
@ -51,12 +52,12 @@ struct TParseContext {
|
||||
ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
|
||||
int shaderVersion;
|
||||
int compileOptions;
|
||||
const char* sourcePath; // Path of source file or NULL.
|
||||
TIntermNode* treeRoot; // root of parse tree being created
|
||||
int loopNestingLevel; // 0 if outside all loops
|
||||
int mLoopNestingLevel; // 0 if outside all loops
|
||||
int structNestingLevel; // incremented while parsing a struct declaration
|
||||
int mSwitchNestingLevel; // 0 if outside all switch statements
|
||||
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
||||
bool functionReturnsValue; // true if a non-void function has a return
|
||||
bool mFunctionReturnsValue; // true if a non-void function has a return
|
||||
bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
|
||||
bool fragmentPrecisionHigh; // true if highp precision is supported in the fragment language.
|
||||
TLayoutMatrixPacking defaultMatrixPacking;
|
||||
@ -110,6 +111,7 @@ struct TParseContext {
|
||||
bool extensionErrorCheck(const TSourceLoc& line, const TString&);
|
||||
bool singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier);
|
||||
bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
|
||||
bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
|
||||
|
||||
const TPragma& pragma() const { return directiveHandler.pragma(); }
|
||||
const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
|
||||
@ -120,7 +122,7 @@ struct TParseContext {
|
||||
|
||||
bool containsSampler(TType& type);
|
||||
bool areAllChildConst(TIntermAggregate* aggrNode);
|
||||
const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, int shaderVersion, bool *builtIn = 0);
|
||||
const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, int inputShaderVersion, bool *builtIn = 0);
|
||||
bool executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType,
|
||||
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
|
||||
|
||||
@ -136,7 +138,7 @@ struct TParseContext {
|
||||
TIntermAggregate* parseInitDeclarator(TPublicType &publicType, TIntermAggregate *declaratorList, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer);
|
||||
void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
|
||||
TFunction *addConstructorFunc(TPublicType publicType);
|
||||
TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
|
||||
TIntermTyped* addConstructor(TIntermNode*, TType*, TOperator, TFunction*, const TSourceLoc&);
|
||||
TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
|
||||
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
|
||||
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, const TSourceLoc&);
|
||||
@ -164,9 +166,42 @@ struct TParseContext {
|
||||
void exitStructDeclaration();
|
||||
|
||||
bool structNestingErrorCheck(const TSourceLoc& line, const TField& field);
|
||||
|
||||
TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc);
|
||||
TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
|
||||
TIntermCase *addDefault(const TSourceLoc &loc);
|
||||
|
||||
TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &);
|
||||
TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &);
|
||||
TIntermTyped *addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &);
|
||||
TIntermTyped *addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &);
|
||||
TIntermTyped *addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &loc);
|
||||
|
||||
TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
|
||||
TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc);
|
||||
|
||||
TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *node,
|
||||
const TSourceLoc &loc, bool *fatalError);
|
||||
|
||||
private:
|
||||
TIntermTyped *addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &loc);
|
||||
TIntermTyped *createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &loc);
|
||||
// The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
|
||||
// It is expected to be null for other unary operators.
|
||||
TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc,
|
||||
const TType *funcReturnType);
|
||||
|
||||
// Return true if the checks pass
|
||||
bool binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right,
|
||||
const TSourceLoc &loc);
|
||||
};
|
||||
|
||||
int PaParseStrings(size_t count, const char* const string[], const int length[],
|
||||
TParseContext* context);
|
||||
|
||||
#endif // _PARSER_HELPER_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _POOLALLOC_INCLUDED_
|
||||
#define _POOLALLOC_INCLUDED_
|
||||
#ifndef COMPILER_TRANSLATOR_POOLALLOC_H_
|
||||
#define COMPILER_TRANSLATOR_POOLALLOC_H_
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define GUARD_BLOCKS // define to enable guard block sanity checking
|
||||
@ -297,4 +297,4 @@ protected:
|
||||
TPoolAllocator* allocator;
|
||||
};
|
||||
|
||||
#endif // _POOLALLOC_INCLUDED_
|
||||
#endif // COMPILER_TRANSLATOR_POOLALLOC_H_
|
||||
|
@ -4,8 +4,8 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_PRAGMA_H_
|
||||
#define COMPILER_PRAGMA_H_
|
||||
#ifndef COMPILER_TRANSLATOR_PRAGMA_H_
|
||||
#define COMPILER_TRANSLATOR_PRAGMA_H_
|
||||
|
||||
struct TPragma
|
||||
{
|
||||
@ -18,12 +18,15 @@ struct TPragma
|
||||
|
||||
|
||||
// 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) { }
|
||||
// Precision emulation is turned on by default, but has no effect unless
|
||||
// the extension is enabled.
|
||||
TPragma() : optimize(true), debug(false), debugShaderPrecision(true) { }
|
||||
TPragma(bool o, bool d) : optimize(o), debug(d), debugShaderPrecision(true) { }
|
||||
|
||||
bool optimize;
|
||||
bool debug;
|
||||
bool debugShaderPrecision;
|
||||
STDGL stdgl;
|
||||
};
|
||||
|
||||
#endif // COMPILER_PRAGMA_H_
|
||||
#endif // COMPILER_TRANSLATOR_PRAGMA_H_
|
||||
|
@ -49,7 +49,7 @@ void TAliveTraverser::visitSymbol(TIntermSymbol* node)
|
||||
found = true;
|
||||
}
|
||||
|
||||
bool TAliveTraverser::visitSelection(Visit preVisit, TIntermSelection* node)
|
||||
bool TAliveTraverser::visitSelection(Visit, TIntermSelection*)
|
||||
{
|
||||
if (wasFound())
|
||||
return false;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user