Add ANGLE as a 3rdparty library to Qt.
ANGLE is a component that implements the OpenGL ES 2.0 API on top of DirectX 9. See the following for more info: http://code.google.com/p/angleproject/ ANGLE is now the default configuration on Windows. If you want to use desktop OpenGL, you should build Qt with the following configure options: -opengl desktop To configure Qt to use another OpenGL ES 2 implementation, you should use: -opengl es2 -no-angle Task-number: QTBUG-24207 Change-Id: Iefcbeaa37ed920f431729749ab8333b248fe5134 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
parent
84d09214bc
commit
e0c0e83fd5
35
src/3rdparty/angle/.gitignore
vendored
Normal file
35
src/3rdparty/angle/.gitignore
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
# This file is used to ignore files which are generated when building ANGLE
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# Directories from ANGLE we don't want/need
|
||||
build
|
||||
extensions
|
||||
samples
|
||||
tests
|
||||
third_party
|
||||
src/ipch
|
||||
.svn
|
||||
|
||||
# Files from ANGLE we don't want/need
|
||||
DEPS
|
||||
*.gyp
|
||||
*.gypi
|
||||
*.sh
|
||||
*.bat
|
||||
codereview.settings
|
||||
|
||||
# Generated by flex/bison
|
||||
src/compiler/preprocessor/new/Tokenizer.cpp
|
||||
src/compiler/preprocessor/new/ExpressionParser.cpp
|
||||
src/compiler/glslang_lex.cpp
|
||||
src/compiler/glslang_tab.cpp
|
||||
src/compiler/glslang_tab.h
|
||||
|
||||
# Generated by FXC
|
||||
src/libGLESv2/shaders/standardvs.h
|
||||
src/libGLESv2/shaders/flipyvs.h
|
||||
src/libGLESv2/shaders/luminanceps.h
|
||||
src/libGLESv2/shaders/componentmaskps.h
|
||||
src/libGLESv2/shaders/passthroughps.h
|
||||
|
||||
|
30
src/3rdparty/angle/AUTHORS
vendored
Normal file
30
src/3rdparty/angle/AUTHORS
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
# This is the official list of The ANGLE Project Authors
|
||||
# for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS files.
|
||||
# See the latter for an explanation.
|
||||
|
||||
# Names should be added to this file as
|
||||
# Name or Organization
|
||||
# Email addresses for individuals are tracked elsewhere to avoid spam.
|
||||
|
||||
Google Inc.
|
||||
TransGaming Inc.
|
||||
3DLabs Inc. Ltd.
|
||||
|
||||
Adobe Systems Inc.
|
||||
Autodesk, Inc.
|
||||
Cloud Party, Inc.
|
||||
Intel Corporation
|
||||
Mozilla Corporation
|
||||
Turbulenz
|
||||
|
||||
Jacek Caban
|
||||
Mark Callow
|
||||
Ginn Chen
|
||||
James Hauxwell
|
||||
Sam Hocevar
|
||||
Pierre Leveille
|
||||
Boying Lu
|
||||
Aitor Moreno
|
||||
Yuri O'Donnell
|
||||
Josh Soref
|
70
src/3rdparty/angle/CONTRIBUTORS
vendored
Normal file
70
src/3rdparty/angle/CONTRIBUTORS
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
# 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
|
||||
# lists people. For example, Google employees are listed here
|
||||
# but not in AUTHORS, because Google holds the copyright.
|
||||
#
|
||||
|
||||
TransGaming Inc.
|
||||
Nicolas Capens
|
||||
Daniel Koch
|
||||
Andrew Lewycky
|
||||
Gavriel State
|
||||
Shannon Woods
|
||||
|
||||
Google Inc.
|
||||
Brent Austin
|
||||
Michael Bai
|
||||
John Bauman
|
||||
Peter Beverloo
|
||||
Steve Block
|
||||
Rachel Blum
|
||||
Eric Boren
|
||||
Henry Bridge
|
||||
Nat Duca
|
||||
Peter Kasting
|
||||
Vangelis Kokkevis
|
||||
Zhenyao Mo
|
||||
Daniel Nicoara
|
||||
Alastair Patrick
|
||||
Alok Priyadarshi
|
||||
Kenneth Russell
|
||||
Brian Salomon
|
||||
Gregg Tavares
|
||||
Jeff Timanus
|
||||
Ben Vanik
|
||||
Adrienne Walker
|
||||
thestig@chromium.org
|
||||
|
||||
Adobe Systems Inc.
|
||||
Alexandru Chiculita
|
||||
Steve Minns
|
||||
Max Vujovic
|
||||
|
||||
Autodesk, Inc.
|
||||
Ranger Harke
|
||||
|
||||
Cloud Party, Inc.
|
||||
Conor Dickinson
|
||||
|
||||
Intel Corporation
|
||||
Jin Yang
|
||||
Andy Chen
|
||||
Josh Triplett
|
||||
|
||||
Mozilla Corp.
|
||||
Ehsan Akhgari
|
||||
Jeff Gilbert
|
||||
Mike Hommey
|
||||
Benoit Jacob
|
||||
Makoto Kato
|
||||
Vladimir Vukicevic
|
||||
|
||||
Turbulenz
|
||||
Michael Braithwaite
|
||||
|
||||
Ulrik Persson (ddefrostt)
|
||||
Mark Banner (standard8mbp)
|
||||
David Kilzer
|
||||
|
32
src/3rdparty/angle/LICENSE
vendored
Normal file
32
src/3rdparty/angle/LICENSE
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (C) 2002-2010 The ANGLE Project Authors.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of TransGaming Inc., Google Inc., 3DLabs Inc.
|
||||
// Ltd., nor the names of their contributors may be used to endorse
|
||||
// or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
45
src/3rdparty/angle/LICENSE.preprocessor
vendored
Normal file
45
src/3rdparty/angle/LICENSE.preprocessor
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
Files in src/compiler/preprocessor are provided under the following license:
|
||||
|
||||
****************************************************************************
|
||||
Copyright (c) 2002, NVIDIA Corporation.
|
||||
|
||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
||||
consideration of your agreement to the following terms, and your use,
|
||||
installation, modification or redistribution of this NVIDIA software
|
||||
constitutes acceptance of these terms. If you do not agree with these
|
||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
||||
software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
||||
NVIDIA Software, with or without modifications, in source and/or binary
|
||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
||||
retain the copyright notice of NVIDIA, this notice and the following
|
||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
||||
Corporation may be used to endorse or promote products derived from the
|
||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
||||
Except as expressly stated in this notice, no other rights or licenses
|
||||
express or implied, are granted by NVIDIA herein, including but not
|
||||
limited to any patent rights that may be infringed by your derivative
|
||||
works or by other works in which the NVIDIA Software may be
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
|
||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
||||
PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
****************************************************************************
|
329
src/3rdparty/angle/include/EGL/egl.h
vendored
Normal file
329
src/3rdparty/angle/include/EGL/egl.h
vendored
Normal file
@ -0,0 +1,329 @@
|
||||
/* -*- mode: c; tab-width: 8; -*- */
|
||||
/* vi: set sw=4 ts=8: */
|
||||
/* Reference version of egl.h for EGL 1.4.
|
||||
* $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
|
||||
*/
|
||||
|
||||
/*
|
||||
** Copyright (c) 2007-2009 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
#ifndef __egl_h_
|
||||
#define __egl_h_
|
||||
|
||||
/* All platform-dependent types and macro boilerplate (such as EGLAPI
|
||||
* and EGLAPIENTRY) should go in eglplatform.h.
|
||||
*/
|
||||
#include <EGL/eglplatform.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* EGL Types */
|
||||
/* EGLint is defined in eglplatform.h */
|
||||
typedef unsigned int EGLBoolean;
|
||||
typedef unsigned int EGLenum;
|
||||
typedef void *EGLConfig;
|
||||
typedef void *EGLContext;
|
||||
typedef void *EGLDisplay;
|
||||
typedef void *EGLSurface;
|
||||
typedef void *EGLClientBuffer;
|
||||
|
||||
/* EGL Versioning */
|
||||
#define EGL_VERSION_1_0 1
|
||||
#define EGL_VERSION_1_1 1
|
||||
#define EGL_VERSION_1_2 1
|
||||
#define EGL_VERSION_1_3 1
|
||||
#define EGL_VERSION_1_4 1
|
||||
|
||||
/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
|
||||
* enums are assigned unique values starting at 0x3000.
|
||||
*/
|
||||
|
||||
/* EGL aliases */
|
||||
#define EGL_FALSE 0
|
||||
#define EGL_TRUE 1
|
||||
|
||||
/* Out-of-band handle values */
|
||||
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
|
||||
#define EGL_NO_CONTEXT ((EGLContext)0)
|
||||
#define EGL_NO_DISPLAY ((EGLDisplay)0)
|
||||
#define EGL_NO_SURFACE ((EGLSurface)0)
|
||||
|
||||
/* Out-of-band attribute value */
|
||||
#define EGL_DONT_CARE ((EGLint)-1)
|
||||
|
||||
/* Errors / GetError return values */
|
||||
#define EGL_SUCCESS 0x3000
|
||||
#define EGL_NOT_INITIALIZED 0x3001
|
||||
#define EGL_BAD_ACCESS 0x3002
|
||||
#define EGL_BAD_ALLOC 0x3003
|
||||
#define EGL_BAD_ATTRIBUTE 0x3004
|
||||
#define EGL_BAD_CONFIG 0x3005
|
||||
#define EGL_BAD_CONTEXT 0x3006
|
||||
#define EGL_BAD_CURRENT_SURFACE 0x3007
|
||||
#define EGL_BAD_DISPLAY 0x3008
|
||||
#define EGL_BAD_MATCH 0x3009
|
||||
#define EGL_BAD_NATIVE_PIXMAP 0x300A
|
||||
#define EGL_BAD_NATIVE_WINDOW 0x300B
|
||||
#define EGL_BAD_PARAMETER 0x300C
|
||||
#define EGL_BAD_SURFACE 0x300D
|
||||
#define EGL_CONTEXT_LOST 0x300E /* EGL 1.1 - IMG_power_management */
|
||||
|
||||
/* Reserved 0x300F-0x301F for additional errors */
|
||||
|
||||
/* Config attributes */
|
||||
#define EGL_BUFFER_SIZE 0x3020
|
||||
#define EGL_ALPHA_SIZE 0x3021
|
||||
#define EGL_BLUE_SIZE 0x3022
|
||||
#define EGL_GREEN_SIZE 0x3023
|
||||
#define EGL_RED_SIZE 0x3024
|
||||
#define EGL_DEPTH_SIZE 0x3025
|
||||
#define EGL_STENCIL_SIZE 0x3026
|
||||
#define EGL_CONFIG_CAVEAT 0x3027
|
||||
#define EGL_CONFIG_ID 0x3028
|
||||
#define EGL_LEVEL 0x3029
|
||||
#define EGL_MAX_PBUFFER_HEIGHT 0x302A
|
||||
#define EGL_MAX_PBUFFER_PIXELS 0x302B
|
||||
#define EGL_MAX_PBUFFER_WIDTH 0x302C
|
||||
#define EGL_NATIVE_RENDERABLE 0x302D
|
||||
#define EGL_NATIVE_VISUAL_ID 0x302E
|
||||
#define EGL_NATIVE_VISUAL_TYPE 0x302F
|
||||
#define EGL_SAMPLES 0x3031
|
||||
#define EGL_SAMPLE_BUFFERS 0x3032
|
||||
#define EGL_SURFACE_TYPE 0x3033
|
||||
#define EGL_TRANSPARENT_TYPE 0x3034
|
||||
#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
|
||||
#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
|
||||
#define EGL_TRANSPARENT_RED_VALUE 0x3037
|
||||
#define EGL_NONE 0x3038 /* Attrib list terminator */
|
||||
#define EGL_BIND_TO_TEXTURE_RGB 0x3039
|
||||
#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
|
||||
#define EGL_MIN_SWAP_INTERVAL 0x303B
|
||||
#define EGL_MAX_SWAP_INTERVAL 0x303C
|
||||
#define EGL_LUMINANCE_SIZE 0x303D
|
||||
#define EGL_ALPHA_MASK_SIZE 0x303E
|
||||
#define EGL_COLOR_BUFFER_TYPE 0x303F
|
||||
#define EGL_RENDERABLE_TYPE 0x3040
|
||||
#define EGL_MATCH_NATIVE_PIXMAP 0x3041 /* Pseudo-attribute (not queryable) */
|
||||
#define EGL_CONFORMANT 0x3042
|
||||
|
||||
/* Reserved 0x3041-0x304F for additional config attributes */
|
||||
|
||||
/* Config attribute values */
|
||||
#define EGL_SLOW_CONFIG 0x3050 /* EGL_CONFIG_CAVEAT value */
|
||||
#define EGL_NON_CONFORMANT_CONFIG 0x3051 /* EGL_CONFIG_CAVEAT value */
|
||||
#define EGL_TRANSPARENT_RGB 0x3052 /* EGL_TRANSPARENT_TYPE value */
|
||||
#define EGL_RGB_BUFFER 0x308E /* EGL_COLOR_BUFFER_TYPE value */
|
||||
#define EGL_LUMINANCE_BUFFER 0x308F /* EGL_COLOR_BUFFER_TYPE value */
|
||||
|
||||
/* More config attribute values, for EGL_TEXTURE_FORMAT */
|
||||
#define EGL_NO_TEXTURE 0x305C
|
||||
#define EGL_TEXTURE_RGB 0x305D
|
||||
#define EGL_TEXTURE_RGBA 0x305E
|
||||
#define EGL_TEXTURE_2D 0x305F
|
||||
|
||||
/* Config attribute mask bits */
|
||||
#define EGL_PBUFFER_BIT 0x0001 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_PIXMAP_BIT 0x0002 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_WINDOW_BIT 0x0004 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 /* EGL_SURFACE_TYPE mask bits */
|
||||
|
||||
#define EGL_OPENGL_ES_BIT 0x0001 /* EGL_RENDERABLE_TYPE mask bits */
|
||||
#define EGL_OPENVG_BIT 0x0002 /* EGL_RENDERABLE_TYPE mask bits */
|
||||
#define EGL_OPENGL_ES2_BIT 0x0004 /* EGL_RENDERABLE_TYPE mask bits */
|
||||
#define EGL_OPENGL_BIT 0x0008 /* EGL_RENDERABLE_TYPE mask bits */
|
||||
|
||||
/* QueryString targets */
|
||||
#define EGL_VENDOR 0x3053
|
||||
#define EGL_VERSION 0x3054
|
||||
#define EGL_EXTENSIONS 0x3055
|
||||
#define EGL_CLIENT_APIS 0x308D
|
||||
|
||||
/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
|
||||
#define EGL_HEIGHT 0x3056
|
||||
#define EGL_WIDTH 0x3057
|
||||
#define EGL_LARGEST_PBUFFER 0x3058
|
||||
#define EGL_TEXTURE_FORMAT 0x3080
|
||||
#define EGL_TEXTURE_TARGET 0x3081
|
||||
#define EGL_MIPMAP_TEXTURE 0x3082
|
||||
#define EGL_MIPMAP_LEVEL 0x3083
|
||||
#define EGL_RENDER_BUFFER 0x3086
|
||||
#define EGL_VG_COLORSPACE 0x3087
|
||||
#define EGL_VG_ALPHA_FORMAT 0x3088
|
||||
#define EGL_HORIZONTAL_RESOLUTION 0x3090
|
||||
#define EGL_VERTICAL_RESOLUTION 0x3091
|
||||
#define EGL_PIXEL_ASPECT_RATIO 0x3092
|
||||
#define EGL_SWAP_BEHAVIOR 0x3093
|
||||
#define EGL_MULTISAMPLE_RESOLVE 0x3099
|
||||
|
||||
/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
|
||||
#define EGL_BACK_BUFFER 0x3084
|
||||
#define EGL_SINGLE_BUFFER 0x3085
|
||||
|
||||
/* OpenVG color spaces */
|
||||
#define EGL_VG_COLORSPACE_sRGB 0x3089 /* EGL_VG_COLORSPACE value */
|
||||
#define EGL_VG_COLORSPACE_LINEAR 0x308A /* EGL_VG_COLORSPACE value */
|
||||
|
||||
/* OpenVG alpha formats */
|
||||
#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B /* EGL_ALPHA_FORMAT value */
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE 0x308C /* EGL_ALPHA_FORMAT value */
|
||||
|
||||
/* Constant scale factor by which fractional display resolutions &
|
||||
* aspect ratio are scaled when queried as integer values.
|
||||
*/
|
||||
#define EGL_DISPLAY_SCALING 10000
|
||||
|
||||
/* Unknown display resolution/aspect ratio */
|
||||
#define EGL_UNKNOWN ((EGLint)-1)
|
||||
|
||||
/* Back buffer swap behaviors */
|
||||
#define EGL_BUFFER_PRESERVED 0x3094 /* EGL_SWAP_BEHAVIOR value */
|
||||
#define EGL_BUFFER_DESTROYED 0x3095 /* EGL_SWAP_BEHAVIOR value */
|
||||
|
||||
/* CreatePbufferFromClientBuffer buffer types */
|
||||
#define EGL_OPENVG_IMAGE 0x3096
|
||||
|
||||
/* QueryContext targets */
|
||||
#define EGL_CONTEXT_CLIENT_TYPE 0x3097
|
||||
|
||||
/* CreateContext attributes */
|
||||
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
|
||||
|
||||
/* Multisample resolution behaviors */
|
||||
#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A /* EGL_MULTISAMPLE_RESOLVE value */
|
||||
#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B /* EGL_MULTISAMPLE_RESOLVE value */
|
||||
|
||||
/* BindAPI/QueryAPI targets */
|
||||
#define EGL_OPENGL_ES_API 0x30A0
|
||||
#define EGL_OPENVG_API 0x30A1
|
||||
#define EGL_OPENGL_API 0x30A2
|
||||
|
||||
/* GetCurrentSurface targets */
|
||||
#define EGL_DRAW 0x3059
|
||||
#define EGL_READ 0x305A
|
||||
|
||||
/* WaitNative engines */
|
||||
#define EGL_CORE_NATIVE_ENGINE 0x305B
|
||||
|
||||
/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
|
||||
#define EGL_COLORSPACE EGL_VG_COLORSPACE
|
||||
#define EGL_ALPHA_FORMAT EGL_VG_ALPHA_FORMAT
|
||||
#define EGL_COLORSPACE_sRGB EGL_VG_COLORSPACE_sRGB
|
||||
#define EGL_COLORSPACE_LINEAR EGL_VG_COLORSPACE_LINEAR
|
||||
#define EGL_ALPHA_FORMAT_NONPRE EGL_VG_ALPHA_FORMAT_NONPRE
|
||||
#define EGL_ALPHA_FORMAT_PRE EGL_VG_ALPHA_FORMAT_PRE
|
||||
|
||||
/* EGL extensions must request enum blocks from the Khronos
|
||||
* API Registrar, who maintains the enumerant registry. Submit
|
||||
* a bug in Khronos Bugzilla against task "Registry".
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* EGL Functions */
|
||||
|
||||
EGLAPI EGLint EGLAPIENTRY eglGetError(void);
|
||||
|
||||
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
|
||||
|
||||
EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
|
||||
EGLint config_size, EGLint *num_config);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
|
||||
EGLConfig *configs, EGLint config_size,
|
||||
EGLint *num_config);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
|
||||
EGLint attribute, EGLint *value);
|
||||
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
|
||||
EGLNativeWindowType win,
|
||||
const EGLint *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
|
||||
const EGLint *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
|
||||
EGLNativePixmapType pixmap,
|
||||
const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
|
||||
EGLint attribute, EGLint *value);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api);
|
||||
EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void);
|
||||
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
|
||||
EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
|
||||
EGLConfig config, const EGLint *attrib_list);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
|
||||
EGLint attribute, EGLint value);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
|
||||
|
||||
|
||||
EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
|
||||
EGLContext share_context,
|
||||
const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
|
||||
EGLSurface read, EGLContext ctx);
|
||||
|
||||
EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw);
|
||||
EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
|
||||
EGLint attribute, EGLint *value);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
|
||||
EGLNativePixmapType target);
|
||||
|
||||
/* This is a generic function pointer type, whose name indicates it must
|
||||
* be cast to the proper type *and calling convention* before use.
|
||||
*/
|
||||
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
|
||||
|
||||
/* Now, define eglGetProcAddress using the generic function ptr. type */
|
||||
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
|
||||
eglGetProcAddress(const char *procname);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __egl_h_ */
|
348
src/3rdparty/angle/include/EGL/eglext.h
vendored
Normal file
348
src/3rdparty/angle/include/EGL/eglext.h
vendored
Normal file
@ -0,0 +1,348 @@
|
||||
#ifndef __eglext_h_
|
||||
#define __eglext_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2007-2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
#include <EGL/eglplatform.h>
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
/* Header file version number */
|
||||
/* Current version at http://www.khronos.org/registry/egl/ */
|
||||
/* $Revision: 16473 $ on $Date: 2012-01-04 02:20:48 -0800 (Wed, 04 Jan 2012) $ */
|
||||
#define EGL_EGLEXT_VERSION 11
|
||||
|
||||
#ifndef EGL_KHR_config_attribs
|
||||
#define EGL_KHR_config_attribs 1
|
||||
#define EGL_CONFORMANT_KHR 0x3042 /* EGLConfig attribute */
|
||||
#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 /* EGL_SURFACE_TYPE bitfield */
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 /* EGL_SURFACE_TYPE bitfield */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_lock_surface
|
||||
#define EGL_KHR_lock_surface 1
|
||||
#define EGL_READ_SURFACE_BIT_KHR 0x0001 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
|
||||
#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
|
||||
#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 /* EGL_SURFACE_TYPE bitfield */
|
||||
#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 /* EGL_SURFACE_TYPE bitfield */
|
||||
#define EGL_MATCH_FORMAT_KHR 0x3043 /* EGLConfig attribute */
|
||||
#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 /* EGL_MATCH_FORMAT_KHR value */
|
||||
#define EGL_FORMAT_RGB_565_KHR 0x30C1 /* EGL_MATCH_FORMAT_KHR value */
|
||||
#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 /* EGL_MATCH_FORMAT_KHR value */
|
||||
#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 /* EGL_MATCH_FORMAT_KHR value */
|
||||
#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 /* eglLockSurfaceKHR attribute */
|
||||
#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 /* eglLockSurfaceKHR attribute */
|
||||
#define EGL_BITMAP_POINTER_KHR 0x30C6 /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PITCH_KHR 0x30C7 /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_ORIGIN_KHR 0x30C8 /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD /* eglQuerySurface attribute */
|
||||
#define EGL_LOWER_LEFT_KHR 0x30CE /* EGL_BITMAP_ORIGIN_KHR value */
|
||||
#define EGL_UPPER_LEFT_KHR 0x30CF /* EGL_BITMAP_ORIGIN_KHR value */
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_image
|
||||
#define EGL_KHR_image 1
|
||||
#define EGL_NATIVE_PIXMAP_KHR 0x30B0 /* eglCreateImageKHR target */
|
||||
typedef void *EGLImageKHR;
|
||||
#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_vg_parent_image
|
||||
#define EGL_KHR_vg_parent_image 1
|
||||
#define EGL_VG_PARENT_IMAGE_KHR 0x30BA /* eglCreateImageKHR target */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_gl_texture_2D_image
|
||||
#define EGL_KHR_gl_texture_2D_image 1
|
||||
#define EGL_GL_TEXTURE_2D_KHR 0x30B1 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC /* eglCreateImageKHR attribute */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_gl_texture_cubemap_image
|
||||
#define EGL_KHR_gl_texture_cubemap_image 1
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 /* eglCreateImageKHR target */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_gl_texture_3D_image
|
||||
#define EGL_KHR_gl_texture_3D_image 1
|
||||
#define EGL_GL_TEXTURE_3D_KHR 0x30B2 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD /* eglCreateImageKHR attribute */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_gl_renderbuffer_image
|
||||
#define EGL_KHR_gl_renderbuffer_image 1
|
||||
#define EGL_GL_RENDERBUFFER_KHR 0x30B9 /* eglCreateImageKHR target */
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
|
||||
#ifndef EGL_KHR_reusable_sync
|
||||
#define EGL_KHR_reusable_sync 1
|
||||
|
||||
typedef void* EGLSyncKHR;
|
||||
typedef khronos_utime_nanoseconds_t EGLTimeKHR;
|
||||
|
||||
#define EGL_SYNC_STATUS_KHR 0x30F1
|
||||
#define EGL_SIGNALED_KHR 0x30F2
|
||||
#define EGL_UNSIGNALED_KHR 0x30F3
|
||||
#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
|
||||
#define EGL_CONDITION_SATISFIED_KHR 0x30F6
|
||||
#define EGL_SYNC_TYPE_KHR 0x30F7
|
||||
#define EGL_SYNC_REUSABLE_KHR 0x30FA
|
||||
#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 /* eglClientWaitSyncKHR <flags> bitfield */
|
||||
#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
|
||||
#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
|
||||
EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
|
||||
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_image_base
|
||||
#define EGL_KHR_image_base 1
|
||||
/* Most interfaces defined by EGL_KHR_image_pixmap above */
|
||||
#define EGL_IMAGE_PRESERVED_KHR 0x30D2 /* eglCreateImageKHR attribute */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_image_pixmap
|
||||
#define EGL_KHR_image_pixmap 1
|
||||
/* Interfaces defined by EGL_KHR_image above */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_IMG_context_priority
|
||||
#define EGL_IMG_context_priority 1
|
||||
#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
|
||||
#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
|
||||
#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
|
||||
#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_lock_surface2
|
||||
#define EGL_KHR_lock_surface2 1
|
||||
#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
|
||||
#endif
|
||||
|
||||
#ifndef EGL_NV_coverage_sample
|
||||
#define EGL_NV_coverage_sample 1
|
||||
#define EGL_COVERAGE_BUFFERS_NV 0x30E0
|
||||
#define EGL_COVERAGE_SAMPLES_NV 0x30E1
|
||||
#endif
|
||||
|
||||
#ifndef EGL_NV_depth_nonlinear
|
||||
#define EGL_NV_depth_nonlinear 1
|
||||
#define EGL_DEPTH_ENCODING_NV 0x30E2
|
||||
#define EGL_DEPTH_ENCODING_NONE_NV 0
|
||||
#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64 /* EGLTimeNV requires 64-bit uint support */
|
||||
#ifndef EGL_NV_sync
|
||||
#define EGL_NV_sync 1
|
||||
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
|
||||
#define EGL_SYNC_STATUS_NV 0x30E7
|
||||
#define EGL_SIGNALED_NV 0x30E8
|
||||
#define EGL_UNSIGNALED_NV 0x30E9
|
||||
#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
|
||||
#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
|
||||
#define EGL_ALREADY_SIGNALED_NV 0x30EA
|
||||
#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
|
||||
#define EGL_CONDITION_SATISFIED_NV 0x30EC
|
||||
#define EGL_SYNC_TYPE_NV 0x30ED
|
||||
#define EGL_SYNC_CONDITION_NV 0x30EE
|
||||
#define EGL_SYNC_FENCE_NV 0x30EF
|
||||
#define EGL_NO_SYNC_NV ((EGLSyncNV)0)
|
||||
typedef void* EGLSyncNV;
|
||||
typedef khronos_utime_nanoseconds_t EGLTimeNV;
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLSyncNV eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
|
||||
EGLBoolean eglDestroySyncNV (EGLSyncNV sync);
|
||||
EGLBoolean eglFenceNV (EGLSyncNV sync);
|
||||
EGLint eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
|
||||
EGLBoolean eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
|
||||
EGLBoolean eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
|
||||
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64 /* Dependent on EGL_KHR_reusable_sync which requires 64-bit uint support */
|
||||
#ifndef EGL_KHR_fence_sync
|
||||
#define EGL_KHR_fence_sync 1
|
||||
/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */
|
||||
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
|
||||
#define EGL_SYNC_CONDITION_KHR 0x30F8
|
||||
#define EGL_SYNC_FENCE_KHR 0x30F9
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EGL_HI_clientpixmap
|
||||
#define EGL_HI_clientpixmap 1
|
||||
|
||||
/* Surface Attribute */
|
||||
#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
|
||||
/*
|
||||
* Structure representing a client pixmap
|
||||
* (pixmap's data is in client-space memory).
|
||||
*/
|
||||
struct EGLClientPixmapHI
|
||||
{
|
||||
void* pData;
|
||||
EGLint iWidth;
|
||||
EGLint iHeight;
|
||||
EGLint iStride;
|
||||
};
|
||||
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
|
||||
#endif /* EGL_HI_clientpixmap */
|
||||
|
||||
#ifndef EGL_HI_colorformats
|
||||
#define EGL_HI_colorformats 1
|
||||
/* Config Attribute */
|
||||
#define EGL_COLOR_FORMAT_HI 0x8F70
|
||||
/* Color Formats */
|
||||
#define EGL_COLOR_RGB_HI 0x8F71
|
||||
#define EGL_COLOR_RGBA_HI 0x8F72
|
||||
#define EGL_COLOR_ARGB_HI 0x8F73
|
||||
#endif /* EGL_HI_colorformats */
|
||||
|
||||
#ifndef EGL_MESA_drm_image
|
||||
#define EGL_MESA_drm_image 1
|
||||
#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 /* CreateDRMImageMESA attribute */
|
||||
#define EGL_DRM_BUFFER_USE_MESA 0x31D1 /* CreateDRMImageMESA attribute */
|
||||
#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 /* EGL_IMAGE_FORMAT_MESA attribute value */
|
||||
#define EGL_DRM_BUFFER_MESA 0x31D3 /* eglCreateImageKHR target */
|
||||
#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
|
||||
#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 /* EGL_DRM_BUFFER_USE_MESA bits */
|
||||
#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 /* EGL_DRM_BUFFER_USE_MESA bits */
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_NV_post_sub_buffer
|
||||
#define EGL_NV_post_sub_buffer 1
|
||||
#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_query_surface_pointer
|
||||
#define EGL_ANGLE_query_surface_pointer 1
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLBoolean eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
|
||||
#endif
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_software_display
|
||||
#define EGL_ANGLE_software_display 1
|
||||
#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1)
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
|
||||
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
|
||||
#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
|
||||
#endif
|
||||
|
||||
#ifndef EGL_NV_coverage_sample_resolve
|
||||
#define EGL_NV_coverage_sample_resolve 1
|
||||
#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
|
||||
#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
|
||||
#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
|
||||
#ifndef EGL_NV_system_time
|
||||
#define EGL_NV_system_time 1
|
||||
|
||||
typedef khronos_utime_nanoseconds_t EGLuint64NV;
|
||||
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV(void);
|
||||
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV(void);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
|
||||
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EGL_EXT_create_context_robustness
|
||||
#define EGL_EXT_create_context_robustness 1
|
||||
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
|
||||
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
|
||||
#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
|
||||
#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
129
src/3rdparty/angle/include/EGL/eglplatform.h
vendored
Normal file
129
src/3rdparty/angle/include/EGL/eglplatform.h
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
#ifndef __eglplatform_h_
|
||||
#define __eglplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2007-2009 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Platform-specific types and definitions for egl.h
|
||||
* $Revision: 12306 $ on $Date: 2010-08-25 09:51:28 -0700 (Wed, 25 Aug 2010) $
|
||||
*
|
||||
* Adopters may modify khrplatform.h and this file to suit their platform.
|
||||
* You are encouraged to submit all modifications to the Khronos group so that
|
||||
* they can be included in future versions of this file. Please submit changes
|
||||
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
|
||||
* by filing a bug against product "EGL" component "Registry".
|
||||
*/
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
|
||||
/* Macros used in EGL function prototype declarations.
|
||||
*
|
||||
* EGL functions should be prototyped as:
|
||||
*
|
||||
* EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
|
||||
* typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
|
||||
*
|
||||
* KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
|
||||
*/
|
||||
|
||||
#ifndef EGLAPI
|
||||
#define EGLAPI KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
#ifndef EGLAPIENTRY
|
||||
#define EGLAPIENTRY KHRONOS_APIENTRY
|
||||
#endif
|
||||
#define EGLAPIENTRYP EGLAPIENTRY*
|
||||
|
||||
/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
|
||||
* are aliases of window-system-dependent types, such as X Display * or
|
||||
* Windows Device Context. They must be defined in platform-specific
|
||||
* code below. The EGL-prefixed versions of Native*Type are the same
|
||||
* types, renamed in EGL 1.3 so all types in the API start with "EGL".
|
||||
*
|
||||
* Khronos STRONGLY RECOMMENDS that you use the default definitions
|
||||
* provided below, since these changes affect both binary and source
|
||||
* portability of applications using EGL running on different EGL
|
||||
* implementations.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HBITMAP EGLNativePixmapType;
|
||||
typedef HWND EGLNativeWindowType;
|
||||
|
||||
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
|
||||
|
||||
typedef int EGLNativeDisplayType;
|
||||
typedef void *EGLNativeWindowType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
|
||||
#elif defined(WL_EGL_PLATFORM)
|
||||
|
||||
typedef struct wl_display *EGLNativeDisplayType;
|
||||
typedef struct wl_egl_pixmap *EGLNativePixmapType;
|
||||
typedef struct wl_egl_window *EGLNativeWindowType;
|
||||
|
||||
#elif defined(__unix__) && !defined(ANDROID)
|
||||
|
||||
/* X11 (tentative) */
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
typedef Display *EGLNativeDisplayType;
|
||||
typedef Pixmap EGLNativePixmapType;
|
||||
typedef Window EGLNativeWindowType;
|
||||
|
||||
#elif defined(ANDROID)
|
||||
|
||||
struct egl_native_pixmap_t;
|
||||
|
||||
typedef struct ANativeWindow* EGLNativeWindowType;
|
||||
typedef struct egl_native_pixmap_t* EGLNativePixmapType;
|
||||
typedef void* EGLNativeDisplayType;
|
||||
|
||||
#else
|
||||
#error "Platform not recognized"
|
||||
#endif
|
||||
|
||||
/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
|
||||
typedef EGLNativeDisplayType NativeDisplayType;
|
||||
typedef EGLNativePixmapType NativePixmapType;
|
||||
typedef EGLNativeWindowType NativeWindowType;
|
||||
|
||||
|
||||
/* Define EGLint. This must be a signed integral type large enough to contain
|
||||
* all legal attribute names and values passed into and out of EGL, whether
|
||||
* their type is boolean, bitmask, enumerant (symbolic constant), integer,
|
||||
* handle, or other. While in general a 32-bit integer will suffice, if
|
||||
* handles are 64 bit types, then EGLint should be defined as a signed 64-bit
|
||||
* integer type.
|
||||
*/
|
||||
typedef khronos_int32_t EGLint;
|
||||
|
||||
#endif /* __eglplatform_h */
|
621
src/3rdparty/angle/include/GLES2/gl2.h
vendored
Normal file
621
src/3rdparty/angle/include/GLES2/gl2.h
vendored
Normal file
@ -0,0 +1,621 @@
|
||||
#ifndef __gl2_h_
|
||||
#define __gl2_h_
|
||||
|
||||
/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */
|
||||
|
||||
#include <GLES2/gl2platform.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This document is licensed under the SGI Free Software B License Version
|
||||
* 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Data type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
typedef void GLvoid;
|
||||
typedef char GLchar;
|
||||
typedef unsigned int GLenum;
|
||||
typedef unsigned char GLboolean;
|
||||
typedef unsigned int GLbitfield;
|
||||
typedef khronos_int8_t GLbyte;
|
||||
typedef short GLshort;
|
||||
typedef int GLint;
|
||||
typedef int GLsizei;
|
||||
typedef khronos_uint8_t GLubyte;
|
||||
typedef unsigned short GLushort;
|
||||
typedef unsigned int GLuint;
|
||||
typedef khronos_float_t GLfloat;
|
||||
typedef khronos_float_t GLclampf;
|
||||
typedef khronos_int32_t GLfixed;
|
||||
|
||||
/* GL types for handling large vertex buffer objects */
|
||||
typedef khronos_intptr_t GLintptr;
|
||||
typedef khronos_ssize_t GLsizeiptr;
|
||||
|
||||
/* OpenGL ES core versions */
|
||||
#define GL_ES_VERSION_2_0 1
|
||||
|
||||
/* ClearBufferMask */
|
||||
#define GL_DEPTH_BUFFER_BIT 0x00000100
|
||||
#define GL_STENCIL_BUFFER_BIT 0x00000400
|
||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||
|
||||
/* Boolean */
|
||||
#define GL_FALSE 0
|
||||
#define GL_TRUE 1
|
||||
|
||||
/* BeginMode */
|
||||
#define GL_POINTS 0x0000
|
||||
#define GL_LINES 0x0001
|
||||
#define GL_LINE_LOOP 0x0002
|
||||
#define GL_LINE_STRIP 0x0003
|
||||
#define GL_TRIANGLES 0x0004
|
||||
#define GL_TRIANGLE_STRIP 0x0005
|
||||
#define GL_TRIANGLE_FAN 0x0006
|
||||
|
||||
/* AlphaFunction (not supported in ES20) */
|
||||
/* GL_NEVER */
|
||||
/* GL_LESS */
|
||||
/* GL_EQUAL */
|
||||
/* GL_LEQUAL */
|
||||
/* GL_GREATER */
|
||||
/* GL_NOTEQUAL */
|
||||
/* GL_GEQUAL */
|
||||
/* GL_ALWAYS */
|
||||
|
||||
/* BlendingFactorDest */
|
||||
#define GL_ZERO 0
|
||||
#define GL_ONE 1
|
||||
#define GL_SRC_COLOR 0x0300
|
||||
#define GL_ONE_MINUS_SRC_COLOR 0x0301
|
||||
#define GL_SRC_ALPHA 0x0302
|
||||
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
|
||||
#define GL_DST_ALPHA 0x0304
|
||||
#define GL_ONE_MINUS_DST_ALPHA 0x0305
|
||||
|
||||
/* BlendingFactorSrc */
|
||||
/* GL_ZERO */
|
||||
/* GL_ONE */
|
||||
#define GL_DST_COLOR 0x0306
|
||||
#define GL_ONE_MINUS_DST_COLOR 0x0307
|
||||
#define GL_SRC_ALPHA_SATURATE 0x0308
|
||||
/* GL_SRC_ALPHA */
|
||||
/* GL_ONE_MINUS_SRC_ALPHA */
|
||||
/* GL_DST_ALPHA */
|
||||
/* GL_ONE_MINUS_DST_ALPHA */
|
||||
|
||||
/* BlendEquationSeparate */
|
||||
#define GL_FUNC_ADD 0x8006
|
||||
#define GL_BLEND_EQUATION 0x8009
|
||||
#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */
|
||||
#define GL_BLEND_EQUATION_ALPHA 0x883D
|
||||
|
||||
/* BlendSubtract */
|
||||
#define GL_FUNC_SUBTRACT 0x800A
|
||||
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
|
||||
|
||||
/* Separate Blend Functions */
|
||||
#define GL_BLEND_DST_RGB 0x80C8
|
||||
#define GL_BLEND_SRC_RGB 0x80C9
|
||||
#define GL_BLEND_DST_ALPHA 0x80CA
|
||||
#define GL_BLEND_SRC_ALPHA 0x80CB
|
||||
#define GL_CONSTANT_COLOR 0x8001
|
||||
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
|
||||
#define GL_CONSTANT_ALPHA 0x8003
|
||||
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
|
||||
#define GL_BLEND_COLOR 0x8005
|
||||
|
||||
/* Buffer Objects */
|
||||
#define GL_ARRAY_BUFFER 0x8892
|
||||
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
|
||||
#define GL_ARRAY_BUFFER_BINDING 0x8894
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
|
||||
|
||||
#define GL_STREAM_DRAW 0x88E0
|
||||
#define GL_STATIC_DRAW 0x88E4
|
||||
#define GL_DYNAMIC_DRAW 0x88E8
|
||||
|
||||
#define GL_BUFFER_SIZE 0x8764
|
||||
#define GL_BUFFER_USAGE 0x8765
|
||||
|
||||
#define GL_CURRENT_VERTEX_ATTRIB 0x8626
|
||||
|
||||
/* CullFaceMode */
|
||||
#define GL_FRONT 0x0404
|
||||
#define GL_BACK 0x0405
|
||||
#define GL_FRONT_AND_BACK 0x0408
|
||||
|
||||
/* DepthFunction */
|
||||
/* GL_NEVER */
|
||||
/* GL_LESS */
|
||||
/* GL_EQUAL */
|
||||
/* GL_LEQUAL */
|
||||
/* GL_GREATER */
|
||||
/* GL_NOTEQUAL */
|
||||
/* GL_GEQUAL */
|
||||
/* GL_ALWAYS */
|
||||
|
||||
/* EnableCap */
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
#define GL_CULL_FACE 0x0B44
|
||||
#define GL_BLEND 0x0BE2
|
||||
#define GL_DITHER 0x0BD0
|
||||
#define GL_STENCIL_TEST 0x0B90
|
||||
#define GL_DEPTH_TEST 0x0B71
|
||||
#define GL_SCISSOR_TEST 0x0C11
|
||||
#define GL_POLYGON_OFFSET_FILL 0x8037
|
||||
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
|
||||
#define GL_SAMPLE_COVERAGE 0x80A0
|
||||
|
||||
/* ErrorCode */
|
||||
#define GL_NO_ERROR 0
|
||||
#define GL_INVALID_ENUM 0x0500
|
||||
#define GL_INVALID_VALUE 0x0501
|
||||
#define GL_INVALID_OPERATION 0x0502
|
||||
#define GL_OUT_OF_MEMORY 0x0505
|
||||
|
||||
/* FrontFaceDirection */
|
||||
#define GL_CW 0x0900
|
||||
#define GL_CCW 0x0901
|
||||
|
||||
/* GetPName */
|
||||
#define GL_LINE_WIDTH 0x0B21
|
||||
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
|
||||
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
|
||||
#define GL_CULL_FACE_MODE 0x0B45
|
||||
#define GL_FRONT_FACE 0x0B46
|
||||
#define GL_DEPTH_RANGE 0x0B70
|
||||
#define GL_DEPTH_WRITEMASK 0x0B72
|
||||
#define GL_DEPTH_CLEAR_VALUE 0x0B73
|
||||
#define GL_DEPTH_FUNC 0x0B74
|
||||
#define GL_STENCIL_CLEAR_VALUE 0x0B91
|
||||
#define GL_STENCIL_FUNC 0x0B92
|
||||
#define GL_STENCIL_FAIL 0x0B94
|
||||
#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
|
||||
#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
|
||||
#define GL_STENCIL_REF 0x0B97
|
||||
#define GL_STENCIL_VALUE_MASK 0x0B93
|
||||
#define GL_STENCIL_WRITEMASK 0x0B98
|
||||
#define GL_STENCIL_BACK_FUNC 0x8800
|
||||
#define GL_STENCIL_BACK_FAIL 0x8801
|
||||
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
|
||||
#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
|
||||
#define GL_STENCIL_BACK_REF 0x8CA3
|
||||
#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
|
||||
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
|
||||
#define GL_VIEWPORT 0x0BA2
|
||||
#define GL_SCISSOR_BOX 0x0C10
|
||||
/* GL_SCISSOR_TEST */
|
||||
#define GL_COLOR_CLEAR_VALUE 0x0C22
|
||||
#define GL_COLOR_WRITEMASK 0x0C23
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
#define GL_PACK_ALIGNMENT 0x0D05
|
||||
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||
#define GL_MAX_VIEWPORT_DIMS 0x0D3A
|
||||
#define GL_SUBPIXEL_BITS 0x0D50
|
||||
#define GL_RED_BITS 0x0D52
|
||||
#define GL_GREEN_BITS 0x0D53
|
||||
#define GL_BLUE_BITS 0x0D54
|
||||
#define GL_ALPHA_BITS 0x0D55
|
||||
#define GL_DEPTH_BITS 0x0D56
|
||||
#define GL_STENCIL_BITS 0x0D57
|
||||
#define GL_POLYGON_OFFSET_UNITS 0x2A00
|
||||
/* GL_POLYGON_OFFSET_FILL */
|
||||
#define GL_POLYGON_OFFSET_FACTOR 0x8038
|
||||
#define GL_TEXTURE_BINDING_2D 0x8069
|
||||
#define GL_SAMPLE_BUFFERS 0x80A8
|
||||
#define GL_SAMPLES 0x80A9
|
||||
#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
|
||||
#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
|
||||
|
||||
/* GetTextureParameter */
|
||||
/* GL_TEXTURE_MAG_FILTER */
|
||||
/* GL_TEXTURE_MIN_FILTER */
|
||||
/* GL_TEXTURE_WRAP_S */
|
||||
/* GL_TEXTURE_WRAP_T */
|
||||
|
||||
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
|
||||
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
|
||||
|
||||
/* HintMode */
|
||||
#define GL_DONT_CARE 0x1100
|
||||
#define GL_FASTEST 0x1101
|
||||
#define GL_NICEST 0x1102
|
||||
|
||||
/* HintTarget */
|
||||
#define GL_GENERATE_MIPMAP_HINT 0x8192
|
||||
|
||||
/* DataType */
|
||||
#define GL_BYTE 0x1400
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
#define GL_SHORT 0x1402
|
||||
#define GL_UNSIGNED_SHORT 0x1403
|
||||
#define GL_INT 0x1404
|
||||
#define GL_UNSIGNED_INT 0x1405
|
||||
#define GL_FLOAT 0x1406
|
||||
#define GL_FIXED 0x140C
|
||||
|
||||
/* PixelFormat */
|
||||
#define GL_DEPTH_COMPONENT 0x1902
|
||||
#define GL_ALPHA 0x1906
|
||||
#define GL_RGB 0x1907
|
||||
#define GL_RGBA 0x1908
|
||||
#define GL_LUMINANCE 0x1909
|
||||
#define GL_LUMINANCE_ALPHA 0x190A
|
||||
|
||||
/* PixelType */
|
||||
/* GL_UNSIGNED_BYTE */
|
||||
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
|
||||
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
|
||||
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
|
||||
|
||||
/* Shaders */
|
||||
#define GL_FRAGMENT_SHADER 0x8B30
|
||||
#define GL_VERTEX_SHADER 0x8B31
|
||||
#define GL_MAX_VERTEX_ATTRIBS 0x8869
|
||||
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
|
||||
#define GL_MAX_VARYING_VECTORS 0x8DFC
|
||||
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
|
||||
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
|
||||
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
|
||||
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
|
||||
#define GL_SHADER_TYPE 0x8B4F
|
||||
#define GL_DELETE_STATUS 0x8B80
|
||||
#define GL_LINK_STATUS 0x8B82
|
||||
#define GL_VALIDATE_STATUS 0x8B83
|
||||
#define GL_ATTACHED_SHADERS 0x8B85
|
||||
#define GL_ACTIVE_UNIFORMS 0x8B86
|
||||
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
|
||||
#define GL_ACTIVE_ATTRIBUTES 0x8B89
|
||||
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
|
||||
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
|
||||
#define GL_CURRENT_PROGRAM 0x8B8D
|
||||
|
||||
/* StencilFunction */
|
||||
#define GL_NEVER 0x0200
|
||||
#define GL_LESS 0x0201
|
||||
#define GL_EQUAL 0x0202
|
||||
#define GL_LEQUAL 0x0203
|
||||
#define GL_GREATER 0x0204
|
||||
#define GL_NOTEQUAL 0x0205
|
||||
#define GL_GEQUAL 0x0206
|
||||
#define GL_ALWAYS 0x0207
|
||||
|
||||
/* StencilOp */
|
||||
/* GL_ZERO */
|
||||
#define GL_KEEP 0x1E00
|
||||
#define GL_REPLACE 0x1E01
|
||||
#define GL_INCR 0x1E02
|
||||
#define GL_DECR 0x1E03
|
||||
#define GL_INVERT 0x150A
|
||||
#define GL_INCR_WRAP 0x8507
|
||||
#define GL_DECR_WRAP 0x8508
|
||||
|
||||
/* StringName */
|
||||
#define GL_VENDOR 0x1F00
|
||||
#define GL_RENDERER 0x1F01
|
||||
#define GL_VERSION 0x1F02
|
||||
#define GL_EXTENSIONS 0x1F03
|
||||
|
||||
/* TextureMagFilter */
|
||||
#define GL_NEAREST 0x2600
|
||||
#define GL_LINEAR 0x2601
|
||||
|
||||
/* TextureMinFilter */
|
||||
/* GL_NEAREST */
|
||||
/* GL_LINEAR */
|
||||
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
|
||||
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
|
||||
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
|
||||
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
|
||||
|
||||
/* TextureParameterName */
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
#define GL_TEXTURE_WRAP_S 0x2802
|
||||
#define GL_TEXTURE_WRAP_T 0x2803
|
||||
|
||||
/* TextureTarget */
|
||||
/* GL_TEXTURE_2D */
|
||||
#define GL_TEXTURE 0x1702
|
||||
|
||||
#define GL_TEXTURE_CUBE_MAP 0x8513
|
||||
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
|
||||
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
|
||||
|
||||
/* TextureUnit */
|
||||
#define GL_TEXTURE0 0x84C0
|
||||
#define GL_TEXTURE1 0x84C1
|
||||
#define GL_TEXTURE2 0x84C2
|
||||
#define GL_TEXTURE3 0x84C3
|
||||
#define GL_TEXTURE4 0x84C4
|
||||
#define GL_TEXTURE5 0x84C5
|
||||
#define GL_TEXTURE6 0x84C6
|
||||
#define GL_TEXTURE7 0x84C7
|
||||
#define GL_TEXTURE8 0x84C8
|
||||
#define GL_TEXTURE9 0x84C9
|
||||
#define GL_TEXTURE10 0x84CA
|
||||
#define GL_TEXTURE11 0x84CB
|
||||
#define GL_TEXTURE12 0x84CC
|
||||
#define GL_TEXTURE13 0x84CD
|
||||
#define GL_TEXTURE14 0x84CE
|
||||
#define GL_TEXTURE15 0x84CF
|
||||
#define GL_TEXTURE16 0x84D0
|
||||
#define GL_TEXTURE17 0x84D1
|
||||
#define GL_TEXTURE18 0x84D2
|
||||
#define GL_TEXTURE19 0x84D3
|
||||
#define GL_TEXTURE20 0x84D4
|
||||
#define GL_TEXTURE21 0x84D5
|
||||
#define GL_TEXTURE22 0x84D6
|
||||
#define GL_TEXTURE23 0x84D7
|
||||
#define GL_TEXTURE24 0x84D8
|
||||
#define GL_TEXTURE25 0x84D9
|
||||
#define GL_TEXTURE26 0x84DA
|
||||
#define GL_TEXTURE27 0x84DB
|
||||
#define GL_TEXTURE28 0x84DC
|
||||
#define GL_TEXTURE29 0x84DD
|
||||
#define GL_TEXTURE30 0x84DE
|
||||
#define GL_TEXTURE31 0x84DF
|
||||
#define GL_ACTIVE_TEXTURE 0x84E0
|
||||
|
||||
/* TextureWrapMode */
|
||||
#define GL_REPEAT 0x2901
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
#define GL_MIRRORED_REPEAT 0x8370
|
||||
|
||||
/* Uniform Types */
|
||||
#define GL_FLOAT_VEC2 0x8B50
|
||||
#define GL_FLOAT_VEC3 0x8B51
|
||||
#define GL_FLOAT_VEC4 0x8B52
|
||||
#define GL_INT_VEC2 0x8B53
|
||||
#define GL_INT_VEC3 0x8B54
|
||||
#define GL_INT_VEC4 0x8B55
|
||||
#define GL_BOOL 0x8B56
|
||||
#define GL_BOOL_VEC2 0x8B57
|
||||
#define GL_BOOL_VEC3 0x8B58
|
||||
#define GL_BOOL_VEC4 0x8B59
|
||||
#define GL_FLOAT_MAT2 0x8B5A
|
||||
#define GL_FLOAT_MAT3 0x8B5B
|
||||
#define GL_FLOAT_MAT4 0x8B5C
|
||||
#define GL_SAMPLER_2D 0x8B5E
|
||||
#define GL_SAMPLER_CUBE 0x8B60
|
||||
|
||||
/* Vertex Arrays */
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
|
||||
|
||||
/* Read Format */
|
||||
#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
|
||||
#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
|
||||
|
||||
/* Shader Source */
|
||||
#define GL_COMPILE_STATUS 0x8B81
|
||||
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||
#define GL_SHADER_SOURCE_LENGTH 0x8B88
|
||||
#define GL_SHADER_COMPILER 0x8DFA
|
||||
|
||||
/* Shader Binary */
|
||||
#define GL_SHADER_BINARY_FORMATS 0x8DF8
|
||||
#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
|
||||
|
||||
/* Shader Precision-Specified Types */
|
||||
#define GL_LOW_FLOAT 0x8DF0
|
||||
#define GL_MEDIUM_FLOAT 0x8DF1
|
||||
#define GL_HIGH_FLOAT 0x8DF2
|
||||
#define GL_LOW_INT 0x8DF3
|
||||
#define GL_MEDIUM_INT 0x8DF4
|
||||
#define GL_HIGH_INT 0x8DF5
|
||||
|
||||
/* Framebuffer Object. */
|
||||
#define GL_FRAMEBUFFER 0x8D40
|
||||
#define GL_RENDERBUFFER 0x8D41
|
||||
|
||||
#define GL_RGBA4 0x8056
|
||||
#define GL_RGB5_A1 0x8057
|
||||
#define GL_RGB565 0x8D62
|
||||
#define GL_DEPTH_COMPONENT16 0x81A5
|
||||
#define GL_STENCIL_INDEX 0x1901
|
||||
#define GL_STENCIL_INDEX8 0x8D48
|
||||
|
||||
#define GL_RENDERBUFFER_WIDTH 0x8D42
|
||||
#define GL_RENDERBUFFER_HEIGHT 0x8D43
|
||||
#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
|
||||
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
|
||||
#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
|
||||
#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
|
||||
#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
|
||||
#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
|
||||
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
|
||||
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
|
||||
|
||||
#define GL_COLOR_ATTACHMENT0 0x8CE0
|
||||
#define GL_DEPTH_ATTACHMENT 0x8D00
|
||||
#define GL_STENCIL_ATTACHMENT 0x8D20
|
||||
|
||||
#define GL_NONE 0
|
||||
|
||||
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
|
||||
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
|
||||
|
||||
#define GL_FRAMEBUFFER_BINDING 0x8CA6
|
||||
#define GL_RENDERBUFFER_BINDING 0x8CA7
|
||||
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
|
||||
|
||||
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* GL core functions.
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
|
||||
GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
|
||||
GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name);
|
||||
GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
|
||||
GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
|
||||
GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
|
||||
GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
|
||||
GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||
GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode );
|
||||
GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
|
||||
GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
|
||||
GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
|
||||
GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
|
||||
GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
|
||||
GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
|
||||
GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
|
||||
GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||
GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth);
|
||||
GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
|
||||
GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
|
||||
GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
|
||||
GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
|
||||
GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
|
||||
GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
|
||||
GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
|
||||
GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers);
|
||||
GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers);
|
||||
GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
|
||||
GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers);
|
||||
GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
|
||||
GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures);
|
||||
GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
|
||||
GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
|
||||
GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar);
|
||||
GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
|
||||
GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
|
||||
GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
|
||||
GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
|
||||
GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
|
||||
GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
|
||||
GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
|
||||
GL_APICALL void GL_APIENTRY glFinish (void);
|
||||
GL_APICALL void GL_APIENTRY glFlush (void);
|
||||
GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
|
||||
GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
|
||||
GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers);
|
||||
GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
|
||||
GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers);
|
||||
GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers);
|
||||
GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures);
|
||||
GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
|
||||
GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
|
||||
GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
|
||||
GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name);
|
||||
GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params);
|
||||
GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params);
|
||||
GL_APICALL GLenum GL_APIENTRY glGetError (void);
|
||||
GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params);
|
||||
GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params);
|
||||
GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params);
|
||||
GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params);
|
||||
GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
|
||||
GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params);
|
||||
GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params);
|
||||
GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
|
||||
GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
|
||||
GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
|
||||
GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name);
|
||||
GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params);
|
||||
GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params);
|
||||
GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params);
|
||||
GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params);
|
||||
GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer);
|
||||
GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
|
||||
GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
|
||||
GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
|
||||
GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
|
||||
GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
|
||||
GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
|
||||
GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
|
||||
GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
|
||||
GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
|
||||
GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
|
||||
GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
|
||||
GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
|
||||
GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
|
||||
GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
|
||||
GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params);
|
||||
GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
|
||||
GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params);
|
||||
GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
|
||||
GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x);
|
||||
GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v);
|
||||
GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x);
|
||||
GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v);
|
||||
GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y);
|
||||
GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v);
|
||||
GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y);
|
||||
GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v);
|
||||
GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z);
|
||||
GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v);
|
||||
GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z);
|
||||
GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v);
|
||||
GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v);
|
||||
GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w);
|
||||
GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v);
|
||||
GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
|
||||
GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
|
||||
GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __gl2_h_ */
|
1504
src/3rdparty/angle/include/GLES2/gl2ext.h
vendored
Normal file
1504
src/3rdparty/angle/include/GLES2/gl2ext.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
30
src/3rdparty/angle/include/GLES2/gl2platform.h
vendored
Normal file
30
src/3rdparty/angle/include/GLES2/gl2platform.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef __gl2platform_h_
|
||||
#define __gl2platform_h_
|
||||
|
||||
/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */
|
||||
|
||||
/*
|
||||
* This document is licensed under the SGI Free Software B License Version
|
||||
* 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
|
||||
*/
|
||||
|
||||
/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h
|
||||
*
|
||||
* Adopters may modify khrplatform.h and this file to suit their platform.
|
||||
* You are encouraged to submit all modifications to the Khronos group so that
|
||||
* they can be included in future versions of this file. Please submit changes
|
||||
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
|
||||
* by filing a bug against product "OpenGL-ES" component "Registry".
|
||||
*/
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
|
||||
#ifndef GL_APICALL
|
||||
#define GL_APICALL KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
#ifndef GL_APIENTRY
|
||||
#define GL_APIENTRY KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
#endif /* __gl2platform_h_ */
|
354
src/3rdparty/angle/include/GLSLANG/ShaderLang.h
vendored
Normal file
354
src/3rdparty/angle/include/GLSLANG/ShaderLang.h
vendored
Normal file
@ -0,0 +1,354 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
#ifndef _COMPILER_INTERFACE_INCLUDED_
|
||||
#define _COMPILER_INTERFACE_INCLUDED_
|
||||
|
||||
#if defined(COMPONENT_BUILD)
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
#if defined(COMPILER_IMPLEMENTATION)
|
||||
#define COMPILER_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define COMPILER_EXPORT __declspec(dllimport)
|
||||
#endif // defined(COMPILER_IMPLEMENTATION)
|
||||
|
||||
#else // defined(WIN32)
|
||||
#define COMPILER_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#else // defined(COMPONENT_BUILD)
|
||||
#define COMPILER_EXPORT
|
||||
#endif
|
||||
|
||||
//
|
||||
// This is the platform independent interface between an OGL driver
|
||||
// and the shading language compiler.
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Version number for shader translation API.
|
||||
// It is incremented everytime the API changes.
|
||||
#define SH_VERSION 107
|
||||
|
||||
//
|
||||
// The names of the following enums have been derived by replacing GL prefix
|
||||
// with SH. For example, SH_INFO_LOG_LENGTH is equivalent to GL_INFO_LOG_LENGTH.
|
||||
// The enum values are also equal to the values of their GL counterpart. This
|
||||
// is done to make it easier for applications to use the shader library.
|
||||
//
|
||||
typedef enum {
|
||||
SH_FRAGMENT_SHADER = 0x8B30,
|
||||
SH_VERTEX_SHADER = 0x8B31
|
||||
} ShShaderType;
|
||||
|
||||
typedef enum {
|
||||
SH_GLES2_SPEC = 0x8B40,
|
||||
SH_WEBGL_SPEC = 0x8B41,
|
||||
|
||||
// The CSS Shaders spec is a subset of the WebGL spec.
|
||||
//
|
||||
// In both CSS vertex and fragment shaders, ANGLE:
|
||||
// (1) Reserves the "css_" prefix.
|
||||
// (2) Renames the main function to css_main.
|
||||
// (3) Disables the gl_MaxDrawBuffers built-in.
|
||||
//
|
||||
// In CSS fragment shaders, ANGLE:
|
||||
// (1) Disables the gl_FragColor built-in.
|
||||
// (2) Disables the gl_FragData built-in.
|
||||
// (3) Enables the css_MixColor built-in.
|
||||
// (4) Enables the css_ColorMatrix built-in.
|
||||
//
|
||||
// After passing a CSS shader through ANGLE, the browser is expected to append
|
||||
// a new main function to it.
|
||||
// This new main function will call the css_main function.
|
||||
// It may also perform additional operations like varying assignment, texture
|
||||
// access, and gl_FragColor assignment in order to implement the CSS Shaders
|
||||
// blend modes.
|
||||
//
|
||||
SH_CSS_SHADERS_SPEC = 0x8B42
|
||||
} ShShaderSpec;
|
||||
|
||||
typedef enum {
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
SH_GLSL_OUTPUT = 0x8B46,
|
||||
SH_HLSL_OUTPUT = 0x8B47
|
||||
} ShShaderOutput;
|
||||
|
||||
typedef enum {
|
||||
SH_NONE = 0,
|
||||
SH_INT = 0x1404,
|
||||
SH_FLOAT = 0x1406,
|
||||
SH_FLOAT_VEC2 = 0x8B50,
|
||||
SH_FLOAT_VEC3 = 0x8B51,
|
||||
SH_FLOAT_VEC4 = 0x8B52,
|
||||
SH_INT_VEC2 = 0x8B53,
|
||||
SH_INT_VEC3 = 0x8B54,
|
||||
SH_INT_VEC4 = 0x8B55,
|
||||
SH_BOOL = 0x8B56,
|
||||
SH_BOOL_VEC2 = 0x8B57,
|
||||
SH_BOOL_VEC3 = 0x8B58,
|
||||
SH_BOOL_VEC4 = 0x8B59,
|
||||
SH_FLOAT_MAT2 = 0x8B5A,
|
||||
SH_FLOAT_MAT3 = 0x8B5B,
|
||||
SH_FLOAT_MAT4 = 0x8B5C,
|
||||
SH_SAMPLER_2D = 0x8B5E,
|
||||
SH_SAMPLER_CUBE = 0x8B60,
|
||||
SH_SAMPLER_2D_RECT_ARB = 0x8B63,
|
||||
SH_SAMPLER_EXTERNAL_OES = 0x8D66
|
||||
} ShDataType;
|
||||
|
||||
typedef enum {
|
||||
SH_INFO_LOG_LENGTH = 0x8B84,
|
||||
SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
|
||||
SH_ACTIVE_UNIFORMS = 0x8B86,
|
||||
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
|
||||
SH_ACTIVE_ATTRIBUTES = 0x8B89,
|
||||
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
|
||||
SH_MAPPED_NAME_MAX_LENGTH = 0x8B8B
|
||||
} ShShaderInfo;
|
||||
|
||||
// Compile options.
|
||||
typedef enum {
|
||||
SH_VALIDATE = 0,
|
||||
SH_VALIDATE_LOOP_INDEXING = 0x0001,
|
||||
SH_INTERMEDIATE_TREE = 0x0002,
|
||||
SH_OBJECT_CODE = 0x0004,
|
||||
SH_ATTRIBUTES_UNIFORMS = 0x0008,
|
||||
SH_LINE_DIRECTIVES = 0x0010,
|
||||
SH_SOURCE_PATH = 0x0020,
|
||||
SH_MAP_LONG_VARIABLE_NAMES = 0x0040,
|
||||
SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX = 0x0080,
|
||||
|
||||
// This is needed only as a workaround for certain OpenGL driver bugs.
|
||||
SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100,
|
||||
|
||||
// This is an experimental flag to enforce restrictions that aim to prevent
|
||||
// timing attacks.
|
||||
// It generates compilation errors for shaders that could expose sensitive
|
||||
// texture information via the timing channel.
|
||||
// To use this flag, you must compile the shader under the WebGL spec
|
||||
// (using the SH_WEBGL_SPEC flag).
|
||||
SH_TIMING_RESTRICTIONS = 0x0200,
|
||||
|
||||
// This flag prints the dependency graph that is used to enforce timing
|
||||
// restrictions on fragment shaders.
|
||||
// This flag only has an effect if all of the following are true:
|
||||
// - The shader spec is SH_WEBGL_SPEC.
|
||||
// - The compile options contain the SH_TIMING_RESTRICTIONS flag.
|
||||
// - The shader type is SH_FRAGMENT_SHADER.
|
||||
SH_DEPENDENCY_GRAPH = 0x0400,
|
||||
|
||||
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
|
||||
SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800,
|
||||
} ShCompileOptions;
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler operations.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
//
|
||||
COMPILER_EXPORT int ShInitialize();
|
||||
//
|
||||
// Driver should call this at shutdown.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
//
|
||||
COMPILER_EXPORT int ShFinalize();
|
||||
|
||||
//
|
||||
// Implementation dependent built-in resources (constants and extensions).
|
||||
// The names for these resources has been obtained by stripping gl_/GL_.
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
// Constants.
|
||||
int MaxVertexAttribs;
|
||||
int MaxVertexUniformVectors;
|
||||
int MaxVaryingVectors;
|
||||
int MaxVertexTextureImageUnits;
|
||||
int MaxCombinedTextureImageUnits;
|
||||
int MaxTextureImageUnits;
|
||||
int MaxFragmentUniformVectors;
|
||||
int MaxDrawBuffers;
|
||||
|
||||
// Extensions.
|
||||
// Set to 1 to enable the extension, else 0.
|
||||
int OES_standard_derivatives;
|
||||
int OES_EGL_image_external;
|
||||
int ARB_texture_rectangle;
|
||||
} ShBuiltInResources;
|
||||
|
||||
//
|
||||
// Initialize built-in resources with minimum expected values.
|
||||
//
|
||||
COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
|
||||
|
||||
//
|
||||
// ShHandle held by but opaque to the driver. It is allocated,
|
||||
// managed, and de-allocated by the compiler. It's contents
|
||||
// are defined by and used by the compiler.
|
||||
//
|
||||
// If handle creation fails, 0 will be returned.
|
||||
//
|
||||
typedef void* ShHandle;
|
||||
|
||||
//
|
||||
// Driver calls these to create and destroy compiler objects.
|
||||
//
|
||||
// Returns the handle of constructed compiler, null if the requested compiler is
|
||||
// not supported.
|
||||
// Parameters:
|
||||
// type: Specifies the type of shader - SH_FRAGMENT_SHADER or SH_VERTEX_SHADER.
|
||||
// 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,
|
||||
// or SH_HLSL_OUTPUT.
|
||||
// resources: Specifies the built-in resources.
|
||||
COMPILER_EXPORT ShHandle ShConstructCompiler(
|
||||
ShShaderType type,
|
||||
ShShaderSpec spec,
|
||||
ShShaderOutput output,
|
||||
const ShBuiltInResources* resources);
|
||||
COMPILER_EXPORT void ShDestruct(ShHandle handle);
|
||||
|
||||
//
|
||||
// Compiles the given shader source.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// Parameters:
|
||||
// handle: Specifies the handle of compiler to be used.
|
||||
// shaderStrings: Specifies an array of pointers to null-terminated strings
|
||||
// containing the shader source code.
|
||||
// numStrings: Specifies the number of elements in shaderStrings array.
|
||||
// compileOptions: A mask containing the following parameters:
|
||||
// SH_VALIDATE: Validates shader to ensure that it conforms to the spec
|
||||
// specified during compiler construction.
|
||||
// SH_VALIDATE_LOOP_INDEXING: Validates loop and indexing in the shader to
|
||||
// ensure that they do not exceed the minimum
|
||||
// functionality mandated in GLSL 1.0 spec,
|
||||
// Appendix A, Section 4 and 5.
|
||||
// There is no need to specify this parameter when
|
||||
// compiling for WebGL - it is implied.
|
||||
// SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
|
||||
// Can be queried by calling ShGetInfoLog().
|
||||
// SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
|
||||
// Can be queried by calling ShGetObjectCode().
|
||||
// SH_ATTRIBUTES_UNIFORMS: Extracts attributes and uniforms.
|
||||
// Can be queried by calling ShGetActiveAttrib() and
|
||||
// ShGetActiveUniform().
|
||||
//
|
||||
COMPILER_EXPORT int ShCompile(
|
||||
const ShHandle handle,
|
||||
const char* const shaderStrings[],
|
||||
const int numStrings,
|
||||
int compileOptions
|
||||
);
|
||||
|
||||
// Returns a parameter from a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// pname: Specifies the parameter to query.
|
||||
// The following parameters are defined:
|
||||
// SH_INFO_LOG_LENGTH: the number of characters in the information log
|
||||
// including the null termination character.
|
||||
// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
|
||||
// including the null termination character.
|
||||
// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
|
||||
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
|
||||
// variable name including the null
|
||||
// termination character.
|
||||
// SH_ACTIVE_UNIFORMS: the number of active uniform variables.
|
||||
// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
|
||||
// variable name including the null
|
||||
// termination character.
|
||||
// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
|
||||
// the null termination character.
|
||||
//
|
||||
// params: Requested parameter
|
||||
COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
|
||||
ShShaderInfo pname,
|
||||
int* params);
|
||||
|
||||
// Returns nul-terminated information log for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// infoLog: Specifies an array of characters that is used to return
|
||||
// the information log. It is assumed that infoLog has enough memory
|
||||
// to accomodate the information log. The size of the buffer required
|
||||
// to store the returned information log can be obtained by calling
|
||||
// ShGetInfo with SH_INFO_LOG_LENGTH.
|
||||
COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog);
|
||||
|
||||
// Returns null-terminated object code for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// infoLog: Specifies an array of characters that is used to return
|
||||
// the object code. It is assumed that infoLog has enough memory to
|
||||
// accomodate the object code. The size of the buffer required to
|
||||
// store the returned object code can be obtained by calling
|
||||
// ShGetInfo with SH_OBJECT_CODE_LENGTH.
|
||||
COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
|
||||
|
||||
// Returns information about an active attribute variable.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// index: Specifies the index of the attribute variable to be queried.
|
||||
// length: Returns the number of characters actually written in the string
|
||||
// indicated by name (excluding the null terminator) if a value other
|
||||
// than NULL is passed.
|
||||
// size: Returns the size of the attribute variable.
|
||||
// type: Returns the data type of the attribute variable.
|
||||
// name: Returns a null terminated string containing the name of the
|
||||
// attribute variable. It is assumed that name has enough memory to
|
||||
// accomodate the attribute variable name. The size of the buffer
|
||||
// required to store the attribute variable name can be obtained by
|
||||
// calling ShGetInfo with SH_ACTIVE_ATTRIBUTE_MAX_LENGTH.
|
||||
// mappedName: Returns a null terminated string containing the mapped name of
|
||||
// the attribute variable, It is assumed that mappedName has enough
|
||||
// memory (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care
|
||||
// about the mapped name. If the name is not mapped, then name and
|
||||
// mappedName are the same.
|
||||
COMPILER_EXPORT void ShGetActiveAttrib(const ShHandle handle,
|
||||
int index,
|
||||
int* length,
|
||||
int* size,
|
||||
ShDataType* type,
|
||||
char* name,
|
||||
char* mappedName);
|
||||
|
||||
// Returns information about an active uniform variable.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// index: Specifies the index of the uniform variable to be queried.
|
||||
// length: Returns the number of characters actually written in the string
|
||||
// indicated by name (excluding the null terminator) if a value
|
||||
// other than NULL is passed.
|
||||
// size: Returns the size of the uniform variable.
|
||||
// type: Returns the data type of the uniform variable.
|
||||
// name: Returns a null terminated string containing the name of the
|
||||
// uniform variable. It is assumed that name has enough memory to
|
||||
// accomodate the uniform variable name. The size of the buffer required
|
||||
// to store the uniform variable name can be obtained by calling
|
||||
// ShGetInfo with SH_ACTIVE_UNIFORMS_MAX_LENGTH.
|
||||
// mappedName: Returns a null terminated string containing the mapped name of
|
||||
// the uniform variable, It is assumed that mappedName has enough
|
||||
// memory (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care
|
||||
// about the mapped name. If the name is not mapped, then name and
|
||||
// mappedName are the same.
|
||||
COMPILER_EXPORT void ShGetActiveUniform(const ShHandle handle,
|
||||
int index,
|
||||
int* length,
|
||||
int* size,
|
||||
ShDataType* type,
|
||||
char* name,
|
||||
char* mappedName);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _COMPILER_INTERFACE_INCLUDED_
|
269
src/3rdparty/angle/include/KHR/khrplatform.h
vendored
Normal file
269
src/3rdparty/angle/include/KHR/khrplatform.h
vendored
Normal file
@ -0,0 +1,269 @@
|
||||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2009 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by sending them to the public Khronos Bugzilla
|
||||
* (http://khronos.org/bugzilla) by filing a bug against product
|
||||
* "Khronos (general)" component "Registry".
|
||||
*
|
||||
* A predefined template which fills in some of the bug fields can be
|
||||
* reached using http://tinyurl.com/khrplatform-h-bugreport, but you
|
||||
* must create a Bugzilla login first.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
47
src/3rdparty/angle/src/common/RefCountObject.cpp
vendored
Normal file
47
src/3rdparty/angle/src/common/RefCountObject.cpp
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// 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.cpp: 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.)
|
||||
|
||||
#include "RefCountObject.h"
|
||||
|
||||
RefCountObject::RefCountObject(GLuint id)
|
||||
{
|
||||
mId = id;
|
||||
mRefCount = 0;
|
||||
}
|
||||
|
||||
RefCountObject::~RefCountObject()
|
||||
{
|
||||
ASSERT(mRefCount == 0);
|
||||
}
|
||||
|
||||
void RefCountObject::addRef() const
|
||||
{
|
||||
mRefCount++;
|
||||
}
|
||||
|
||||
void RefCountObject::release() const
|
||||
{
|
||||
ASSERT(mRefCount > 0);
|
||||
|
||||
if (--mRefCount == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void RefCountObjectBindingPointer::set(RefCountObject *newObject)
|
||||
{
|
||||
// addRef first in case newObject == mObject and this is the last reference to it.
|
||||
if (newObject != NULL) newObject->addRef();
|
||||
if (mObject != NULL) mObject->release();
|
||||
|
||||
mObject = newObject;
|
||||
}
|
65
src/3rdparty/angle/src/common/RefCountObject.h
vendored
Normal file
65
src/3rdparty/angle/src/common/RefCountObject.h
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// 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 <cstddef>
|
||||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
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(); }
|
||||
};
|
||||
|
||||
#endif // COMMON_REFCOUNTOBJECT_H_
|
26
src/3rdparty/angle/src/common/angleutils.h
vendored
Normal file
26
src/3rdparty/angle/src/common/angleutils.h
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// angleutils.h: Common ANGLE utilities.
|
||||
|
||||
#ifndef COMMON_ANGLEUTILS_H_
|
||||
#define COMMON_ANGLEUTILS_H_
|
||||
|
||||
// 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&)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#define VENDOR_ID_AMD 0x1002
|
||||
#define VENDOR_ID_INTEL 0x8086
|
||||
#define VENDOR_ID_NVIDIA 0x10DE
|
||||
|
||||
#endif // COMMON_ANGLEUTILS_H_
|
103
src/3rdparty/angle/src/common/debug.cpp
vendored
Normal file
103
src/3rdparty/angle/src/common/debug.cpp
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// debug.cpp: Debugging utilities.
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <d3d9.h>
|
||||
#include <windows.h>
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
|
||||
|
||||
static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
|
||||
{
|
||||
#if !defined(ANGLE_DISABLE_PERF)
|
||||
if (perfActive())
|
||||
{
|
||||
char message[32768];
|
||||
int len = vsprintf_s(message, format, vararg);
|
||||
if (len < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// There are no ASCII variants of these D3DPERF functions.
|
||||
wchar_t wideMessage[32768];
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
wideMessage[i] = message[i];
|
||||
}
|
||||
wideMessage[len] = 0;
|
||||
|
||||
perfFunc(0, wideMessage);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(ANGLE_DISABLE_TRACE)
|
||||
#if defined(NDEBUG)
|
||||
if (traceFileDebugOnly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
FILE* file = fopen(TRACE_OUTPUT_FILE, "a");
|
||||
if (file)
|
||||
{
|
||||
vfprintf(file, format, vararg);
|
||||
fclose(file);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void trace(bool traceFileDebugOnly, const char *format, ...)
|
||||
{
|
||||
va_list vararg;
|
||||
va_start(vararg, format);
|
||||
#if defined(ANGLE_DISABLE_PERF)
|
||||
output(traceFileDebugOnly, NULL, format, vararg);
|
||||
#else
|
||||
output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
|
||||
#endif
|
||||
va_end(vararg);
|
||||
}
|
||||
|
||||
bool perfActive()
|
||||
{
|
||||
#if defined(ANGLE_DISABLE_PERF)
|
||||
return false;
|
||||
#else
|
||||
static bool active = D3DPERF_GetStatus() != 0;
|
||||
return active;
|
||||
#endif
|
||||
}
|
||||
|
||||
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
|
||||
{
|
||||
#if !defined(ANGLE_DISABLE_PERF)
|
||||
va_list vararg;
|
||||
va_start(vararg, format);
|
||||
output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
|
||||
va_end(vararg);
|
||||
#endif
|
||||
}
|
||||
|
||||
ScopedPerfEventHelper::~ScopedPerfEventHelper()
|
||||
{
|
||||
#if !defined(ANGLE_DISABLE_PERF)
|
||||
if (perfActive())
|
||||
{
|
||||
D3DPERF_EndEvent();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
105
src/3rdparty/angle/src/common/debug.h
vendored
Normal file
105
src/3rdparty/angle/src/common/debug.h
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// debug.h: Debugging utilities.
|
||||
|
||||
#ifndef COMMON_DEBUG_H_
|
||||
#define COMMON_DEBUG_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#if !defined(TRACE_OUTPUT_FILE)
|
||||
#define TRACE_OUTPUT_FILE "debug.txt"
|
||||
#endif
|
||||
|
||||
namespace gl
|
||||
{
|
||||
// Outputs text to the debugging log
|
||||
void trace(bool traceFileDebugOnly, const char *format, ...);
|
||||
|
||||
// Returns whether D3DPERF is active.
|
||||
bool perfActive();
|
||||
|
||||
// Pairs a D3D begin event with an end event.
|
||||
class ScopedPerfEventHelper
|
||||
{
|
||||
public:
|
||||
ScopedPerfEventHelper(const char* format, ...);
|
||||
~ScopedPerfEventHelper();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper);
|
||||
};
|
||||
}
|
||||
|
||||
// A macro to output a trace of a function call and its arguments to the debugging log
|
||||
#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF)
|
||||
#define TRACE(message, ...) (void(0))
|
||||
#else
|
||||
#define TRACE(message, ...) gl::trace(true, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#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_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF)
|
||||
#define FIXME(message, ...) (void(0))
|
||||
#else
|
||||
#define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// A macro to output a function call and its arguments to the debugging log, in case of error.
|
||||
#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF)
|
||||
#define ERR(message, ...) (void(0))
|
||||
#else
|
||||
#define ERR(message, ...) gl::trace(false, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// A macro to log a performance event around a scope.
|
||||
#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF)
|
||||
#define EVENT(message, ...) (void(0))
|
||||
#elif defined(_MSC_VER)
|
||||
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__(__FUNCTION__ message "\n", __VA_ARGS__);
|
||||
#else
|
||||
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper(message "\n", ##__VA_ARGS__);
|
||||
#endif
|
||||
|
||||
// A macro asserting a condition and outputting failures to the debug log
|
||||
#if !defined(NDEBUG)
|
||||
#define ASSERT(expression) do { \
|
||||
if(!(expression)) \
|
||||
ERR("\t! Assert failed in %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \
|
||||
assert(expression); \
|
||||
} while(0)
|
||||
#else
|
||||
#define ASSERT(expression) (void(0))
|
||||
#endif
|
||||
|
||||
// A macro to indicate unimplemented functionality
|
||||
#if !defined(NDEBUG)
|
||||
#define UNIMPLEMENTED() do { \
|
||||
FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \
|
||||
assert(false); \
|
||||
} while(0)
|
||||
#else
|
||||
#define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__)
|
||||
#endif
|
||||
|
||||
// A macro for code which is not expected to be reached under valid assumptions
|
||||
#if !defined(NDEBUG)
|
||||
#define UNREACHABLE() do { \
|
||||
ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \
|
||||
assert(false); \
|
||||
} while(0)
|
||||
#else
|
||||
#define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__)
|
||||
#endif
|
||||
|
||||
// A macro functioning as a compile-time assert to validate constant conditions
|
||||
#define META_ASSERT(condition) typedef int COMPILE_TIME_ASSERT_##__LINE__[static_cast<bool>(condition)?1:-1]
|
||||
|
||||
#endif // COMMON_DEBUG_H_
|
10
src/3rdparty/angle/src/common/version.h
vendored
Normal file
10
src/3rdparty/angle/src/common/version.h
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
#define MAJOR_VERSION 1
|
||||
#define MINOR_VERSION 0
|
||||
#define BUILD_VERSION 0
|
||||
#define BUILD_REVISION 1318
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define MACRO_STRINGIFY(x) STRINGIFY(x)
|
||||
|
||||
#define REVISION_STRING MACRO_STRINGIFY(BUILD_REVISION)
|
||||
#define VERSION_STRING MACRO_STRINGIFY(MAJOR_VERSION) "." MACRO_STRINGIFY(MINOR_VERSION) "." MACRO_STRINGIFY(BUILD_VERSION) "." MACRO_STRINGIFY(BUILD_REVISION)
|
152
src/3rdparty/angle/src/compiler/BaseTypes.h
vendored
Normal file
152
src/3rdparty/angle/src/compiler/BaseTypes.h
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef _BASICTYPES_INCLUDED_
|
||||
#define _BASICTYPES_INCLUDED_
|
||||
|
||||
//
|
||||
// Precision qualifiers
|
||||
//
|
||||
enum TPrecision
|
||||
{
|
||||
// These need to be kept sorted
|
||||
EbpUndefined,
|
||||
EbpLow,
|
||||
EbpMedium,
|
||||
EbpHigh,
|
||||
};
|
||||
|
||||
inline const char* getPrecisionString(TPrecision p)
|
||||
{
|
||||
switch(p)
|
||||
{
|
||||
case EbpHigh: return "highp"; break;
|
||||
case EbpMedium: return "mediump"; break;
|
||||
case EbpLow: return "lowp"; break;
|
||||
default: return "mediump"; break; // Safest fallback
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Basic type. Arrays, vectors, etc., are orthogonal to this.
|
||||
//
|
||||
enum TBasicType
|
||||
{
|
||||
EbtVoid,
|
||||
EbtFloat,
|
||||
EbtInt,
|
||||
EbtBool,
|
||||
EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
|
||||
EbtSampler2D,
|
||||
EbtSamplerCube,
|
||||
EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists.
|
||||
EbtSampler2DRect, // Only valid if GL_ARB_texture_rectangle exists.
|
||||
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
|
||||
EbtStruct,
|
||||
EbtAddress, // should be deprecated??
|
||||
EbtInvariant, // used as a type when qualifying a previously declared variable as being invariant
|
||||
};
|
||||
|
||||
inline const char* getBasicString(TBasicType t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case EbtVoid: return "void"; break;
|
||||
case EbtFloat: return "float"; break;
|
||||
case EbtInt: return "int"; break;
|
||||
case EbtBool: return "bool"; break;
|
||||
case EbtSampler2D: return "sampler2D"; break;
|
||||
case EbtSamplerCube: return "samplerCube"; break;
|
||||
case EbtSamplerExternalOES: return "samplerExternalOES"; break;
|
||||
case EbtSampler2DRect: return "sampler2DRect"; break;
|
||||
case EbtStruct: return "structure"; break;
|
||||
default: return "unknown type";
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IsSampler(TBasicType type)
|
||||
{
|
||||
return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
|
||||
}
|
||||
|
||||
//
|
||||
// Qualifiers and built-ins. These are mainly used to see what can be read
|
||||
// or written, and by the machine dependent translator to know which registers
|
||||
// to allocate variables in. Since built-ins tend to go to different registers
|
||||
// than varying or uniform, it makes sense they are peers, not sub-classes.
|
||||
//
|
||||
enum TQualifier
|
||||
{
|
||||
EvqTemporary, // For temporaries (within a function), read/write
|
||||
EvqGlobal, // For globals read/write
|
||||
EvqConst, // User defined constants and non-output parameters in functions
|
||||
EvqAttribute, // Readonly
|
||||
EvqVaryingIn, // readonly, fragment shaders only
|
||||
EvqVaryingOut, // vertex shaders only read/write
|
||||
EvqInvariantVaryingIn, // readonly, fragment shaders only
|
||||
EvqInvariantVaryingOut, // vertex shaders only read/write
|
||||
EvqUniform, // Readonly, vertex and fragment
|
||||
|
||||
// pack/unpack input and output
|
||||
EvqInput,
|
||||
EvqOutput,
|
||||
|
||||
// parameters
|
||||
EvqIn,
|
||||
EvqOut,
|
||||
EvqInOut,
|
||||
EvqConstReadOnly,
|
||||
|
||||
// built-ins written by vertex shader
|
||||
EvqPosition,
|
||||
EvqPointSize,
|
||||
|
||||
// built-ins read by fragment shader
|
||||
EvqFragCoord,
|
||||
EvqFrontFacing,
|
||||
EvqPointCoord,
|
||||
|
||||
// built-ins written by fragment shader
|
||||
EvqFragColor,
|
||||
EvqFragData,
|
||||
|
||||
// end of list
|
||||
EvqLast,
|
||||
};
|
||||
|
||||
//
|
||||
// This is just for debug print out, carried along with the definitions above.
|
||||
//
|
||||
inline const char* getQualifierString(TQualifier q)
|
||||
{
|
||||
switch(q)
|
||||
{
|
||||
case EvqTemporary: return "Temporary"; break;
|
||||
case EvqGlobal: return "Global"; break;
|
||||
case EvqConst: return "const"; break;
|
||||
case EvqConstReadOnly: return "const"; break;
|
||||
case EvqAttribute: return "attribute"; break;
|
||||
case EvqVaryingIn: return "varying"; break;
|
||||
case EvqVaryingOut: return "varying"; break;
|
||||
case EvqInvariantVaryingIn: return "invariant varying"; break;
|
||||
case EvqInvariantVaryingOut:return "invariant varying"; break;
|
||||
case EvqUniform: return "uniform"; break;
|
||||
case EvqIn: return "in"; break;
|
||||
case EvqOut: return "out"; break;
|
||||
case EvqInOut: return "inout"; break;
|
||||
case EvqInput: return "input"; break;
|
||||
case EvqOutput: return "output"; break;
|
||||
case EvqPosition: return "Position"; break;
|
||||
case EvqPointSize: return "PointSize"; break;
|
||||
case EvqFragCoord: return "FragCoord"; break;
|
||||
case EvqFrontFacing: return "FrontFacing"; break;
|
||||
case EvqFragColor: return "FragColor"; break;
|
||||
case EvqFragData: return "FragData"; break;
|
||||
default: return "unknown qualifier";
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _BASICTYPES_INCLUDED_
|
406
src/3rdparty/angle/src/compiler/BuiltInFunctionEmulator.cpp
vendored
Normal file
406
src/3rdparty/angle/src/compiler/BuiltInFunctionEmulator.cpp
vendored
Normal file
@ -0,0 +1,406 @@
|
||||
//
|
||||
// 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 "compiler/BuiltInFunctionEmulator.h"
|
||||
|
||||
#include "compiler/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:
|
||||
BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator& emulator)
|
||||
: mEmulator(emulator)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool visitUnary(Visit visit, TIntermUnary* node)
|
||||
{
|
||||
if (visit == PreVisit) {
|
||||
bool needToEmulate = mEmulator.SetFunctionCalled(
|
||||
node->getOp(), node->getOperand()->getType());
|
||||
if (needToEmulate)
|
||||
node->setUseEmulatedFunction();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool visitAggregate(Visit visit, TIntermAggregate* node)
|
||||
{
|
||||
if (visit == PreVisit) {
|
||||
// Here we handle all the built-in functions instead of the ones we
|
||||
// currently identified as problematic.
|
||||
switch (node->getOp()) {
|
||||
case EOpLessThan:
|
||||
case EOpGreaterThan:
|
||||
case EOpLessThanEqual:
|
||||
case EOpGreaterThanEqual:
|
||||
case EOpVectorEqual:
|
||||
case EOpVectorNotEqual:
|
||||
case EOpMod:
|
||||
case EOpPow:
|
||||
case EOpAtan:
|
||||
case EOpMin:
|
||||
case EOpMax:
|
||||
case EOpClamp:
|
||||
case EOpMix:
|
||||
case EOpStep:
|
||||
case EOpSmoothStep:
|
||||
case EOpDistance:
|
||||
case EOpDot:
|
||||
case EOpCross:
|
||||
case EOpFaceForward:
|
||||
case EOpReflect:
|
||||
case EOpRefract:
|
||||
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)
|
||||
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:
|
||||
BuiltInFunctionEmulator& mEmulator;
|
||||
};
|
||||
|
||||
} // anonymous namepsace
|
||||
|
||||
BuiltInFunctionEmulator::BuiltInFunctionEmulator(ShShaderType shaderType)
|
||||
{
|
||||
if (shaderType == SH_FRAGMENT_SHADER) {
|
||||
mFunctionMask = kFunctionEmulationFragmentMask;
|
||||
mFunctionSource = kFunctionEmulationFragmentSource;
|
||||
} else {
|
||||
mFunctionMask = kFunctionEmulationVertexMask;
|
||||
mFunctionSource = kFunctionEmulationVertexSource;
|
||||
}
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
TOperator op, const TType& param)
|
||||
{
|
||||
TBuiltInFunction function = IdentifyFunction(op, param);
|
||||
return SetFunctionCalled(function);
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2)
|
||||
{
|
||||
TBuiltInFunction function = IdentifyFunction(op, param1, param2);
|
||||
return SetFunctionCalled(function);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
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)
|
||||
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.isVector() != param2.isVector() ||
|
||||
param1.getNominalSize() != param2.getNominalSize() ||
|
||||
param1.getNominalSize() > 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);
|
||||
}
|
||||
|
||||
void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
|
||||
TIntermNode* root)
|
||||
{
|
||||
ASSERT(root);
|
||||
|
||||
BuiltInFunctionEmulationMarker marker(*this);
|
||||
root->traverse(&marker);
|
||||
}
|
||||
|
||||
void BuiltInFunctionEmulator::Cleanup()
|
||||
{
|
||||
mFunctions.clear();
|
||||
}
|
||||
|
||||
//static
|
||||
TString BuiltInFunctionEmulator::GetEmulatedFunctionName(
|
||||
const TString& name)
|
||||
{
|
||||
ASSERT(name[name.length() - 1] == '(');
|
||||
return "webgl_" + name.substr(0, name.length() - 1) + "_emu(";
|
||||
}
|
||||
|
93
src/3rdparty/angle/src/compiler/BuiltInFunctionEmulator.h
vendored
Normal file
93
src/3rdparty/angle/src/compiler/BuiltInFunctionEmulator.h
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
//
|
||||
// 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 COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
|
||||
#define COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
class BuiltInFunctionEmulator {
|
||||
public:
|
||||
BuiltInFunctionEmulator(ShShaderType 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;
|
||||
|
||||
void MarkBuiltInFunctionsForEmulation(TIntermNode* root);
|
||||
|
||||
void Cleanup();
|
||||
|
||||
// "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);
|
||||
|
||||
TFunctionDistance1_1, // float distance(float, float);
|
||||
TFunctionDistance2_2, // vec2 distance(vec2, vec2);
|
||||
TFunctionDistance3_3, // vec3 distance(vec3, vec3);
|
||||
TFunctionDistance4_4, // vec4 distance(vec4, vec4);
|
||||
|
||||
TFunctionDot1_1, // float dot(float, float);
|
||||
TFunctionDot2_2, // vec2 dot(vec2, vec2);
|
||||
TFunctionDot3_3, // vec3 dot(vec3, vec3);
|
||||
TFunctionDot4_4, // vec4 dot(vec4, vec4);
|
||||
|
||||
TFunctionLength1, // float length(float);
|
||||
TFunctionLength2, // float length(vec2);
|
||||
TFunctionLength3, // float length(vec3);
|
||||
TFunctionLength4, // float length(vec4);
|
||||
|
||||
TFunctionNormalize1, // float normalize(float);
|
||||
TFunctionNormalize2, // vec2 normalize(vec2);
|
||||
TFunctionNormalize3, // vec3 normalize(vec3);
|
||||
TFunctionNormalize4, // vec4 normalize(vec4);
|
||||
|
||||
TFunctionReflect1_1, // float reflect(float, float);
|
||||
TFunctionReflect2_2, // vec2 reflect(vec2, vec2);
|
||||
TFunctionReflect3_3, // vec3 reflect(vec3, vec3);
|
||||
TFunctionReflect4_4, // vec4 reflect(vec4, vec4);
|
||||
|
||||
TFunctionUnknown
|
||||
};
|
||||
|
||||
TBuiltInFunction IdentifyFunction(TOperator op, const TType& param);
|
||||
TBuiltInFunction IdentifyFunction(
|
||||
TOperator op, const TType& param1, const TType& param2);
|
||||
|
||||
bool SetFunctionCalled(TBuiltInFunction function);
|
||||
|
||||
std::vector<TBuiltInFunction> mFunctions;
|
||||
|
||||
const bool* mFunctionMask; // a boolean flag for each function.
|
||||
const char** mFunctionSource;
|
||||
};
|
||||
|
||||
#endif // COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
|
34
src/3rdparty/angle/src/compiler/CodeGenGLSL.cpp
vendored
Normal file
34
src/3rdparty/angle/src/compiler/CodeGenGLSL.cpp
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/TranslatorGLSL.h"
|
||||
#include "compiler/TranslatorESSL.h"
|
||||
|
||||
//
|
||||
// This function must be provided to create the actual
|
||||
// compile object used by higher level code. It returns
|
||||
// a subclass of TCompiler.
|
||||
//
|
||||
TCompiler* ConstructCompiler(
|
||||
ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
|
||||
{
|
||||
switch (output) {
|
||||
case SH_GLSL_OUTPUT:
|
||||
return new TranslatorGLSL(type, spec);
|
||||
case SH_ESSL_OUTPUT:
|
||||
return new TranslatorESSL(type, spec);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Delete the compiler made by ConstructCompiler
|
||||
//
|
||||
void DeleteCompiler(TCompiler* compiler)
|
||||
{
|
||||
delete compiler;
|
||||
}
|
31
src/3rdparty/angle/src/compiler/CodeGenHLSL.cpp
vendored
Normal file
31
src/3rdparty/angle/src/compiler/CodeGenHLSL.cpp
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/TranslatorHLSL.h"
|
||||
|
||||
//
|
||||
// This function must be provided to create the actual
|
||||
// compile object used by higher level code. It returns
|
||||
// a subclass of TCompiler.
|
||||
//
|
||||
TCompiler* ConstructCompiler(
|
||||
ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
|
||||
{
|
||||
switch (output) {
|
||||
case SH_HLSL_OUTPUT:
|
||||
return new TranslatorHLSL(type, spec);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Delete the compiler made by ConstructCompiler
|
||||
//
|
||||
void DeleteCompiler(TCompiler* compiler)
|
||||
{
|
||||
delete compiler;
|
||||
}
|
89
src/3rdparty/angle/src/compiler/Common.h
vendored
Normal file
89
src/3rdparty/angle/src/compiler/Common.h
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef _COMMON_INCLUDED_
|
||||
#define _COMMON_INCLUDED_
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "compiler/PoolAlloc.h"
|
||||
|
||||
// We need two pieces of information to report errors/warnings - string and
|
||||
// line number. We encode these into a single int so that it can be easily
|
||||
// incremented/decremented by lexer. The right SOURCE_LOC_LINE_SIZE bits store
|
||||
// line number while the rest store the string number. Since the shaders are
|
||||
// usually small, we should not run out of memory. SOURCE_LOC_LINE_SIZE
|
||||
// can be increased to alleviate this issue.
|
||||
typedef int TSourceLoc;
|
||||
const unsigned int SOURCE_LOC_LINE_SIZE = 16; // in bits.
|
||||
const unsigned int SOURCE_LOC_LINE_MASK = (1 << SOURCE_LOC_LINE_SIZE) - 1;
|
||||
|
||||
inline TSourceLoc EncodeSourceLoc(int string, int line) {
|
||||
return (string << SOURCE_LOC_LINE_SIZE) | (line & SOURCE_LOC_LINE_MASK);
|
||||
}
|
||||
|
||||
inline void DecodeSourceLoc(TSourceLoc loc, int* string, int* line) {
|
||||
if (string) *string = loc >> SOURCE_LOC_LINE_SIZE;
|
||||
if (line) *line = loc & SOURCE_LOC_LINE_MASK;
|
||||
}
|
||||
|
||||
//
|
||||
// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
|
||||
//
|
||||
#define POOL_ALLOCATOR_NEW_DELETE(A) \
|
||||
void* operator new(size_t s) { return (A).allocate(s); } \
|
||||
void* operator new(size_t, void *_Where) { return (_Where); } \
|
||||
void operator delete(void*) { } \
|
||||
void operator delete(void *, void *) { } \
|
||||
void* operator new[](size_t s) { return (A).allocate(s); } \
|
||||
void* operator new[](size_t, void *_Where) { return (_Where); } \
|
||||
void operator delete[](void*) { } \
|
||||
void operator delete[](void *, void *) { }
|
||||
|
||||
//
|
||||
// Pool version of string.
|
||||
//
|
||||
typedef pool_allocator<char> TStringAllocator;
|
||||
typedef std::basic_string <char, std::char_traits<char>, TStringAllocator> TString;
|
||||
typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
|
||||
inline TString* NewPoolTString(const char* s)
|
||||
{
|
||||
void* memory = GlobalPoolAllocator.allocate(sizeof(TString));
|
||||
return new(memory) TString(s);
|
||||
}
|
||||
|
||||
//
|
||||
// Persistent string memory. Should only be used for strings that survive
|
||||
// across compiles.
|
||||
//
|
||||
#define TPersistString std::string
|
||||
#define TPersistStringStream std::ostringstream
|
||||
|
||||
//
|
||||
// Pool allocator versions of vectors, lists, and maps
|
||||
//
|
||||
template <class T> class TVector : public std::vector<T, pool_allocator<T> > {
|
||||
public:
|
||||
typedef typename std::vector<T, pool_allocator<T> >::size_type size_type;
|
||||
TVector() : std::vector<T, pool_allocator<T> >() {}
|
||||
TVector(const pool_allocator<T>& a) : std::vector<T, pool_allocator<T> >(a) {}
|
||||
TVector(size_type i): std::vector<T, pool_allocator<T> >(i) {}
|
||||
};
|
||||
|
||||
template <class K, class D, class CMP = std::less<K> >
|
||||
class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<const K, D> > > {
|
||||
public:
|
||||
typedef pool_allocator<std::pair<const K, D> > tAllocator;
|
||||
|
||||
TMap() : std::map<K, D, CMP, tAllocator>() {}
|
||||
// use correct two-stage name lookup supported in gcc 3.4 and above
|
||||
TMap(const tAllocator& a) : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a) {}
|
||||
};
|
||||
|
||||
#endif // _COMMON_INCLUDED_
|
350
src/3rdparty/angle/src/compiler/Compiler.cpp
vendored
Normal file
350
src/3rdparty/angle/src/compiler/Compiler.cpp
vendored
Normal file
@ -0,0 +1,350 @@
|
||||
//
|
||||
// Copyright (c) 2002-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 "compiler/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/DetectRecursion.h"
|
||||
#include "compiler/ForLoopUnroll.h"
|
||||
#include "compiler/Initialize.h"
|
||||
#include "compiler/InitializeParseContext.h"
|
||||
#include "compiler/MapLongVariableNames.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
#include "compiler/RenameFunction.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/ValidateLimitations.h"
|
||||
#include "compiler/VariablePacker.h"
|
||||
#include "compiler/depgraph/DependencyGraph.h"
|
||||
#include "compiler/depgraph/DependencyGraphOutput.h"
|
||||
#include "compiler/timing/RestrictFragmentShaderTiming.h"
|
||||
#include "compiler/timing/RestrictVertexShaderTiming.h"
|
||||
|
||||
bool isWebGLBasedSpec(ShShaderSpec spec)
|
||||
{
|
||||
return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool InitializeSymbolTable(
|
||||
const TBuiltInStrings& builtInStrings,
|
||||
ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
|
||||
TInfoSink& infoSink, TSymbolTable& symbolTable)
|
||||
{
|
||||
TIntermediate intermediate(infoSink);
|
||||
TExtensionBehavior extBehavior;
|
||||
InitExtensionBehavior(resources, extBehavior);
|
||||
// The builtins deliberately don't specify precisions for the function
|
||||
// arguments and return types. For that reason we don't try to check them.
|
||||
TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink);
|
||||
|
||||
GlobalParseContext = &parseContext;
|
||||
|
||||
assert(symbolTable.isEmpty());
|
||||
//
|
||||
// Parse the built-ins. This should only happen once per
|
||||
// language symbol table.
|
||||
//
|
||||
// Push the symbol table to give it an initial scope. This
|
||||
// push should not have a corresponding pop, so that built-ins
|
||||
// are preserved, and the test for an empty table fails.
|
||||
//
|
||||
symbolTable.push();
|
||||
|
||||
for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
|
||||
{
|
||||
const char* builtInShaders = i->c_str();
|
||||
int builtInLengths = static_cast<int>(i->size());
|
||||
if (builtInLengths <= 0)
|
||||
continue;
|
||||
|
||||
if (PaParseStrings(1, &builtInShaders, &builtInLengths, &parseContext) != 0)
|
||||
{
|
||||
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
IdentifyBuiltIns(type, spec, resources, symbolTable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class TScopedPoolAllocator {
|
||||
public:
|
||||
TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop)
|
||||
: mAllocator(allocator), mPushPopAllocator(pushPop) {
|
||||
if (mPushPopAllocator) mAllocator->push();
|
||||
SetGlobalPoolAllocator(mAllocator);
|
||||
}
|
||||
~TScopedPoolAllocator() {
|
||||
SetGlobalPoolAllocator(NULL);
|
||||
if (mPushPopAllocator) mAllocator->pop();
|
||||
}
|
||||
|
||||
private:
|
||||
TPoolAllocator* mAllocator;
|
||||
bool mPushPopAllocator;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TShHandleBase::TShHandleBase() {
|
||||
allocator.push();
|
||||
SetGlobalPoolAllocator(&allocator);
|
||||
}
|
||||
|
||||
TShHandleBase::~TShHandleBase() {
|
||||
SetGlobalPoolAllocator(NULL);
|
||||
allocator.popAll();
|
||||
}
|
||||
|
||||
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
|
||||
: shaderType(type),
|
||||
shaderSpec(spec),
|
||||
builtInFunctionEmulator(type)
|
||||
{
|
||||
longNameMap = LongNameMap::GetInstance();
|
||||
}
|
||||
|
||||
TCompiler::~TCompiler()
|
||||
{
|
||||
ASSERT(longNameMap);
|
||||
longNameMap->Release();
|
||||
}
|
||||
|
||||
bool TCompiler::Init(const ShBuiltInResources& resources)
|
||||
{
|
||||
maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
|
||||
resources.MaxVertexUniformVectors :
|
||||
resources.MaxFragmentUniformVectors;
|
||||
TScopedPoolAllocator scopedAlloc(&allocator, false);
|
||||
|
||||
// Generate built-in symbol table.
|
||||
if (!InitBuiltInSymbolTable(resources))
|
||||
return false;
|
||||
InitExtensionBehavior(resources, extensionBehavior);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TCompiler::compile(const char* const shaderStrings[],
|
||||
const int numStrings,
|
||||
int compileOptions)
|
||||
{
|
||||
TScopedPoolAllocator scopedAlloc(&allocator, true);
|
||||
clearResults();
|
||||
|
||||
if (numStrings == 0)
|
||||
return true;
|
||||
|
||||
// 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;
|
||||
int firstSource = 0;
|
||||
if (compileOptions & SH_SOURCE_PATH)
|
||||
{
|
||||
sourcePath = shaderStrings[0];
|
||||
++firstSource;
|
||||
}
|
||||
|
||||
TIntermediate intermediate(infoSink);
|
||||
TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
|
||||
shaderType, shaderSpec, compileOptions, true,
|
||||
sourcePath, infoSink);
|
||||
GlobalParseContext = &parseContext;
|
||||
|
||||
// We preserve symbols at the built-in level from compile-to-compile.
|
||||
// Start pushing the user-defined symbols at global level.
|
||||
symbolTable.push();
|
||||
if (!symbolTable.atGlobalLevel())
|
||||
infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
|
||||
|
||||
// Parse shader.
|
||||
bool success =
|
||||
(PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
|
||||
(parseContext.treeRoot != NULL);
|
||||
if (success) {
|
||||
TIntermNode* root = parseContext.treeRoot;
|
||||
success = intermediate.postProcess(root);
|
||||
|
||||
if (success)
|
||||
success = detectRecursion(root);
|
||||
|
||||
if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
|
||||
success = validateLimitations(root);
|
||||
|
||||
if (success && (compileOptions & SH_TIMING_RESTRICTIONS))
|
||||
success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0);
|
||||
|
||||
if (success && shaderSpec == SH_CSS_SHADERS_SPEC)
|
||||
rewriteCSSShader(root);
|
||||
|
||||
// Unroll for-loop markup needs to happen after validateLimitations pass.
|
||||
if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
|
||||
ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root);
|
||||
|
||||
// Built-in function emulation needs to happen after validateLimitations pass.
|
||||
if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
|
||||
builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
|
||||
|
||||
// Call mapLongVariableNames() before collectAttribsUniforms() so in
|
||||
// collectAttribsUniforms() we already have the mapped symbol names and
|
||||
// we could composite mapped and original variable names.
|
||||
if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES))
|
||||
mapLongVariableNames(root);
|
||||
|
||||
if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) {
|
||||
collectAttribsUniforms(root);
|
||||
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
|
||||
success = enforcePackingRestrictions();
|
||||
if (!success) {
|
||||
infoSink.info.message(EPrefixError, "too many uniforms");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success && (compileOptions & SH_INTERMEDIATE_TREE))
|
||||
intermediate.outputTree(root);
|
||||
|
||||
if (success && (compileOptions & SH_OBJECT_CODE))
|
||||
translate(root);
|
||||
}
|
||||
|
||||
// Cleanup memory.
|
||||
intermediate.remove(parseContext.treeRoot);
|
||||
// Ensure symbol table is returned to the built-in level,
|
||||
// throwing away all but the built-ins.
|
||||
while (!symbolTable.atBuiltInLevel())
|
||||
symbolTable.pop();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
|
||||
{
|
||||
TBuiltIns builtIns;
|
||||
|
||||
builtIns.initialize(shaderType, shaderSpec, resources);
|
||||
return InitializeSymbolTable(builtIns.getBuiltInStrings(),
|
||||
shaderType, shaderSpec, resources, infoSink, symbolTable);
|
||||
}
|
||||
|
||||
void TCompiler::clearResults()
|
||||
{
|
||||
infoSink.info.erase();
|
||||
infoSink.obj.erase();
|
||||
infoSink.debug.erase();
|
||||
|
||||
attribs.clear();
|
||||
uniforms.clear();
|
||||
|
||||
builtInFunctionEmulator.Cleanup();
|
||||
}
|
||||
|
||||
bool TCompiler::detectRecursion(TIntermNode* root)
|
||||
{
|
||||
DetectRecursion detect;
|
||||
root->traverse(&detect);
|
||||
switch (detect.detectRecursion()) {
|
||||
case DetectRecursion::kErrorNone:
|
||||
return true;
|
||||
case DetectRecursion::kErrorMissingMain:
|
||||
infoSink.info.message(EPrefixError, "Missing main()");
|
||||
return false;
|
||||
case DetectRecursion::kErrorRecursion:
|
||||
infoSink.info.message(EPrefixError, "Function recursion detected");
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void TCompiler::rewriteCSSShader(TIntermNode* root)
|
||||
{
|
||||
RenameFunction renamer("main(", "css_main(");
|
||||
root->traverse(&renamer);
|
||||
}
|
||||
|
||||
bool TCompiler::validateLimitations(TIntermNode* root) {
|
||||
ValidateLimitations validate(shaderType, infoSink.info);
|
||||
root->traverse(&validate);
|
||||
return validate.numErrors() == 0;
|
||||
}
|
||||
|
||||
bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
|
||||
{
|
||||
if (shaderSpec != SH_WEBGL_SPEC) {
|
||||
infoSink.info << "Timing restrictions must be enforced under the WebGL spec.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (shaderType == SH_FRAGMENT_SHADER) {
|
||||
TDependencyGraph graph(root);
|
||||
|
||||
// Output any errors first.
|
||||
bool success = enforceFragmentShaderTimingRestrictions(graph);
|
||||
|
||||
// Then, output the dependency graph.
|
||||
if (outputGraph) {
|
||||
TDependencyGraphOutput output(infoSink.info);
|
||||
output.outputAllSpanningTrees(graph);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
else {
|
||||
return enforceVertexShaderTimingRestrictions(root);
|
||||
}
|
||||
}
|
||||
|
||||
bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
|
||||
{
|
||||
RestrictFragmentShaderTiming restrictor(infoSink.info);
|
||||
restrictor.enforceRestrictions(graph);
|
||||
return restrictor.numErrors() == 0;
|
||||
}
|
||||
|
||||
bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
|
||||
{
|
||||
RestrictVertexShaderTiming restrictor(infoSink.info);
|
||||
restrictor.enforceRestrictions(root);
|
||||
return restrictor.numErrors() == 0;
|
||||
}
|
||||
|
||||
void TCompiler::collectAttribsUniforms(TIntermNode* root)
|
||||
{
|
||||
CollectAttribsUniforms collect(attribs, uniforms);
|
||||
root->traverse(&collect);
|
||||
}
|
||||
|
||||
bool TCompiler::enforcePackingRestrictions()
|
||||
{
|
||||
VariablePacker packer;
|
||||
return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
|
||||
}
|
||||
|
||||
void TCompiler::mapLongVariableNames(TIntermNode* root)
|
||||
{
|
||||
ASSERT(longNameMap);
|
||||
MapLongVariableNames map(longNameMap);
|
||||
root->traverse(&map);
|
||||
}
|
||||
|
||||
int TCompiler::getMappedNameMaxLength() const
|
||||
{
|
||||
return MAX_SHORTENED_IDENTIFIER_SIZE + 1;
|
||||
}
|
||||
|
||||
const TExtensionBehavior& TCompiler::getExtensionBehavior() const
|
||||
{
|
||||
return extensionBehavior;
|
||||
}
|
||||
|
||||
const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
|
||||
{
|
||||
return builtInFunctionEmulator;
|
||||
}
|
256
src/3rdparty/angle/src/compiler/ConstantUnion.h
vendored
Normal file
256
src/3rdparty/angle/src/compiler/ConstantUnion.h
vendored
Normal file
@ -0,0 +1,256 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef _CONSTANT_UNION_INCLUDED_
|
||||
#define _CONSTANT_UNION_INCLUDED_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
class ConstantUnion {
|
||||
public:
|
||||
ConstantUnion()
|
||||
{
|
||||
iConst = 0;
|
||||
}
|
||||
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
void setIConst(int i) {iConst = i; type = EbtInt; }
|
||||
void setFConst(float f) {fConst = f; type = EbtFloat; }
|
||||
void setBConst(bool b) {bConst = b; type = EbtBool; }
|
||||
|
||||
int getIConst() { return iConst; }
|
||||
float getFConst() { return fConst; }
|
||||
bool getBConst() { return bConst; }
|
||||
int getIConst() const { return iConst; }
|
||||
float getFConst() const { return fConst; }
|
||||
bool getBConst() const { return bConst; }
|
||||
|
||||
bool operator==(const int i) const
|
||||
{
|
||||
return i == iConst;
|
||||
}
|
||||
|
||||
bool operator==(const float f) const
|
||||
{
|
||||
return f == fConst;
|
||||
}
|
||||
|
||||
bool operator==(const bool b) const
|
||||
{
|
||||
return b == bConst;
|
||||
}
|
||||
|
||||
bool operator==(const ConstantUnion& constant) const
|
||||
{
|
||||
if (constant.type != type)
|
||||
return false;
|
||||
|
||||
switch (type) {
|
||||
case EbtInt:
|
||||
return constant.iConst == iConst;
|
||||
case EbtFloat:
|
||||
return constant.fConst == fConst;
|
||||
case EbtBool:
|
||||
return constant.bConst == bConst;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator!=(const int i) const
|
||||
{
|
||||
return !operator==(i);
|
||||
}
|
||||
|
||||
bool operator!=(const float f) const
|
||||
{
|
||||
return !operator==(f);
|
||||
}
|
||||
|
||||
bool operator!=(const bool b) const
|
||||
{
|
||||
return !operator==(b);
|
||||
}
|
||||
|
||||
bool operator!=(const ConstantUnion& constant) const
|
||||
{
|
||||
return !operator==(constant);
|
||||
}
|
||||
|
||||
bool operator>(const ConstantUnion& constant) const
|
||||
{
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt:
|
||||
return iConst > constant.iConst;
|
||||
case EbtFloat:
|
||||
return fConst > constant.fConst;
|
||||
default:
|
||||
return false; // Invalid operation, handled at semantic analysis
|
||||
}
|
||||
}
|
||||
|
||||
bool operator<(const ConstantUnion& constant) const
|
||||
{
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt:
|
||||
return iConst < constant.iConst;
|
||||
case EbtFloat:
|
||||
return fConst < constant.fConst;
|
||||
default:
|
||||
return false; // Invalid operation, handled at semantic analysis
|
||||
}
|
||||
}
|
||||
|
||||
ConstantUnion operator+(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
|
||||
case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConstantUnion operator-(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
|
||||
case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConstantUnion operator*(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
|
||||
case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConstantUnion operator%(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConstantUnion operator>>(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConstantUnion operator<<(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConstantUnion operator&(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConstantUnion operator|(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConstantUnion operator^(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConstantUnion operator&&(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConstantUnion operator||(const ConstantUnion& constant) const
|
||||
{
|
||||
ConstantUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TBasicType getType() const { return type; }
|
||||
private:
|
||||
|
||||
union {
|
||||
int iConst; // used for ivec, scalar ints
|
||||
bool bConst; // used for bvec, scalar bools
|
||||
float fConst; // used for vec, mat, scalar floats
|
||||
} ;
|
||||
|
||||
TBasicType type;
|
||||
};
|
||||
|
||||
#endif // _CONSTANT_UNION_INCLUDED_
|
119
src/3rdparty/angle/src/compiler/DetectDiscontinuity.cpp
vendored
Normal file
119
src/3rdparty/angle/src/compiler/DetectDiscontinuity.cpp
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Contains analysis utilities for dealing with HLSL's lack of support for
|
||||
// the use of intrinsic functions which (implicitly or explicitly) compute
|
||||
// gradients of functions with discontinuities.
|
||||
//
|
||||
|
||||
#include "compiler/DetectDiscontinuity.h"
|
||||
|
||||
#include "compiler/ParseHelper.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
|
||||
{
|
||||
mLoopDiscontinuity = false;
|
||||
node->traverse(this);
|
||||
return mLoopDiscontinuity;
|
||||
}
|
||||
|
||||
bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node)
|
||||
{
|
||||
if (mLoopDiscontinuity)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (node->getFlowOp())
|
||||
{
|
||||
case EOpKill:
|
||||
break;
|
||||
case EOpBreak:
|
||||
case EOpContinue:
|
||||
mLoopDiscontinuity = true;
|
||||
case EOpReturn:
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
|
||||
return !mLoopDiscontinuity;
|
||||
}
|
||||
|
||||
bool DetectLoopDiscontinuity::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
{
|
||||
return !mLoopDiscontinuity;
|
||||
}
|
||||
|
||||
bool containsLoopDiscontinuity(TIntermNode *node)
|
||||
{
|
||||
DetectLoopDiscontinuity detectLoopDiscontinuity;
|
||||
return detectLoopDiscontinuity.traverse(node);
|
||||
}
|
||||
|
||||
bool DetectGradientOperation::traverse(TIntermNode *node)
|
||||
{
|
||||
mGradientOperation = false;
|
||||
node->traverse(this);
|
||||
return mGradientOperation;
|
||||
}
|
||||
|
||||
bool DetectGradientOperation::visitUnary(Visit visit, TIntermUnary *node)
|
||||
{
|
||||
if (mGradientOperation)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpDFdx:
|
||||
case EOpDFdy:
|
||||
mGradientOperation = true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return !mGradientOperation;
|
||||
}
|
||||
|
||||
bool DetectGradientOperation::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
{
|
||||
if (mGradientOperation)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node->getOp() == EOpFunctionCall)
|
||||
{
|
||||
if (!node->isUserDefined())
|
||||
{
|
||||
TString name = TFunction::unmangleName(node->getName());
|
||||
|
||||
if (name == "texture2D" ||
|
||||
name == "texture2DProj" ||
|
||||
name == "textureCube")
|
||||
{
|
||||
mGradientOperation = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// When a user defined function is called, we have to
|
||||
// conservatively assume it to contain gradient operations
|
||||
mGradientOperation = true;
|
||||
}
|
||||
}
|
||||
|
||||
return !mGradientOperation;
|
||||
}
|
||||
|
||||
bool containsGradientOperation(TIntermNode *node)
|
||||
{
|
||||
DetectGradientOperation detectGradientOperation;
|
||||
return detectGradientOperation.traverse(node);
|
||||
}
|
||||
}
|
50
src/3rdparty/angle/src/compiler/DetectDiscontinuity.h
vendored
Normal file
50
src/3rdparty/angle/src/compiler/DetectDiscontinuity.h
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Contains analysis utilities for dealing with HLSL's lack of support for
|
||||
// the use of intrinsic functions which (implicitly or explicitly) compute
|
||||
// gradients of functions with discontinuities.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_DETECTDISCONTINUITY_H_
|
||||
#define COMPILER_DETECTDISCONTINUITY_H_
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
// Checks whether a loop can run for a variable number of iterations
|
||||
class DetectLoopDiscontinuity : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
bool traverse(TIntermNode *node);
|
||||
|
||||
protected:
|
||||
bool visitBranch(Visit visit, TIntermBranch *node);
|
||||
bool visitAggregate(Visit visit, TIntermAggregate *node);
|
||||
|
||||
bool mLoopDiscontinuity;
|
||||
};
|
||||
|
||||
bool containsLoopDiscontinuity(TIntermNode *node);
|
||||
|
||||
// Checks for intrinsic functions which compute gradients
|
||||
class DetectGradientOperation : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
bool traverse(TIntermNode *node);
|
||||
|
||||
protected:
|
||||
bool visitUnary(Visit visit, TIntermUnary *node);
|
||||
bool visitAggregate(Visit visit, TIntermAggregate *node);
|
||||
|
||||
bool mGradientOperation;
|
||||
};
|
||||
|
||||
bool containsGradientOperation(TIntermNode *node);
|
||||
|
||||
}
|
||||
|
||||
#endif // COMPILER_DETECTDISCONTINUITY_H_
|
125
src/3rdparty/angle/src/compiler/DetectRecursion.cpp
vendored
Normal file
125
src/3rdparty/angle/src/compiler/DetectRecursion.cpp
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
//
|
||||
// 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 "compiler/DetectRecursion.h"
|
||||
|
||||
DetectRecursion::FunctionNode::FunctionNode(const TString& fname)
|
||||
: name(fname),
|
||||
visit(PreVisit)
|
||||
{
|
||||
}
|
||||
|
||||
const TString& DetectRecursion::FunctionNode::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void DetectRecursion::FunctionNode::addCallee(
|
||||
DetectRecursion::FunctionNode* callee)
|
||||
{
|
||||
for (size_t i = 0; i < callees.size(); ++i) {
|
||||
if (callees[i] == callee)
|
||||
return;
|
||||
}
|
||||
callees.push_back(callee);
|
||||
}
|
||||
|
||||
bool DetectRecursion::FunctionNode::detectRecursion()
|
||||
{
|
||||
ASSERT(visit == PreVisit);
|
||||
visit = InVisit;
|
||||
for (size_t i = 0; i < callees.size(); ++i) {
|
||||
switch (callees[i]->visit) {
|
||||
case InVisit:
|
||||
// cycle detected, i.e., recursion detected.
|
||||
return true;
|
||||
case PostVisit:
|
||||
break;
|
||||
case PreVisit: {
|
||||
bool recursion = callees[i]->detectRecursion();
|
||||
if (recursion)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
visit = PostVisit;
|
||||
return false;
|
||||
}
|
||||
|
||||
DetectRecursion::DetectRecursion()
|
||||
: currentFunction(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
DetectRecursion::~DetectRecursion()
|
||||
{
|
||||
for (size_t i = 0; i < functions.size(); ++i)
|
||||
delete functions[i];
|
||||
}
|
||||
|
||||
bool DetectRecursion::visitAggregate(Visit visit, TIntermAggregate* node)
|
||||
{
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpPrototype:
|
||||
// Function declaration.
|
||||
// Don't add FunctionNode here because node->getName() is the
|
||||
// unmangled function name.
|
||||
break;
|
||||
case EOpFunction: {
|
||||
// Function definition.
|
||||
if (visit == PreVisit) {
|
||||
currentFunction = findFunctionByName(node->getName());
|
||||
if (currentFunction == NULL) {
|
||||
currentFunction = new FunctionNode(node->getName());
|
||||
functions.push_back(currentFunction);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EOpFunctionCall: {
|
||||
// Function call.
|
||||
if (visit == PreVisit) {
|
||||
ASSERT(currentFunction != NULL);
|
||||
FunctionNode* func = findFunctionByName(node->getName());
|
||||
if (func == NULL) {
|
||||
func = new FunctionNode(node->getName());
|
||||
functions.push_back(func);
|
||||
}
|
||||
currentFunction->addCallee(func);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DetectRecursion::ErrorCode DetectRecursion::detectRecursion()
|
||||
{
|
||||
FunctionNode* main = findFunctionByName("main(");
|
||||
if (main == NULL)
|
||||
return kErrorMissingMain;
|
||||
if (main->detectRecursion())
|
||||
return kErrorRecursion;
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DetectRecursion::FunctionNode* DetectRecursion::findFunctionByName(
|
||||
const TString& name)
|
||||
{
|
||||
for (size_t i = 0; i < functions.size(); ++i) {
|
||||
if (functions[i]->getName() == name)
|
||||
return functions[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
60
src/3rdparty/angle/src/compiler/DetectRecursion.h
vendored
Normal file
60
src/3rdparty/angle/src/compiler/DetectRecursion.h
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_DETECT_RECURSION_H_
|
||||
#define COMPILER_DETECT_RECURSION_H_
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
#include "compiler/VariableInfo.h"
|
||||
|
||||
// Traverses intermediate tree to detect function recursion.
|
||||
class DetectRecursion : public TIntermTraverser {
|
||||
public:
|
||||
enum ErrorCode {
|
||||
kErrorMissingMain,
|
||||
kErrorRecursion,
|
||||
kErrorNone
|
||||
};
|
||||
|
||||
DetectRecursion();
|
||||
~DetectRecursion();
|
||||
|
||||
virtual bool visitAggregate(Visit, TIntermAggregate*);
|
||||
|
||||
ErrorCode detectRecursion();
|
||||
|
||||
private:
|
||||
class FunctionNode {
|
||||
public:
|
||||
FunctionNode(const TString& fname);
|
||||
|
||||
const TString& getName() const;
|
||||
|
||||
// If a function is already in the callee list, this becomes a no-op.
|
||||
void addCallee(FunctionNode* callee);
|
||||
|
||||
// Return true if recursive function calls are detected.
|
||||
bool detectRecursion();
|
||||
|
||||
private:
|
||||
// mangled function name is unique.
|
||||
TString name;
|
||||
|
||||
// functions that are directly called by this function.
|
||||
TVector<FunctionNode*> callees;
|
||||
|
||||
Visit visit;
|
||||
};
|
||||
|
||||
FunctionNode* findFunctionByName(const TString& name);
|
||||
|
||||
TVector<FunctionNode*> functions;
|
||||
FunctionNode* currentFunction;
|
||||
};
|
||||
|
||||
#endif // COMPILER_DETECT_RECURSION_H_
|
63
src/3rdparty/angle/src/compiler/Diagnostics.cpp
vendored
Normal file
63
src/3rdparty/angle/src/compiler/Diagnostics.cpp
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// 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 "compiler/Diagnostics.h"
|
||||
|
||||
#include "compiler/debug.h"
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/preprocessor/new/SourceLocation.h"
|
||||
|
||||
TDiagnostics::TDiagnostics(TInfoSink& infoSink) :
|
||||
mInfoSink(infoSink),
|
||||
mNumErrors(0),
|
||||
mNumWarnings(0)
|
||||
{
|
||||
}
|
||||
|
||||
TDiagnostics::~TDiagnostics()
|
||||
{
|
||||
}
|
||||
|
||||
void TDiagnostics::writeInfo(Severity severity,
|
||||
const pp::SourceLocation& loc,
|
||||
const std::string& reason,
|
||||
const std::string& token,
|
||||
const std::string& extra)
|
||||
{
|
||||
TPrefixType prefix = EPrefixNone;
|
||||
switch (severity)
|
||||
{
|
||||
case ERROR:
|
||||
++mNumErrors;
|
||||
prefix = EPrefixError;
|
||||
break;
|
||||
case WARNING:
|
||||
++mNumWarnings;
|
||||
prefix = EPrefixWarning;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
TInfoSinkBase& sink = mInfoSink.info;
|
||||
/* VC++ format: file(linenum) : error #: 'token' : extrainfo */
|
||||
sink.prefix(prefix);
|
||||
sink.location(EncodeSourceLoc(loc.file, loc.line));
|
||||
sink << "'" << token << "' : " << reason << " " << extra << "\n";
|
||||
}
|
||||
|
||||
void TDiagnostics::writeDebug(const std::string& str)
|
||||
{
|
||||
mInfoSink.debug << str;
|
||||
}
|
||||
|
||||
void TDiagnostics::print(ID id,
|
||||
const pp::SourceLocation& loc,
|
||||
const std::string& text)
|
||||
{
|
||||
writeInfo(severity(id), loc, message(id), text, "");
|
||||
}
|
44
src/3rdparty/angle/src/compiler/Diagnostics.h
vendored
Normal file
44
src/3rdparty/angle/src/compiler/Diagnostics.h
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// 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 COMPILER_DIAGNOSTICS_H_
|
||||
#define COMPILER_DIAGNOSTICS_H_
|
||||
|
||||
#include "compiler/preprocessor/new/Diagnostics.h"
|
||||
|
||||
class TInfoSink;
|
||||
|
||||
class TDiagnostics : public pp::Diagnostics
|
||||
{
|
||||
public:
|
||||
TDiagnostics(TInfoSink& infoSink);
|
||||
virtual ~TDiagnostics();
|
||||
|
||||
TInfoSink& infoSink() { return mInfoSink; }
|
||||
|
||||
int numErrors() const { return mNumErrors; }
|
||||
int numWarnings() const { return mNumWarnings; }
|
||||
|
||||
void writeInfo(Severity severity,
|
||||
const pp::SourceLocation& loc,
|
||||
const std::string& reason,
|
||||
const std::string& token,
|
||||
const std::string& extra);
|
||||
|
||||
void writeDebug(const std::string& str);
|
||||
|
||||
protected:
|
||||
virtual void print(ID id,
|
||||
const pp::SourceLocation& loc,
|
||||
const std::string& text);
|
||||
|
||||
private:
|
||||
TInfoSink& mInfoSink;
|
||||
int mNumErrors;
|
||||
int mNumWarnings;
|
||||
};
|
||||
|
||||
#endif // COMPILER_DIAGNOSTICS_H_
|
161
src/3rdparty/angle/src/compiler/DirectiveHandler.cpp
vendored
Normal file
161
src/3rdparty/angle/src/compiler/DirectiveHandler.cpp
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
//
|
||||
// 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 "compiler/DirectiveHandler.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "compiler/debug.h"
|
||||
#include "compiler/Diagnostics.h"
|
||||
|
||||
static TBehavior getBehavior(const std::string& str)
|
||||
{
|
||||
static const std::string kRequire("require");
|
||||
static const std::string kEnable("enable");
|
||||
static const std::string kDisable("disable");
|
||||
static const std::string kWarn("warn");
|
||||
|
||||
if (str == kRequire) return EBhRequire;
|
||||
else if (str == kEnable) return EBhEnable;
|
||||
else if (str == kDisable) return EBhDisable;
|
||||
else if (str == kWarn) return EBhWarn;
|
||||
return EBhUndefined;
|
||||
}
|
||||
|
||||
TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
|
||||
TDiagnostics& diagnostics)
|
||||
: mExtensionBehavior(extBehavior),
|
||||
mDiagnostics(diagnostics)
|
||||
{
|
||||
}
|
||||
|
||||
TDirectiveHandler::~TDirectiveHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
|
||||
const std::string& msg)
|
||||
{
|
||||
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, msg, "", "");
|
||||
}
|
||||
|
||||
void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
const std::string& value)
|
||||
{
|
||||
static const std::string kSTDGL("STDGL");
|
||||
static const std::string kOptimize("optimize");
|
||||
static const std::string kDebug("debug");
|
||||
static const std::string kOn("on");
|
||||
static const std::string kOff("off");
|
||||
|
||||
bool invalidValue = false;
|
||||
if (name == kSTDGL)
|
||||
{
|
||||
// The STDGL pragma is used to reserve pragmas for use by future
|
||||
// revisions of GLSL. Ignore it.
|
||||
return;
|
||||
}
|
||||
else if (name == kOptimize)
|
||||
{
|
||||
if (value == kOn) mPragma.optimize = true;
|
||||
else if (value == kOff) mPragma.optimize = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else if (name == kDebug)
|
||||
{
|
||||
if (value == kOn) mPragma.debug = true;
|
||||
else if (value == kOff) mPragma.debug = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDiagnostics.report(pp::Diagnostics::UNRECOGNIZED_PRAGMA, loc, name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (invalidValue)
|
||||
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc,
|
||||
"invalid pragma value", value,
|
||||
"'on' or 'off' expected");
|
||||
}
|
||||
|
||||
void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
const std::string& behavior)
|
||||
{
|
||||
static const std::string kExtAll("all");
|
||||
|
||||
TBehavior behaviorVal = getBehavior(behavior);
|
||||
if (behaviorVal == EBhUndefined)
|
||||
{
|
||||
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc,
|
||||
"behavior", name, "invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
if (name == kExtAll)
|
||||
{
|
||||
if (behaviorVal == EBhRequire)
|
||||
{
|
||||
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc,
|
||||
"extension", name,
|
||||
"cannot have 'require' behavior");
|
||||
}
|
||||
else if (behaviorVal == EBhEnable)
|
||||
{
|
||||
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc,
|
||||
"extension", name,
|
||||
"cannot have 'enable' behavior");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
|
||||
iter != mExtensionBehavior.end(); ++iter)
|
||||
iter->second = behaviorVal;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
|
||||
if (iter != mExtensionBehavior.end())
|
||||
{
|
||||
iter->second = behaviorVal;
|
||||
return;
|
||||
}
|
||||
|
||||
pp::Diagnostics::Severity severity = pp::Diagnostics::ERROR;
|
||||
switch (behaviorVal) {
|
||||
case EBhRequire:
|
||||
severity = pp::Diagnostics::ERROR;
|
||||
break;
|
||||
case EBhEnable:
|
||||
case EBhWarn:
|
||||
case EBhDisable:
|
||||
severity = pp::Diagnostics::WARNING;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
mDiagnostics.writeInfo(severity, loc,
|
||||
"extension", name, "is not supported");
|
||||
}
|
||||
|
||||
void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
|
||||
int version)
|
||||
{
|
||||
static const int kVersion = 100;
|
||||
|
||||
if (version != kVersion)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << version;
|
||||
std::string str = stream.str();
|
||||
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc,
|
||||
"version number", str, "not supported");
|
||||
}
|
||||
}
|
46
src/3rdparty/angle/src/compiler/DirectiveHandler.h
vendored
Normal file
46
src/3rdparty/angle/src/compiler/DirectiveHandler.h
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// 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 COMPILER_DIRECTIVE_HANDLER_H_
|
||||
#define COMPILER_DIRECTIVE_HANDLER_H_
|
||||
|
||||
#include "compiler/ExtensionBehavior.h"
|
||||
#include "compiler/Pragma.h"
|
||||
#include "compiler/preprocessor/new/DirectiveHandler.h"
|
||||
|
||||
class TDiagnostics;
|
||||
|
||||
class TDirectiveHandler : public pp::DirectiveHandler
|
||||
{
|
||||
public:
|
||||
TDirectiveHandler(TExtensionBehavior& extBehavior,
|
||||
TDiagnostics& diagnostics);
|
||||
virtual ~TDirectiveHandler();
|
||||
|
||||
const TPragma& pragma() const { return mPragma; }
|
||||
const TExtensionBehavior& extensionBehavior() const { return mExtensionBehavior; }
|
||||
|
||||
virtual void handleError(const pp::SourceLocation& loc,
|
||||
const std::string& msg);
|
||||
|
||||
virtual void handlePragma(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
const std::string& value);
|
||||
|
||||
virtual void handleExtension(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
const std::string& behavior);
|
||||
|
||||
virtual void handleVersion(const pp::SourceLocation& loc,
|
||||
int version);
|
||||
|
||||
private:
|
||||
TPragma mPragma;
|
||||
TExtensionBehavior& mExtensionBehavior;
|
||||
TDiagnostics& mDiagnostics;
|
||||
};
|
||||
|
||||
#endif // COMPILER_DIRECTIVE_HANDLER_H_
|
37
src/3rdparty/angle/src/compiler/ExtensionBehavior.h
vendored
Normal file
37
src/3rdparty/angle/src/compiler/ExtensionBehavior.h
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef _EXTENSION_BEHAVIOR_INCLUDED_
|
||||
#define _EXTENSION_BEHAVIOR_INCLUDED_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EBhRequire,
|
||||
EBhEnable,
|
||||
EBhWarn,
|
||||
EBhDisable,
|
||||
EBhUndefined,
|
||||
} TBehavior;
|
||||
|
||||
inline const char* getBehaviorString(TBehavior b)
|
||||
{
|
||||
switch(b)
|
||||
{
|
||||
case EBhRequire: return "require";
|
||||
case EBhEnable: return "enable";
|
||||
case EBhWarn: return "warn";
|
||||
case EBhDisable: return "disable";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Mapping between extension name and behavior.
|
||||
typedef std::map<std::string, TBehavior> TExtensionBehavior;
|
||||
|
||||
#endif // _EXTENSION_TABLE_INCLUDED_
|
215
src/3rdparty/angle/src/compiler/ForLoopUnroll.cpp
vendored
Normal file
215
src/3rdparty/angle/src/compiler/ForLoopUnroll.cpp
vendored
Normal file
@ -0,0 +1,215 @@
|
||||
//
|
||||
// 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 "compiler/ForLoopUnroll.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class IntegerForLoopUnrollMarker : public TIntermTraverser {
|
||||
public:
|
||||
|
||||
virtual bool visitLoop(Visit, TIntermLoop* node)
|
||||
{
|
||||
// This is called after ValidateLimitations pass, so all the ASSERT
|
||||
// should never fail.
|
||||
// See ValidateLimitations::validateForLoopInit().
|
||||
ASSERT(node);
|
||||
ASSERT(node->getType() == ELoopFor);
|
||||
ASSERT(node->getInit());
|
||||
TIntermAggregate* decl = node->getInit()->getAsAggregate();
|
||||
ASSERT(decl && decl->getOp() == EOpDeclaration);
|
||||
TIntermSequence& declSeq = decl->getSequence();
|
||||
ASSERT(declSeq.size() == 1);
|
||||
TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
|
||||
ASSERT(declInit && declInit->getOp() == EOpInitialize);
|
||||
ASSERT(declInit->getLeft());
|
||||
TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
|
||||
ASSERT(symbol);
|
||||
TBasicType type = symbol->getBasicType();
|
||||
ASSERT(type == EbtInt || type == EbtFloat);
|
||||
if (type == EbtInt)
|
||||
node->setUnrollFlag(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // anonymous namepsace
|
||||
|
||||
void ForLoopUnroll::FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info)
|
||||
{
|
||||
ASSERT(node->getType() == ELoopFor);
|
||||
ASSERT(node->getUnrollFlag());
|
||||
|
||||
TIntermNode* init = node->getInit();
|
||||
ASSERT(init != NULL);
|
||||
TIntermAggregate* decl = init->getAsAggregate();
|
||||
ASSERT((decl != NULL) && (decl->getOp() == EOpDeclaration));
|
||||
TIntermSequence& declSeq = decl->getSequence();
|
||||
ASSERT(declSeq.size() == 1);
|
||||
TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
|
||||
ASSERT((declInit != NULL) && (declInit->getOp() == EOpInitialize));
|
||||
TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
|
||||
ASSERT(symbol != NULL);
|
||||
ASSERT(symbol->getBasicType() == EbtInt);
|
||||
|
||||
info.id = symbol->getId();
|
||||
|
||||
ASSERT(declInit->getRight() != NULL);
|
||||
TIntermConstantUnion* initNode = declInit->getRight()->getAsConstantUnion();
|
||||
ASSERT(initNode != NULL);
|
||||
|
||||
info.initValue = evaluateIntConstant(initNode);
|
||||
info.currentValue = info.initValue;
|
||||
|
||||
TIntermNode* cond = node->getCondition();
|
||||
ASSERT(cond != NULL);
|
||||
TIntermBinary* binOp = cond->getAsBinaryNode();
|
||||
ASSERT(binOp != NULL);
|
||||
ASSERT(binOp->getRight() != NULL);
|
||||
ASSERT(binOp->getRight()->getAsConstantUnion() != NULL);
|
||||
|
||||
info.incrementValue = getLoopIncrement(node);
|
||||
info.stopValue = evaluateIntConstant(
|
||||
binOp->getRight()->getAsConstantUnion());
|
||||
info.op = binOp->getOp();
|
||||
}
|
||||
|
||||
void ForLoopUnroll::Step()
|
||||
{
|
||||
ASSERT(mLoopIndexStack.size() > 0);
|
||||
TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1];
|
||||
info.currentValue += info.incrementValue;
|
||||
}
|
||||
|
||||
bool ForLoopUnroll::SatisfiesLoopCondition()
|
||||
{
|
||||
ASSERT(mLoopIndexStack.size() > 0);
|
||||
TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1];
|
||||
// Relational operator is one of: > >= < <= == or !=.
|
||||
switch (info.op) {
|
||||
case EOpEqual:
|
||||
return (info.currentValue == info.stopValue);
|
||||
case EOpNotEqual:
|
||||
return (info.currentValue != info.stopValue);
|
||||
case EOpLessThan:
|
||||
return (info.currentValue < info.stopValue);
|
||||
case EOpGreaterThan:
|
||||
return (info.currentValue > info.stopValue);
|
||||
case EOpLessThanEqual:
|
||||
return (info.currentValue <= info.stopValue);
|
||||
case EOpGreaterThanEqual:
|
||||
return (info.currentValue >= info.stopValue);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ForLoopUnroll::NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol)
|
||||
{
|
||||
for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin();
|
||||
i != mLoopIndexStack.end();
|
||||
++i) {
|
||||
if (i->id == symbol->getId())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ForLoopUnroll::GetLoopIndexValue(TIntermSymbol* symbol)
|
||||
{
|
||||
for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin();
|
||||
i != mLoopIndexStack.end();
|
||||
++i) {
|
||||
if (i->id == symbol->getId())
|
||||
return i->currentValue;
|
||||
}
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
|
||||
void ForLoopUnroll::Push(TLoopIndexInfo& info)
|
||||
{
|
||||
mLoopIndexStack.push_back(info);
|
||||
}
|
||||
|
||||
void ForLoopUnroll::Pop()
|
||||
{
|
||||
mLoopIndexStack.pop_back();
|
||||
}
|
||||
|
||||
// static
|
||||
void ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(
|
||||
TIntermNode* root)
|
||||
{
|
||||
ASSERT(root);
|
||||
|
||||
IntegerForLoopUnrollMarker marker;
|
||||
root->traverse(&marker);
|
||||
}
|
||||
|
||||
int ForLoopUnroll::getLoopIncrement(TIntermLoop* node)
|
||||
{
|
||||
TIntermNode* expr = node->getExpression();
|
||||
ASSERT(expr != NULL);
|
||||
// for expression has one of the following forms:
|
||||
// loop_index++
|
||||
// loop_index--
|
||||
// loop_index += constant_expression
|
||||
// loop_index -= constant_expression
|
||||
// ++loop_index
|
||||
// --loop_index
|
||||
// The last two forms are not specified in the spec, but I am assuming
|
||||
// its an oversight.
|
||||
TIntermUnary* unOp = expr->getAsUnaryNode();
|
||||
TIntermBinary* binOp = unOp ? NULL : expr->getAsBinaryNode();
|
||||
|
||||
TOperator op = EOpNull;
|
||||
TIntermConstantUnion* incrementNode = NULL;
|
||||
if (unOp != NULL) {
|
||||
op = unOp->getOp();
|
||||
} else if (binOp != NULL) {
|
||||
op = binOp->getOp();
|
||||
ASSERT(binOp->getRight() != NULL);
|
||||
incrementNode = binOp->getRight()->getAsConstantUnion();
|
||||
ASSERT(incrementNode != NULL);
|
||||
}
|
||||
|
||||
int increment = 0;
|
||||
// The operator is one of: ++ -- += -=.
|
||||
switch (op) {
|
||||
case EOpPostIncrement:
|
||||
case EOpPreIncrement:
|
||||
ASSERT((unOp != NULL) && (binOp == NULL));
|
||||
increment = 1;
|
||||
break;
|
||||
case EOpPostDecrement:
|
||||
case EOpPreDecrement:
|
||||
ASSERT((unOp != NULL) && (binOp == NULL));
|
||||
increment = -1;
|
||||
break;
|
||||
case EOpAddAssign:
|
||||
ASSERT((unOp == NULL) && (binOp != NULL));
|
||||
increment = evaluateIntConstant(incrementNode);
|
||||
break;
|
||||
case EOpSubAssign:
|
||||
ASSERT((unOp == NULL) && (binOp != NULL));
|
||||
increment = - evaluateIntConstant(incrementNode);
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
return increment;
|
||||
}
|
||||
|
||||
int ForLoopUnroll::evaluateIntConstant(TIntermConstantUnion* node)
|
||||
{
|
||||
ASSERT((node != NULL) && (node->getUnionArrayPointer() != NULL));
|
||||
return node->getUnionArrayPointer()->getIConst();
|
||||
}
|
||||
|
48
src/3rdparty/angle/src/compiler/ForLoopUnroll.h
vendored
Normal file
48
src/3rdparty/angle/src/compiler/ForLoopUnroll.h
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
struct TLoopIndexInfo {
|
||||
int id;
|
||||
int initValue;
|
||||
int stopValue;
|
||||
int incrementValue;
|
||||
TOperator op;
|
||||
int currentValue;
|
||||
};
|
||||
|
||||
class ForLoopUnroll {
|
||||
public:
|
||||
ForLoopUnroll() { }
|
||||
|
||||
void FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info);
|
||||
|
||||
// Update the info.currentValue for the next loop iteration.
|
||||
void Step();
|
||||
|
||||
// Return false if loop condition is no longer satisfied.
|
||||
bool SatisfiesLoopCondition();
|
||||
|
||||
// Check if the symbol is the index of a loop that's unrolled.
|
||||
bool NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol);
|
||||
|
||||
// Return the current value of a given loop index symbol.
|
||||
int GetLoopIndexValue(TIntermSymbol* symbol);
|
||||
|
||||
void Push(TLoopIndexInfo& info);
|
||||
void Pop();
|
||||
|
||||
static void MarkForLoopsWithIntegerIndicesForUnrolling(TIntermNode* root);
|
||||
|
||||
private:
|
||||
int getLoopIncrement(TIntermLoop* node);
|
||||
|
||||
int evaluateIntConstant(TIntermConstantUnion* node);
|
||||
|
||||
TVector<TLoopIndexInfo> mLoopIndexStack;
|
||||
};
|
||||
|
59
src/3rdparty/angle/src/compiler/InfoSink.cpp
vendored
Normal file
59
src/3rdparty/angle/src/compiler/InfoSink.cpp
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/InfoSink.h"
|
||||
|
||||
void TInfoSinkBase::prefix(TPrefixType message) {
|
||||
switch(message) {
|
||||
case EPrefixNone:
|
||||
break;
|
||||
case EPrefixWarning:
|
||||
sink.append("WARNING: ");
|
||||
break;
|
||||
case EPrefixError:
|
||||
sink.append("ERROR: ");
|
||||
break;
|
||||
case EPrefixInternalError:
|
||||
sink.append("INTERNAL ERROR: ");
|
||||
break;
|
||||
case EPrefixUnimplemented:
|
||||
sink.append("UNIMPLEMENTED: ");
|
||||
break;
|
||||
case EPrefixNote:
|
||||
sink.append("NOTE: ");
|
||||
break;
|
||||
default:
|
||||
sink.append("UNKOWN ERROR: ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TInfoSinkBase::location(TSourceLoc loc) {
|
||||
int string = 0, line = 0;
|
||||
DecodeSourceLoc(loc, &string, &line);
|
||||
|
||||
TPersistStringStream stream;
|
||||
if (line)
|
||||
stream << string << ":" << line;
|
||||
else
|
||||
stream << string << ":? ";
|
||||
stream << ": ";
|
||||
|
||||
sink.append(stream.str());
|
||||
}
|
||||
|
||||
void TInfoSinkBase::message(TPrefixType message, const char* s) {
|
||||
prefix(message);
|
||||
sink.append(s);
|
||||
sink.append("\n");
|
||||
}
|
||||
|
||||
void TInfoSinkBase::message(TPrefixType message, const char* s, TSourceLoc loc) {
|
||||
prefix(message);
|
||||
location(loc);
|
||||
sink.append(s);
|
||||
sink.append("\n");
|
||||
}
|
115
src/3rdparty/angle/src/compiler/InfoSink.h
vendored
Normal file
115
src/3rdparty/angle/src/compiler/InfoSink.h
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef _INFOSINK_INCLUDED_
|
||||
#define _INFOSINK_INCLUDED_
|
||||
|
||||
#include <math.h>
|
||||
#include "compiler/Common.h"
|
||||
|
||||
// Returns the fractional part of the given floating-point number.
|
||||
inline float fractionalPart(float f) {
|
||||
float intPart = 0.0f;
|
||||
return modff(f, &intPart);
|
||||
}
|
||||
|
||||
//
|
||||
// TPrefixType is used to centralize how info log messages start.
|
||||
// See below.
|
||||
//
|
||||
enum TPrefixType {
|
||||
EPrefixNone,
|
||||
EPrefixWarning,
|
||||
EPrefixError,
|
||||
EPrefixInternalError,
|
||||
EPrefixUnimplemented,
|
||||
EPrefixNote
|
||||
};
|
||||
|
||||
//
|
||||
// Encapsulate info logs for all objects that have them.
|
||||
//
|
||||
// The methods are a general set of tools for getting a variety of
|
||||
// messages and types inserted into the log.
|
||||
//
|
||||
class TInfoSinkBase {
|
||||
public:
|
||||
TInfoSinkBase() {}
|
||||
|
||||
template <typename T>
|
||||
TInfoSinkBase& operator<<(const T& t) {
|
||||
TPersistStringStream stream;
|
||||
stream << t;
|
||||
sink.append(stream.str());
|
||||
return *this;
|
||||
}
|
||||
// Override << operator for specific types. It is faster to append strings
|
||||
// and characters directly to the sink.
|
||||
TInfoSinkBase& operator<<(char c) {
|
||||
sink.append(1, c);
|
||||
return *this;
|
||||
}
|
||||
TInfoSinkBase& operator<<(const char* str) {
|
||||
sink.append(str);
|
||||
return *this;
|
||||
}
|
||||
TInfoSinkBase& operator<<(const TPersistString& str) {
|
||||
sink.append(str);
|
||||
return *this;
|
||||
}
|
||||
TInfoSinkBase& operator<<(const TString& str) {
|
||||
sink.append(str.c_str());
|
||||
return *this;
|
||||
}
|
||||
// Make sure floats are written with correct precision.
|
||||
TInfoSinkBase& operator<<(float f) {
|
||||
// Make sure that at least one decimal point is written. If a number
|
||||
// does not have a fractional part, the default precision format does
|
||||
// not write the decimal portion which gets interpreted as integer by
|
||||
// the compiler.
|
||||
TPersistStringStream stream;
|
||||
if (fractionalPart(f) == 0.0f) {
|
||||
stream.precision(1);
|
||||
stream << std::showpoint << std::fixed << f;
|
||||
} else {
|
||||
stream.unsetf(std::ios::fixed);
|
||||
stream.unsetf(std::ios::scientific);
|
||||
stream.precision(8);
|
||||
stream << f;
|
||||
}
|
||||
sink.append(stream.str());
|
||||
return *this;
|
||||
}
|
||||
// Write boolean values as their names instead of integral value.
|
||||
TInfoSinkBase& operator<<(bool b) {
|
||||
const char* str = b ? "true" : "false";
|
||||
sink.append(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void erase() { sink.clear(); }
|
||||
int size() { return static_cast<int>(sink.size()); }
|
||||
|
||||
const TPersistString& str() const { return sink; }
|
||||
const char* c_str() const { return sink.c_str(); }
|
||||
|
||||
void prefix(TPrefixType message);
|
||||
void location(TSourceLoc loc);
|
||||
void message(TPrefixType message, const char* s);
|
||||
void message(TPrefixType message, const char* s, TSourceLoc loc);
|
||||
|
||||
private:
|
||||
TPersistString sink;
|
||||
};
|
||||
|
||||
class TInfoSink {
|
||||
public:
|
||||
TInfoSinkBase info;
|
||||
TInfoSinkBase debug;
|
||||
TInfoSinkBase obj;
|
||||
};
|
||||
|
||||
#endif // _INFOSINK_INCLUDED_
|
657
src/3rdparty/angle/src/compiler/Initialize.cpp
vendored
Normal file
657
src/3rdparty/angle/src/compiler/Initialize.cpp
vendored
Normal file
@ -0,0 +1,657 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
//
|
||||
// Create strings that declare built-in definitions, add built-ins that
|
||||
// cannot be expressed in the files, and establish mappings between
|
||||
// built-in functions and operators.
|
||||
//
|
||||
|
||||
#include "compiler/Initialize.h"
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Prototypes for built-in functions seen by both vertex and fragment shaders.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInFunctionsCommon(const ShBuiltInResources& resources)
|
||||
{
|
||||
TString s;
|
||||
|
||||
//
|
||||
// Angle and Trigonometric Functions.
|
||||
//
|
||||
s.append(TString("float radians(float degrees);"));
|
||||
s.append(TString("vec2 radians(vec2 degrees);"));
|
||||
s.append(TString("vec3 radians(vec3 degrees);"));
|
||||
s.append(TString("vec4 radians(vec4 degrees);"));
|
||||
|
||||
s.append(TString("float degrees(float radians);"));
|
||||
s.append(TString("vec2 degrees(vec2 radians);"));
|
||||
s.append(TString("vec3 degrees(vec3 radians);"));
|
||||
s.append(TString("vec4 degrees(vec4 radians);"));
|
||||
|
||||
s.append(TString("float sin(float angle);"));
|
||||
s.append(TString("vec2 sin(vec2 angle);"));
|
||||
s.append(TString("vec3 sin(vec3 angle);"));
|
||||
s.append(TString("vec4 sin(vec4 angle);"));
|
||||
|
||||
s.append(TString("float cos(float angle);"));
|
||||
s.append(TString("vec2 cos(vec2 angle);"));
|
||||
s.append(TString("vec3 cos(vec3 angle);"));
|
||||
s.append(TString("vec4 cos(vec4 angle);"));
|
||||
|
||||
s.append(TString("float tan(float angle);"));
|
||||
s.append(TString("vec2 tan(vec2 angle);"));
|
||||
s.append(TString("vec3 tan(vec3 angle);"));
|
||||
s.append(TString("vec4 tan(vec4 angle);"));
|
||||
|
||||
s.append(TString("float asin(float x);"));
|
||||
s.append(TString("vec2 asin(vec2 x);"));
|
||||
s.append(TString("vec3 asin(vec3 x);"));
|
||||
s.append(TString("vec4 asin(vec4 x);"));
|
||||
|
||||
s.append(TString("float acos(float x);"));
|
||||
s.append(TString("vec2 acos(vec2 x);"));
|
||||
s.append(TString("vec3 acos(vec3 x);"));
|
||||
s.append(TString("vec4 acos(vec4 x);"));
|
||||
|
||||
s.append(TString("float atan(float y, float x);"));
|
||||
s.append(TString("vec2 atan(vec2 y, vec2 x);"));
|
||||
s.append(TString("vec3 atan(vec3 y, vec3 x);"));
|
||||
s.append(TString("vec4 atan(vec4 y, vec4 x);"));
|
||||
|
||||
s.append(TString("float atan(float y_over_x);"));
|
||||
s.append(TString("vec2 atan(vec2 y_over_x);"));
|
||||
s.append(TString("vec3 atan(vec3 y_over_x);"));
|
||||
s.append(TString("vec4 atan(vec4 y_over_x);"));
|
||||
|
||||
//
|
||||
// Exponential Functions.
|
||||
//
|
||||
s.append(TString("float pow(float x, float y);"));
|
||||
s.append(TString("vec2 pow(vec2 x, vec2 y);"));
|
||||
s.append(TString("vec3 pow(vec3 x, vec3 y);"));
|
||||
s.append(TString("vec4 pow(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("float exp(float x);"));
|
||||
s.append(TString("vec2 exp(vec2 x);"));
|
||||
s.append(TString("vec3 exp(vec3 x);"));
|
||||
s.append(TString("vec4 exp(vec4 x);"));
|
||||
|
||||
s.append(TString("float log(float x);"));
|
||||
s.append(TString("vec2 log(vec2 x);"));
|
||||
s.append(TString("vec3 log(vec3 x);"));
|
||||
s.append(TString("vec4 log(vec4 x);"));
|
||||
|
||||
s.append(TString("float exp2(float x);"));
|
||||
s.append(TString("vec2 exp2(vec2 x);"));
|
||||
s.append(TString("vec3 exp2(vec3 x);"));
|
||||
s.append(TString("vec4 exp2(vec4 x);"));
|
||||
|
||||
s.append(TString("float log2(float x);"));
|
||||
s.append(TString("vec2 log2(vec2 x);"));
|
||||
s.append(TString("vec3 log2(vec3 x);"));
|
||||
s.append(TString("vec4 log2(vec4 x);"));
|
||||
|
||||
s.append(TString("float sqrt(float x);"));
|
||||
s.append(TString("vec2 sqrt(vec2 x);"));
|
||||
s.append(TString("vec3 sqrt(vec3 x);"));
|
||||
s.append(TString("vec4 sqrt(vec4 x);"));
|
||||
|
||||
s.append(TString("float inversesqrt(float x);"));
|
||||
s.append(TString("vec2 inversesqrt(vec2 x);"));
|
||||
s.append(TString("vec3 inversesqrt(vec3 x);"));
|
||||
s.append(TString("vec4 inversesqrt(vec4 x);"));
|
||||
|
||||
//
|
||||
// Common Functions.
|
||||
//
|
||||
s.append(TString("float abs(float x);"));
|
||||
s.append(TString("vec2 abs(vec2 x);"));
|
||||
s.append(TString("vec3 abs(vec3 x);"));
|
||||
s.append(TString("vec4 abs(vec4 x);"));
|
||||
|
||||
s.append(TString("float sign(float x);"));
|
||||
s.append(TString("vec2 sign(vec2 x);"));
|
||||
s.append(TString("vec3 sign(vec3 x);"));
|
||||
s.append(TString("vec4 sign(vec4 x);"));
|
||||
|
||||
s.append(TString("float floor(float x);"));
|
||||
s.append(TString("vec2 floor(vec2 x);"));
|
||||
s.append(TString("vec3 floor(vec3 x);"));
|
||||
s.append(TString("vec4 floor(vec4 x);"));
|
||||
|
||||
s.append(TString("float ceil(float x);"));
|
||||
s.append(TString("vec2 ceil(vec2 x);"));
|
||||
s.append(TString("vec3 ceil(vec3 x);"));
|
||||
s.append(TString("vec4 ceil(vec4 x);"));
|
||||
|
||||
s.append(TString("float fract(float x);"));
|
||||
s.append(TString("vec2 fract(vec2 x);"));
|
||||
s.append(TString("vec3 fract(vec3 x);"));
|
||||
s.append(TString("vec4 fract(vec4 x);"));
|
||||
|
||||
s.append(TString("float mod(float x, float y);"));
|
||||
s.append(TString("vec2 mod(vec2 x, float y);"));
|
||||
s.append(TString("vec3 mod(vec3 x, float y);"));
|
||||
s.append(TString("vec4 mod(vec4 x, float y);"));
|
||||
s.append(TString("vec2 mod(vec2 x, vec2 y);"));
|
||||
s.append(TString("vec3 mod(vec3 x, vec3 y);"));
|
||||
s.append(TString("vec4 mod(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("float min(float x, float y);"));
|
||||
s.append(TString("vec2 min(vec2 x, float y);"));
|
||||
s.append(TString("vec3 min(vec3 x, float y);"));
|
||||
s.append(TString("vec4 min(vec4 x, float y);"));
|
||||
s.append(TString("vec2 min(vec2 x, vec2 y);"));
|
||||
s.append(TString("vec3 min(vec3 x, vec3 y);"));
|
||||
s.append(TString("vec4 min(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("float max(float x, float y);"));
|
||||
s.append(TString("vec2 max(vec2 x, float y);"));
|
||||
s.append(TString("vec3 max(vec3 x, float y);"));
|
||||
s.append(TString("vec4 max(vec4 x, float y);"));
|
||||
s.append(TString("vec2 max(vec2 x, vec2 y);"));
|
||||
s.append(TString("vec3 max(vec3 x, vec3 y);"));
|
||||
s.append(TString("vec4 max(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("float clamp(float x, float minVal, float maxVal);"));
|
||||
s.append(TString("vec2 clamp(vec2 x, float minVal, float maxVal);"));
|
||||
s.append(TString("vec3 clamp(vec3 x, float minVal, float maxVal);"));
|
||||
s.append(TString("vec4 clamp(vec4 x, float minVal, float maxVal);"));
|
||||
s.append(TString("vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);"));
|
||||
s.append(TString("vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);"));
|
||||
s.append(TString("vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);"));
|
||||
|
||||
s.append(TString("float mix(float x, float y, float a);"));
|
||||
s.append(TString("vec2 mix(vec2 x, vec2 y, float a);"));
|
||||
s.append(TString("vec3 mix(vec3 x, vec3 y, float a);"));
|
||||
s.append(TString("vec4 mix(vec4 x, vec4 y, float a);"));
|
||||
s.append(TString("vec2 mix(vec2 x, vec2 y, vec2 a);"));
|
||||
s.append(TString("vec3 mix(vec3 x, vec3 y, vec3 a);"));
|
||||
s.append(TString("vec4 mix(vec4 x, vec4 y, vec4 a);"));
|
||||
|
||||
s.append(TString("float step(float edge, float x);"));
|
||||
s.append(TString("vec2 step(vec2 edge, vec2 x);"));
|
||||
s.append(TString("vec3 step(vec3 edge, vec3 x);"));
|
||||
s.append(TString("vec4 step(vec4 edge, vec4 x);"));
|
||||
s.append(TString("vec2 step(float edge, vec2 x);"));
|
||||
s.append(TString("vec3 step(float edge, vec3 x);"));
|
||||
s.append(TString("vec4 step(float edge, vec4 x);"));
|
||||
|
||||
s.append(TString("float smoothstep(float edge0, float edge1, float x);"));
|
||||
s.append(TString("vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);"));
|
||||
s.append(TString("vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);"));
|
||||
s.append(TString("vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);"));
|
||||
s.append(TString("vec2 smoothstep(float edge0, float edge1, vec2 x);"));
|
||||
s.append(TString("vec3 smoothstep(float edge0, float edge1, vec3 x);"));
|
||||
s.append(TString("vec4 smoothstep(float edge0, float edge1, vec4 x);"));
|
||||
|
||||
//
|
||||
// Geometric Functions.
|
||||
//
|
||||
s.append(TString("float length(float x);"));
|
||||
s.append(TString("float length(vec2 x);"));
|
||||
s.append(TString("float length(vec3 x);"));
|
||||
s.append(TString("float length(vec4 x);"));
|
||||
|
||||
s.append(TString("float distance(float p0, float p1);"));
|
||||
s.append(TString("float distance(vec2 p0, vec2 p1);"));
|
||||
s.append(TString("float distance(vec3 p0, vec3 p1);"));
|
||||
s.append(TString("float distance(vec4 p0, vec4 p1);"));
|
||||
|
||||
s.append(TString("float dot(float x, float y);"));
|
||||
s.append(TString("float dot(vec2 x, vec2 y);"));
|
||||
s.append(TString("float dot(vec3 x, vec3 y);"));
|
||||
s.append(TString("float dot(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("vec3 cross(vec3 x, vec3 y);"));
|
||||
s.append(TString("float normalize(float x);"));
|
||||
s.append(TString("vec2 normalize(vec2 x);"));
|
||||
s.append(TString("vec3 normalize(vec3 x);"));
|
||||
s.append(TString("vec4 normalize(vec4 x);"));
|
||||
|
||||
s.append(TString("float faceforward(float N, float I, float Nref);"));
|
||||
s.append(TString("vec2 faceforward(vec2 N, vec2 I, vec2 Nref);"));
|
||||
s.append(TString("vec3 faceforward(vec3 N, vec3 I, vec3 Nref);"));
|
||||
s.append(TString("vec4 faceforward(vec4 N, vec4 I, vec4 Nref);"));
|
||||
|
||||
s.append(TString("float reflect(float I, float N);"));
|
||||
s.append(TString("vec2 reflect(vec2 I, vec2 N);"));
|
||||
s.append(TString("vec3 reflect(vec3 I, vec3 N);"));
|
||||
s.append(TString("vec4 reflect(vec4 I, vec4 N);"));
|
||||
|
||||
s.append(TString("float refract(float I, float N, float eta);"));
|
||||
s.append(TString("vec2 refract(vec2 I, vec2 N, float eta);"));
|
||||
s.append(TString("vec3 refract(vec3 I, vec3 N, float eta);"));
|
||||
s.append(TString("vec4 refract(vec4 I, vec4 N, float eta);"));
|
||||
|
||||
//
|
||||
// Matrix Functions.
|
||||
//
|
||||
s.append(TString("mat2 matrixCompMult(mat2 x, mat2 y);"));
|
||||
s.append(TString("mat3 matrixCompMult(mat3 x, mat3 y);"));
|
||||
s.append(TString("mat4 matrixCompMult(mat4 x, mat4 y);"));
|
||||
|
||||
//
|
||||
// Vector relational functions.
|
||||
//
|
||||
s.append(TString("bvec2 lessThan(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 lessThan(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 lessThan(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 lessThan(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 lessThan(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 lessThan(ivec4 x, ivec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 lessThanEqual(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 lessThanEqual(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 lessThanEqual(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 lessThanEqual(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 lessThanEqual(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 lessThanEqual(ivec4 x, ivec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 greaterThan(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 greaterThan(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 greaterThan(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 greaterThan(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 greaterThan(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 greaterThan(ivec4 x, ivec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 greaterThanEqual(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 greaterThanEqual(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 greaterThanEqual(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 greaterThanEqual(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 greaterThanEqual(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 greaterThanEqual(ivec4 x, ivec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 equal(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 equal(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 equal(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 equal(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 equal(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 equal(ivec4 x, ivec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 equal(bvec2 x, bvec2 y);"));
|
||||
s.append(TString("bvec3 equal(bvec3 x, bvec3 y);"));
|
||||
s.append(TString("bvec4 equal(bvec4 x, bvec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 notEqual(vec2 x, vec2 y);"));
|
||||
s.append(TString("bvec3 notEqual(vec3 x, vec3 y);"));
|
||||
s.append(TString("bvec4 notEqual(vec4 x, vec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 notEqual(ivec2 x, ivec2 y);"));
|
||||
s.append(TString("bvec3 notEqual(ivec3 x, ivec3 y);"));
|
||||
s.append(TString("bvec4 notEqual(ivec4 x, ivec4 y);"));
|
||||
|
||||
s.append(TString("bvec2 notEqual(bvec2 x, bvec2 y);"));
|
||||
s.append(TString("bvec3 notEqual(bvec3 x, bvec3 y);"));
|
||||
s.append(TString("bvec4 notEqual(bvec4 x, bvec4 y);"));
|
||||
|
||||
s.append(TString("bool any(bvec2 x);"));
|
||||
s.append(TString("bool any(bvec3 x);"));
|
||||
s.append(TString("bool any(bvec4 x);"));
|
||||
|
||||
s.append(TString("bool all(bvec2 x);"));
|
||||
s.append(TString("bool all(bvec3 x);"));
|
||||
s.append(TString("bool all(bvec4 x);"));
|
||||
|
||||
s.append(TString("bvec2 not(bvec2 x);"));
|
||||
s.append(TString("bvec3 not(bvec3 x);"));
|
||||
s.append(TString("bvec4 not(bvec4 x);"));
|
||||
|
||||
//
|
||||
// Texture Functions.
|
||||
//
|
||||
s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
|
||||
s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
|
||||
|
||||
if (resources.OES_EGL_image_external) {
|
||||
s.append(TString("vec4 texture2D(samplerExternalOES sampler, vec2 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec3 coord);"));
|
||||
s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec4 coord);"));
|
||||
}
|
||||
|
||||
if (resources.ARB_texture_rectangle) {
|
||||
s.append(TString("vec4 texture2DRect(sampler2DRect sampler, vec2 coord);"));
|
||||
s.append(TString("vec4 texture2DRectProj(sampler2DRect sampler, vec3 coord);"));
|
||||
s.append(TString("vec4 texture2DRectProj(sampler2DRect sampler, vec4 coord);"));
|
||||
}
|
||||
|
||||
//
|
||||
// Noise functions.
|
||||
//
|
||||
//s.append(TString("float noise1(float x);"));
|
||||
//s.append(TString("float noise1(vec2 x);"));
|
||||
//s.append(TString("float noise1(vec3 x);"));
|
||||
//s.append(TString("float noise1(vec4 x);"));
|
||||
|
||||
//s.append(TString("vec2 noise2(float x);"));
|
||||
//s.append(TString("vec2 noise2(vec2 x);"));
|
||||
//s.append(TString("vec2 noise2(vec3 x);"));
|
||||
//s.append(TString("vec2 noise2(vec4 x);"));
|
||||
|
||||
//s.append(TString("vec3 noise3(float x);"));
|
||||
//s.append(TString("vec3 noise3(vec2 x);"));
|
||||
//s.append(TString("vec3 noise3(vec3 x);"));
|
||||
//s.append(TString("vec3 noise3(vec4 x);"));
|
||||
|
||||
//s.append(TString("vec4 noise4(float x);"));
|
||||
//s.append(TString("vec4 noise4(vec2 x);"));
|
||||
//s.append(TString("vec4 noise4(vec3 x);"));
|
||||
//s.append(TString("vec4 noise4(vec4 x);"));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Prototypes for built-in functions seen by vertex shaders only.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInFunctionsVertex(const ShBuiltInResources& resources)
|
||||
{
|
||||
TString s;
|
||||
|
||||
//
|
||||
// Geometric Functions.
|
||||
//
|
||||
//s.append(TString("vec4 ftransform();"));
|
||||
|
||||
//
|
||||
// Texture Functions.
|
||||
//
|
||||
s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
|
||||
s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
|
||||
s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
|
||||
s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Prototypes for built-in functions seen by fragment shaders only.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInFunctionsFragment(const ShBuiltInResources& resources)
|
||||
{
|
||||
TString s;
|
||||
|
||||
//
|
||||
// Texture Functions.
|
||||
//
|
||||
s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
|
||||
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
|
||||
s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
|
||||
|
||||
if (resources.OES_standard_derivatives) {
|
||||
s.append(TString("float dFdx(float p);"));
|
||||
s.append(TString("vec2 dFdx(vec2 p);"));
|
||||
s.append(TString("vec3 dFdx(vec3 p);"));
|
||||
s.append(TString("vec4 dFdx(vec4 p);"));
|
||||
|
||||
s.append(TString("float dFdy(float p);"));
|
||||
s.append(TString("vec2 dFdy(vec2 p);"));
|
||||
s.append(TString("vec3 dFdy(vec3 p);"));
|
||||
s.append(TString("vec4 dFdy(vec4 p);"));
|
||||
|
||||
s.append(TString("float fwidth(float p);"));
|
||||
s.append(TString("vec2 fwidth(vec2 p);"));
|
||||
s.append(TString("vec3 fwidth(vec3 p);"));
|
||||
s.append(TString("vec4 fwidth(vec4 p);"));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Standard uniforms.
|
||||
//
|
||||
//============================================================================
|
||||
static TString StandardUniforms()
|
||||
{
|
||||
TString s;
|
||||
|
||||
//
|
||||
// Depth range in window coordinates
|
||||
//
|
||||
s.append(TString("struct gl_DepthRangeParameters {"));
|
||||
s.append(TString(" highp float near;")); // n
|
||||
s.append(TString(" highp float far;")); // f
|
||||
s.append(TString(" highp float diff;")); // f - n
|
||||
s.append(TString("};"));
|
||||
s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Default precision for vertex shaders.
|
||||
//
|
||||
//============================================================================
|
||||
static TString DefaultPrecisionVertex()
|
||||
{
|
||||
TString s;
|
||||
|
||||
s.append(TString("precision highp int;"));
|
||||
s.append(TString("precision highp float;"));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Default precision for fragment shaders.
|
||||
//
|
||||
//============================================================================
|
||||
static TString DefaultPrecisionFragment()
|
||||
{
|
||||
TString s;
|
||||
|
||||
s.append(TString("precision mediump int;"));
|
||||
// No default precision for float in fragment shaders
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Implementation dependent built-in constants.
|
||||
//
|
||||
//============================================================================
|
||||
static TString BuiltInConstants(ShShaderSpec spec, const ShBuiltInResources &resources)
|
||||
{
|
||||
TStringStream s;
|
||||
|
||||
s << "const int gl_MaxVertexAttribs = " << resources.MaxVertexAttribs << ";";
|
||||
s << "const int gl_MaxVertexUniformVectors = " << resources.MaxVertexUniformVectors << ";";
|
||||
|
||||
s << "const int gl_MaxVaryingVectors = " << resources.MaxVaryingVectors << ";";
|
||||
s << "const int gl_MaxVertexTextureImageUnits = " << resources.MaxVertexTextureImageUnits << ";";
|
||||
s << "const int gl_MaxCombinedTextureImageUnits = " << resources.MaxCombinedTextureImageUnits << ";";
|
||||
s << "const int gl_MaxTextureImageUnits = " << resources.MaxTextureImageUnits << ";";
|
||||
s << "const int gl_MaxFragmentUniformVectors = " << resources.MaxFragmentUniformVectors << ";";
|
||||
|
||||
if (spec != SH_CSS_SHADERS_SPEC)
|
||||
s << "const int gl_MaxDrawBuffers = " << resources.MaxDrawBuffers << ";";
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
void TBuiltIns::initialize(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources)
|
||||
{
|
||||
switch (type) {
|
||||
case SH_FRAGMENT_SHADER:
|
||||
builtInStrings.push_back(DefaultPrecisionFragment());
|
||||
builtInStrings.push_back(BuiltInFunctionsCommon(resources));
|
||||
builtInStrings.push_back(BuiltInFunctionsFragment(resources));
|
||||
builtInStrings.push_back(StandardUniforms());
|
||||
break;
|
||||
|
||||
case SH_VERTEX_SHADER:
|
||||
builtInStrings.push_back(DefaultPrecisionVertex());
|
||||
builtInStrings.push_back(BuiltInFunctionsCommon(resources));
|
||||
builtInStrings.push_back(BuiltInFunctionsVertex(resources));
|
||||
builtInStrings.push_back(StandardUniforms());
|
||||
break;
|
||||
|
||||
default: assert(false && "Language not supported");
|
||||
}
|
||||
|
||||
builtInStrings.push_back(BuiltInConstants(spec, resources));
|
||||
}
|
||||
|
||||
void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources,
|
||||
TSymbolTable& symbolTable)
|
||||
{
|
||||
//
|
||||
// First, insert some special built-in variables that are not in
|
||||
// the built-in header files.
|
||||
//
|
||||
switch(type) {
|
||||
case SH_FRAGMENT_SHADER:
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
|
||||
symbolTable.insert(*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(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
|
||||
} else {
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4)));
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, true)));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SH_VERTEX_SHADER:
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4)));
|
||||
symbolTable.insert(*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("not", EOpVectorLogicalNot);
|
||||
|
||||
symbolTable.relateToOperator("matrixCompMult", EOpMul);
|
||||
|
||||
symbolTable.relateToOperator("equal", EOpVectorEqual);
|
||||
symbolTable.relateToOperator("notEqual", EOpVectorNotEqual);
|
||||
symbolTable.relateToOperator("lessThan", EOpLessThan);
|
||||
symbolTable.relateToOperator("greaterThan", EOpGreaterThan);
|
||||
symbolTable.relateToOperator("lessThanEqual", EOpLessThanEqual);
|
||||
symbolTable.relateToOperator("greaterThanEqual", EOpGreaterThanEqual);
|
||||
|
||||
symbolTable.relateToOperator("radians", EOpRadians);
|
||||
symbolTable.relateToOperator("degrees", EOpDegrees);
|
||||
symbolTable.relateToOperator("sin", EOpSin);
|
||||
symbolTable.relateToOperator("cos", EOpCos);
|
||||
symbolTable.relateToOperator("tan", EOpTan);
|
||||
symbolTable.relateToOperator("asin", EOpAsin);
|
||||
symbolTable.relateToOperator("acos", EOpAcos);
|
||||
symbolTable.relateToOperator("atan", EOpAtan);
|
||||
|
||||
symbolTable.relateToOperator("pow", EOpPow);
|
||||
symbolTable.relateToOperator("exp2", EOpExp2);
|
||||
symbolTable.relateToOperator("log", EOpLog);
|
||||
symbolTable.relateToOperator("exp", EOpExp);
|
||||
symbolTable.relateToOperator("log2", EOpLog2);
|
||||
symbolTable.relateToOperator("sqrt", EOpSqrt);
|
||||
symbolTable.relateToOperator("inversesqrt", EOpInverseSqrt);
|
||||
|
||||
symbolTable.relateToOperator("abs", EOpAbs);
|
||||
symbolTable.relateToOperator("sign", EOpSign);
|
||||
symbolTable.relateToOperator("floor", EOpFloor);
|
||||
symbolTable.relateToOperator("ceil", EOpCeil);
|
||||
symbolTable.relateToOperator("fract", EOpFract);
|
||||
symbolTable.relateToOperator("mod", EOpMod);
|
||||
symbolTable.relateToOperator("min", EOpMin);
|
||||
symbolTable.relateToOperator("max", EOpMax);
|
||||
symbolTable.relateToOperator("clamp", EOpClamp);
|
||||
symbolTable.relateToOperator("mix", EOpMix);
|
||||
symbolTable.relateToOperator("step", EOpStep);
|
||||
symbolTable.relateToOperator("smoothstep", EOpSmoothStep);
|
||||
|
||||
symbolTable.relateToOperator("length", EOpLength);
|
||||
symbolTable.relateToOperator("distance", EOpDistance);
|
||||
symbolTable.relateToOperator("dot", EOpDot);
|
||||
symbolTable.relateToOperator("cross", EOpCross);
|
||||
symbolTable.relateToOperator("normalize", EOpNormalize);
|
||||
symbolTable.relateToOperator("faceforward", EOpFaceForward);
|
||||
symbolTable.relateToOperator("reflect", EOpReflect);
|
||||
symbolTable.relateToOperator("refract", EOpRefract);
|
||||
|
||||
symbolTable.relateToOperator("any", EOpAny);
|
||||
symbolTable.relateToOperator("all", EOpAll);
|
||||
|
||||
// Map language-specific operators.
|
||||
switch(type) {
|
||||
case SH_VERTEX_SHADER:
|
||||
break;
|
||||
case SH_FRAGMENT_SHADER:
|
||||
if (resources.OES_standard_derivatives) {
|
||||
symbolTable.relateToOperator("dFdx", EOpDFdx);
|
||||
symbolTable.relateToOperator("dFdy", EOpDFdy);
|
||||
symbolTable.relateToOperator("fwidth", EOpFwidth);
|
||||
|
||||
symbolTable.relateToExtension("dFdx", "GL_OES_standard_derivatives");
|
||||
symbolTable.relateToExtension("dFdy", "GL_OES_standard_derivatives");
|
||||
symbolTable.relateToExtension("fwidth", "GL_OES_standard_derivatives");
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Finally add resource-specific variables.
|
||||
switch(type) {
|
||||
case SH_FRAGMENT_SHADER:
|
||||
if (spec != SH_CSS_SHADERS_SPEC) {
|
||||
// Set up gl_FragData. The array size.
|
||||
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, false, true);
|
||||
fragData.setArraySize(resources.MaxDrawBuffers);
|
||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void InitExtensionBehavior(const ShBuiltInResources& resources,
|
||||
TExtensionBehavior& extBehavior)
|
||||
{
|
||||
if (resources.OES_standard_derivatives)
|
||||
extBehavior["GL_OES_standard_derivatives"] = EBhUndefined;
|
||||
if (resources.OES_EGL_image_external)
|
||||
extBehavior["GL_OES_EGL_image_external"] = EBhUndefined;
|
||||
if (resources.ARB_texture_rectangle)
|
||||
extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined;
|
||||
}
|
35
src/3rdparty/angle/src/compiler/Initialize.h
vendored
Normal file
35
src/3rdparty/angle/src/compiler/Initialize.h
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef _INITIALIZE_INCLUDED_
|
||||
#define _INITIALIZE_INCLUDED_
|
||||
|
||||
#include "compiler/Common.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/SymbolTable.h"
|
||||
|
||||
typedef TVector<TString> TBuiltInStrings;
|
||||
|
||||
class TBuiltIns {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
|
||||
void initialize(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources);
|
||||
const TBuiltInStrings& getBuiltInStrings() { return builtInStrings; }
|
||||
|
||||
protected:
|
||||
TBuiltInStrings builtInStrings;
|
||||
};
|
||||
|
||||
void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
|
||||
const ShBuiltInResources& resources,
|
||||
TSymbolTable& symbolTable);
|
||||
|
||||
void InitExtensionBehavior(const ShBuiltInResources& resources,
|
||||
TExtensionBehavior& extensionBehavior);
|
||||
|
||||
#endif // _INITIALIZE_INCLUDED_
|
115
src/3rdparty/angle/src/compiler/InitializeDll.cpp
vendored
Normal file
115
src/3rdparty/angle/src/compiler/InitializeDll.cpp
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/InitializeDll.h"
|
||||
|
||||
#include "compiler/InitializeGlobals.h"
|
||||
#include "compiler/InitializeParseContext.h"
|
||||
#include "compiler/osinclude.h"
|
||||
|
||||
OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
bool InitProcess()
|
||||
{
|
||||
if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
|
||||
//
|
||||
// Function is re-entrant.
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
ThreadInitializeIndex = OS_AllocTLSIndex();
|
||||
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!InitializePoolIndex()) {
|
||||
assert(0 && "InitProcess(): Failed to initalize global pool");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!InitializeParseContextIndex()) {
|
||||
assert(0 && "InitProcess(): Failed to initalize parse context");
|
||||
return false;
|
||||
}
|
||||
|
||||
return InitThread();
|
||||
}
|
||||
|
||||
bool DetachProcess()
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
|
||||
return true;
|
||||
|
||||
success = DetachThread();
|
||||
|
||||
if (!FreeParseContextIndex())
|
||||
success = false;
|
||||
|
||||
FreePoolIndex();
|
||||
|
||||
OS_FreeTLSIndex(ThreadInitializeIndex);
|
||||
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool InitThread()
|
||||
{
|
||||
//
|
||||
// This function is re-entrant
|
||||
//
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitThread(): Process hasn't been initalised.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
|
||||
return true;
|
||||
|
||||
InitializeGlobalPools();
|
||||
|
||||
if (!InitializeGlobalParseContext())
|
||||
return false;
|
||||
|
||||
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
|
||||
assert(0 && "InitThread(): Unable to set init flag.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DetachThread()
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
|
||||
return true;
|
||||
|
||||
//
|
||||
// Function is re-entrant and this thread may not have been initalised.
|
||||
//
|
||||
if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
|
||||
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
|
||||
assert(0 && "DetachThread(): Unable to clear init flag.");
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (!FreeParseContext())
|
||||
success = false;
|
||||
|
||||
FreeGlobalPools();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
16
src/3rdparty/angle/src/compiler/InitializeDll.h
vendored
Normal file
16
src/3rdparty/angle/src/compiler/InitializeDll.h
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
#ifndef __INITIALIZEDLL_H
|
||||
#define __INITIALIZEDLL_H
|
||||
|
||||
bool InitProcess();
|
||||
bool DetachProcess();
|
||||
|
||||
bool InitThread();
|
||||
bool DetachThread();
|
||||
|
||||
#endif // __INITIALIZEDLL_H
|
||||
|
15
src/3rdparty/angle/src/compiler/InitializeGlobals.h
vendored
Normal file
15
src/3rdparty/angle/src/compiler/InitializeGlobals.h
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef __INITIALIZE_GLOBALS_INCLUDED_
|
||||
#define __INITIALIZE_GLOBALS_INCLUDED_
|
||||
|
||||
void InitializeGlobalPools();
|
||||
void FreeGlobalPools();
|
||||
bool InitializePoolIndex();
|
||||
void FreePoolIndex();
|
||||
|
||||
#endif // __INITIALIZE_GLOBALS_INCLUDED_
|
96
src/3rdparty/angle/src/compiler/InitializeParseContext.cpp
vendored
Normal file
96
src/3rdparty/angle/src/compiler/InitializeParseContext.cpp
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
//
|
||||
// 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 "compiler/InitializeParseContext.h"
|
||||
|
||||
#include "compiler/osinclude.h"
|
||||
|
||||
OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
bool InitializeParseContextIndex()
|
||||
{
|
||||
if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate a TLS index.
|
||||
//
|
||||
GlobalParseContextIndex = OS_AllocTLSIndex();
|
||||
|
||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FreeParseContextIndex()
|
||||
{
|
||||
OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
|
||||
|
||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "FreeParseContextIndex(): Parse Context index not initalized");
|
||||
return false;
|
||||
}
|
||||
|
||||
GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
return OS_FreeTLSIndex(tlsiIndex);
|
||||
}
|
||||
|
||||
bool InitializeGlobalParseContext()
|
||||
{
|
||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalized");
|
||||
return false;
|
||||
}
|
||||
|
||||
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
|
||||
if (lpParseContext != 0) {
|
||||
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
|
||||
return false;
|
||||
}
|
||||
|
||||
TThreadParseContext *lpThreadData = new TThreadParseContext();
|
||||
if (lpThreadData == 0) {
|
||||
assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
|
||||
return false;
|
||||
}
|
||||
|
||||
lpThreadData->lpGlobalParseContext = 0;
|
||||
OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FreeParseContext()
|
||||
{
|
||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "FreeParseContext(): Parse Context index not initalized");
|
||||
return false;
|
||||
}
|
||||
|
||||
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
|
||||
if (lpParseContext)
|
||||
delete lpParseContext;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TParseContextPointer& GetGlobalParseContext()
|
||||
{
|
||||
//
|
||||
// Minimal error checking for speed
|
||||
//
|
||||
|
||||
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
|
||||
|
||||
return lpParseContext->lpGlobalParseContext;
|
||||
}
|
||||
|
26
src/3rdparty/angle/src/compiler/InitializeParseContext.h
vendored
Normal file
26
src/3rdparty/angle/src/compiler/InitializeParseContext.h
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
||||
#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
||||
|
||||
bool InitializeParseContextIndex();
|
||||
bool FreeParseContextIndex();
|
||||
|
||||
bool InitializeGlobalParseContext();
|
||||
bool FreeParseContext();
|
||||
|
||||
struct TParseContext;
|
||||
typedef TParseContext* TParseContextPointer;
|
||||
extern TParseContextPointer& GetGlobalParseContext();
|
||||
#define GlobalParseContext GetGlobalParseContext()
|
||||
|
||||
typedef struct TThreadParseContextRec
|
||||
{
|
||||
TParseContext *lpGlobalParseContext;
|
||||
} TThreadParseContext;
|
||||
|
||||
#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
293
src/3rdparty/angle/src/compiler/IntermTraverse.cpp
vendored
Normal file
293
src/3rdparty/angle/src/compiler/IntermTraverse.cpp
vendored
Normal file
@ -0,0 +1,293 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
//
|
||||
// Traverse the intermediate representation tree, and
|
||||
// call a node type specific function for each node.
|
||||
// Done recursively through the member function Traverse().
|
||||
// Node types can be skipped if their function to call is 0,
|
||||
// but their subtree will still be traversed.
|
||||
// Nodes with children can have their whole subtree skipped
|
||||
// if preVisit is turned on and the type specific function
|
||||
// returns false.
|
||||
//
|
||||
// preVisit, postVisit, and rightToLeft control what order
|
||||
// nodes are visited in.
|
||||
//
|
||||
|
||||
//
|
||||
// Traversal functions for terminals are straighforward....
|
||||
//
|
||||
void TIntermSymbol::traverse(TIntermTraverser* it)
|
||||
{
|
||||
it->visitSymbol(this);
|
||||
}
|
||||
|
||||
void TIntermConstantUnion::traverse(TIntermTraverser* it)
|
||||
{
|
||||
it->visitConstantUnion(this);
|
||||
}
|
||||
|
||||
//
|
||||
// Traverse a binary node.
|
||||
//
|
||||
void TIntermBinary::traverse(TIntermTraverser* it)
|
||||
{
|
||||
bool visit = true;
|
||||
|
||||
//
|
||||
// visit the node before children if pre-visiting.
|
||||
//
|
||||
if(it->preVisit)
|
||||
{
|
||||
visit = it->visitBinary(PreVisit, this);
|
||||
}
|
||||
|
||||
//
|
||||
// Visit the children, in the right order.
|
||||
//
|
||||
if(visit)
|
||||
{
|
||||
it->incrementDepth();
|
||||
|
||||
if(it->rightToLeft)
|
||||
{
|
||||
if(right)
|
||||
{
|
||||
right->traverse(it);
|
||||
}
|
||||
|
||||
if(it->inVisit)
|
||||
{
|
||||
visit = it->visitBinary(InVisit, this);
|
||||
}
|
||||
|
||||
if(visit && left)
|
||||
{
|
||||
left->traverse(it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(left)
|
||||
{
|
||||
left->traverse(it);
|
||||
}
|
||||
|
||||
if(it->inVisit)
|
||||
{
|
||||
visit = it->visitBinary(InVisit, this);
|
||||
}
|
||||
|
||||
if(visit && right)
|
||||
{
|
||||
right->traverse(it);
|
||||
}
|
||||
}
|
||||
|
||||
it->decrementDepth();
|
||||
}
|
||||
|
||||
//
|
||||
// Visit the node after the children, if requested and the traversal
|
||||
// hasn't been cancelled yet.
|
||||
//
|
||||
if(visit && it->postVisit)
|
||||
{
|
||||
it->visitBinary(PostVisit, this);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Traverse a unary node. Same comments in binary node apply here.
|
||||
//
|
||||
void TIntermUnary::traverse(TIntermTraverser* it)
|
||||
{
|
||||
bool visit = true;
|
||||
|
||||
if (it->preVisit)
|
||||
visit = it->visitUnary(PreVisit, this);
|
||||
|
||||
if (visit) {
|
||||
it->incrementDepth();
|
||||
operand->traverse(it);
|
||||
it->decrementDepth();
|
||||
}
|
||||
|
||||
if (visit && it->postVisit)
|
||||
it->visitUnary(PostVisit, this);
|
||||
}
|
||||
|
||||
//
|
||||
// Traverse an aggregate node. Same comments in binary node apply here.
|
||||
//
|
||||
void TIntermAggregate::traverse(TIntermTraverser* it)
|
||||
{
|
||||
bool visit = true;
|
||||
|
||||
if(it->preVisit)
|
||||
{
|
||||
visit = it->visitAggregate(PreVisit, this);
|
||||
}
|
||||
|
||||
if(visit)
|
||||
{
|
||||
it->incrementDepth();
|
||||
|
||||
if(it->rightToLeft)
|
||||
{
|
||||
for(TIntermSequence::reverse_iterator sit = sequence.rbegin(); sit != sequence.rend(); sit++)
|
||||
{
|
||||
(*sit)->traverse(it);
|
||||
|
||||
if(visit && it->inVisit)
|
||||
{
|
||||
if(*sit != sequence.front())
|
||||
{
|
||||
visit = it->visitAggregate(InVisit, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
|
||||
{
|
||||
(*sit)->traverse(it);
|
||||
|
||||
if(visit && it->inVisit)
|
||||
{
|
||||
if(*sit != sequence.back())
|
||||
{
|
||||
visit = it->visitAggregate(InVisit, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it->decrementDepth();
|
||||
}
|
||||
|
||||
if(visit && it->postVisit)
|
||||
{
|
||||
it->visitAggregate(PostVisit, this);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Traverse a selection node. Same comments in binary node apply here.
|
||||
//
|
||||
void TIntermSelection::traverse(TIntermTraverser* it)
|
||||
{
|
||||
bool visit = true;
|
||||
|
||||
if (it->preVisit)
|
||||
visit = it->visitSelection(PreVisit, this);
|
||||
|
||||
if (visit) {
|
||||
it->incrementDepth();
|
||||
if (it->rightToLeft) {
|
||||
if (falseBlock)
|
||||
falseBlock->traverse(it);
|
||||
if (trueBlock)
|
||||
trueBlock->traverse(it);
|
||||
condition->traverse(it);
|
||||
} else {
|
||||
condition->traverse(it);
|
||||
if (trueBlock)
|
||||
trueBlock->traverse(it);
|
||||
if (falseBlock)
|
||||
falseBlock->traverse(it);
|
||||
}
|
||||
it->decrementDepth();
|
||||
}
|
||||
|
||||
if (visit && it->postVisit)
|
||||
it->visitSelection(PostVisit, this);
|
||||
}
|
||||
|
||||
//
|
||||
// Traverse a loop node. Same comments in binary node apply here.
|
||||
//
|
||||
void TIntermLoop::traverse(TIntermTraverser* it)
|
||||
{
|
||||
bool visit = true;
|
||||
|
||||
if(it->preVisit)
|
||||
{
|
||||
visit = it->visitLoop(PreVisit, this);
|
||||
}
|
||||
|
||||
if(visit)
|
||||
{
|
||||
it->incrementDepth();
|
||||
|
||||
if(it->rightToLeft)
|
||||
{
|
||||
if(expr)
|
||||
{
|
||||
expr->traverse(it);
|
||||
}
|
||||
|
||||
if(body)
|
||||
{
|
||||
body->traverse(it);
|
||||
}
|
||||
|
||||
if(cond)
|
||||
{
|
||||
cond->traverse(it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cond)
|
||||
{
|
||||
cond->traverse(it);
|
||||
}
|
||||
|
||||
if(body)
|
||||
{
|
||||
body->traverse(it);
|
||||
}
|
||||
|
||||
if(expr)
|
||||
{
|
||||
expr->traverse(it);
|
||||
}
|
||||
}
|
||||
|
||||
it->decrementDepth();
|
||||
}
|
||||
|
||||
if(visit && it->postVisit)
|
||||
{
|
||||
it->visitLoop(PostVisit, this);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Traverse a branch node. Same comments in binary node apply here.
|
||||
//
|
||||
void TIntermBranch::traverse(TIntermTraverser* it)
|
||||
{
|
||||
bool visit = true;
|
||||
|
||||
if (it->preVisit)
|
||||
visit = it->visitBranch(PreVisit, this);
|
||||
|
||||
if (visit && expression) {
|
||||
it->incrementDepth();
|
||||
expression->traverse(it);
|
||||
it->decrementDepth();
|
||||
}
|
||||
|
||||
if (visit && it->postVisit)
|
||||
it->visitBranch(PostVisit, this);
|
||||
}
|
||||
|
1447
src/3rdparty/angle/src/compiler/Intermediate.cpp
vendored
Normal file
1447
src/3rdparty/angle/src/compiler/Intermediate.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
56
src/3rdparty/angle/src/compiler/MMap.h
vendored
Normal file
56
src/3rdparty/angle/src/compiler/MMap.h
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef _MMAP_INCLUDED_
|
||||
#define _MMAP_INCLUDED_
|
||||
|
||||
//
|
||||
// Encapsulate memory mapped files
|
||||
//
|
||||
|
||||
class TMMap {
|
||||
public:
|
||||
TMMap(const char* fileName) :
|
||||
fSize(-1), // -1 is the error value returned by GetFileSize()
|
||||
fp(NULL),
|
||||
fBuff(0) // 0 is the error value returned by MapViewOfFile()
|
||||
{
|
||||
if ((fp = fopen(fileName, "r")) == NULL)
|
||||
return;
|
||||
char c = getc(fp);
|
||||
fSize = 0;
|
||||
while (c != EOF) {
|
||||
fSize++;
|
||||
c = getc(fp);
|
||||
}
|
||||
if (c == EOF)
|
||||
fSize++;
|
||||
rewind(fp);
|
||||
fBuff = (char*)malloc(sizeof(char) * fSize);
|
||||
int count = 0;
|
||||
c = getc(fp);
|
||||
while (c != EOF) {
|
||||
fBuff[count++] = c;
|
||||
c = getc(fp);
|
||||
}
|
||||
fBuff[count++] = c;
|
||||
}
|
||||
|
||||
char* getData() { return fBuff; }
|
||||
int getSize() { return fSize; }
|
||||
|
||||
~TMMap() {
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
private:
|
||||
int fSize; // size of file to map in
|
||||
FILE *fp;
|
||||
char* fBuff; // the actual data;
|
||||
};
|
||||
|
||||
#endif // _MMAP_INCLUDED_
|
122
src/3rdparty/angle/src/compiler/MapLongVariableNames.cpp
vendored
Normal file
122
src/3rdparty/angle/src/compiler/MapLongVariableNames.cpp
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
//
|
||||
// Copyright (c) 2002-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 "compiler/MapLongVariableNames.h"
|
||||
|
||||
namespace {
|
||||
|
||||
TString mapLongName(int id, const TString& name, bool isGlobal)
|
||||
{
|
||||
ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE);
|
||||
TStringStream stream;
|
||||
stream << "webgl_";
|
||||
if (isGlobal)
|
||||
stream << "g";
|
||||
stream << id;
|
||||
if (name[0] != '_')
|
||||
stream << "_";
|
||||
stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size());
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
LongNameMap* gLongNameMapInstance = NULL;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
LongNameMap::LongNameMap()
|
||||
: refCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
LongNameMap::~LongNameMap()
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
LongNameMap* LongNameMap::GetInstance()
|
||||
{
|
||||
if (gLongNameMapInstance == NULL)
|
||||
gLongNameMapInstance = new LongNameMap;
|
||||
gLongNameMapInstance->refCount++;
|
||||
return gLongNameMapInstance;
|
||||
}
|
||||
|
||||
void LongNameMap::Release()
|
||||
{
|
||||
ASSERT(gLongNameMapInstance == this);
|
||||
ASSERT(refCount > 0);
|
||||
refCount--;
|
||||
if (refCount == 0) {
|
||||
delete gLongNameMapInstance;
|
||||
gLongNameMapInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* LongNameMap::Find(const char* originalName) const
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator it = mLongNameMap.find(
|
||||
originalName);
|
||||
if (it != mLongNameMap.end())
|
||||
return (*it).second.c_str();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LongNameMap::Insert(const char* originalName, const char* mappedName)
|
||||
{
|
||||
mLongNameMap.insert(std::map<std::string, std::string>::value_type(
|
||||
originalName, mappedName));
|
||||
}
|
||||
|
||||
int LongNameMap::Size() const
|
||||
{
|
||||
return mLongNameMap.size();
|
||||
}
|
||||
|
||||
MapLongVariableNames::MapLongVariableNames(LongNameMap* globalMap)
|
||||
{
|
||||
ASSERT(globalMap);
|
||||
mGlobalMap = globalMap;
|
||||
}
|
||||
|
||||
void MapLongVariableNames::visitSymbol(TIntermSymbol* symbol)
|
||||
{
|
||||
ASSERT(symbol != NULL);
|
||||
if (symbol->getSymbol().size() > MAX_SHORTENED_IDENTIFIER_SIZE) {
|
||||
switch (symbol->getQualifier()) {
|
||||
case EvqVaryingIn:
|
||||
case EvqVaryingOut:
|
||||
case EvqInvariantVaryingIn:
|
||||
case EvqInvariantVaryingOut:
|
||||
case EvqUniform:
|
||||
symbol->setSymbol(
|
||||
mapGlobalLongName(symbol->getSymbol()));
|
||||
break;
|
||||
default:
|
||||
symbol->setSymbol(
|
||||
mapLongName(symbol->getId(), symbol->getSymbol(), false));
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
bool MapLongVariableNames::visitLoop(Visit, TIntermLoop* node)
|
||||
{
|
||||
if (node->getInit())
|
||||
node->getInit()->traverse(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
TString MapLongVariableNames::mapGlobalLongName(const TString& name)
|
||||
{
|
||||
ASSERT(mGlobalMap);
|
||||
const char* mappedName = mGlobalMap->Find(name.c_str());
|
||||
if (mappedName != NULL)
|
||||
return mappedName;
|
||||
int id = mGlobalMap->Size();
|
||||
TString rt = mapLongName(id, name, true);
|
||||
mGlobalMap->Insert(name.c_str(), rt.c_str());
|
||||
return rt;
|
||||
}
|
59
src/3rdparty/angle/src/compiler/MapLongVariableNames.h
vendored
Normal file
59
src/3rdparty/angle/src/compiler/MapLongVariableNames.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// Copyright (c) 2002-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 COMPILER_MAP_LONG_VARIABLE_NAMES_H_
|
||||
#define COMPILER_MAP_LONG_VARIABLE_NAMES_H_
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
#include "compiler/VariableInfo.h"
|
||||
|
||||
// This size does not include '\0' in the end.
|
||||
#define MAX_SHORTENED_IDENTIFIER_SIZE 32
|
||||
|
||||
// This is a ref-counted singleton. GetInstance() returns a pointer to the
|
||||
// singleton, and after use, call Release(). GetInstance() and Release() should
|
||||
// be paired.
|
||||
class LongNameMap {
|
||||
public:
|
||||
static LongNameMap* GetInstance();
|
||||
void Release();
|
||||
|
||||
// Return the mapped name if <originalName, mappedName> is in the map;
|
||||
// otherwise, return NULL.
|
||||
const char* Find(const char* originalName) const;
|
||||
|
||||
// Insert a pair into the map.
|
||||
void Insert(const char* originalName, const char* mappedName);
|
||||
|
||||
// Return the number of entries in the map.
|
||||
int Size() const;
|
||||
|
||||
private:
|
||||
LongNameMap();
|
||||
~LongNameMap();
|
||||
|
||||
size_t refCount;
|
||||
std::map<std::string, std::string> mLongNameMap;
|
||||
};
|
||||
|
||||
// Traverses intermediate tree to map attributes and uniforms names that are
|
||||
// longer than MAX_SHORTENED_IDENTIFIER_SIZE to MAX_SHORTENED_IDENTIFIER_SIZE.
|
||||
class MapLongVariableNames : public TIntermTraverser {
|
||||
public:
|
||||
MapLongVariableNames(LongNameMap* globalMap);
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol*);
|
||||
virtual bool visitLoop(Visit, TIntermLoop*);
|
||||
|
||||
private:
|
||||
TString mapGlobalLongName(const TString& name);
|
||||
|
||||
LongNameMap* mGlobalMap;
|
||||
};
|
||||
|
||||
#endif // COMPILER_MAP_LONG_VARIABLE_NAMES_H_
|
22
src/3rdparty/angle/src/compiler/OutputESSL.cpp
vendored
Normal file
22
src/3rdparty/angle/src/compiler/OutputESSL.cpp
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// 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 "compiler/OutputESSL.h"
|
||||
|
||||
TOutputESSL::TOutputESSL(TInfoSinkBase& objSink)
|
||||
: TOutputGLSLBase(objSink)
|
||||
{
|
||||
}
|
||||
|
||||
bool TOutputESSL::writeVariablePrecision(TPrecision precision)
|
||||
{
|
||||
if (precision == EbpUndefined)
|
||||
return false;
|
||||
|
||||
TInfoSinkBase& out = objSink();
|
||||
out << getPrecisionString(precision);
|
||||
return true;
|
||||
}
|
21
src/3rdparty/angle/src/compiler/OutputESSL.h
vendored
Normal file
21
src/3rdparty/angle/src/compiler/OutputESSL.h
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef CROSSCOMPILERGLSL_OUTPUTESSL_H_
|
||||
#define CROSSCOMPILERGLSL_OUTPUTESSL_H_
|
||||
|
||||
#include "compiler/OutputGLSLBase.h"
|
||||
|
||||
class TOutputESSL : public TOutputGLSLBase
|
||||
{
|
||||
public:
|
||||
TOutputESSL(TInfoSinkBase& objSink);
|
||||
|
||||
protected:
|
||||
virtual bool writeVariablePrecision(TPrecision precision);
|
||||
};
|
||||
|
||||
#endif // CROSSCOMPILERGLSL_OUTPUTESSL_H_
|
17
src/3rdparty/angle/src/compiler/OutputGLSL.cpp
vendored
Normal file
17
src/3rdparty/angle/src/compiler/OutputGLSL.cpp
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// 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 "compiler/OutputGLSL.h"
|
||||
|
||||
TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink)
|
||||
: TOutputGLSLBase(objSink)
|
||||
{
|
||||
}
|
||||
|
||||
bool TOutputGLSL::writeVariablePrecision(TPrecision)
|
||||
{
|
||||
return false;
|
||||
}
|
21
src/3rdparty/angle/src/compiler/OutputGLSL.h
vendored
Normal file
21
src/3rdparty/angle/src/compiler/OutputGLSL.h
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef CROSSCOMPILERGLSL_OUTPUTGLSL_H_
|
||||
#define CROSSCOMPILERGLSL_OUTPUTGLSL_H_
|
||||
|
||||
#include "compiler/OutputGLSLBase.h"
|
||||
|
||||
class TOutputGLSL : public TOutputGLSLBase
|
||||
{
|
||||
public:
|
||||
TOutputGLSL(TInfoSinkBase& objSink);
|
||||
|
||||
protected:
|
||||
virtual bool writeVariablePrecision(TPrecision);
|
||||
};
|
||||
|
||||
#endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
|
720
src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp
vendored
Normal file
720
src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp
vendored
Normal file
@ -0,0 +1,720 @@
|
||||
//
|
||||
// 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 "compiler/OutputGLSLBase.h"
|
||||
#include "compiler/debug.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
TString getTypeName(const TType& type)
|
||||
{
|
||||
TInfoSinkBase out;
|
||||
if (type.isMatrix())
|
||||
{
|
||||
out << "mat";
|
||||
out << type.getNominalSize();
|
||||
}
|
||||
else if (type.isVector())
|
||||
{
|
||||
switch (type.getBasicType())
|
||||
{
|
||||
case EbtFloat: out << "vec"; break;
|
||||
case EbtInt: out << "ivec"; break;
|
||||
case EbtBool: out << "bvec"; break;
|
||||
default: UNREACHABLE(); break;
|
||||
}
|
||||
out << type.getNominalSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type.getBasicType() == EbtStruct)
|
||||
out << type.getTypeName();
|
||||
else
|
||||
out << type.getBasicString();
|
||||
}
|
||||
return TString(out.c_str());
|
||||
}
|
||||
|
||||
TString arrayBrackets(const TType& type)
|
||||
{
|
||||
ASSERT(type.isArray());
|
||||
TInfoSinkBase out;
|
||||
out << "[" << type.getArraySize() << "]";
|
||||
return TString(out.c_str());
|
||||
}
|
||||
|
||||
bool isSingleStatement(TIntermNode* node) {
|
||||
if (const TIntermAggregate* aggregate = node->getAsAggregate())
|
||||
{
|
||||
return (aggregate->getOp() != EOpFunction) &&
|
||||
(aggregate->getOp() != EOpSequence);
|
||||
}
|
||||
else if (const TIntermSelection* selection = node->getAsSelectionNode())
|
||||
{
|
||||
// Ternary operators are usually part of an assignment operator.
|
||||
// This handles those rare cases in which they are all by themselves.
|
||||
return selection->usesTernaryOperator();
|
||||
}
|
||||
else if (node->getAsLoopNode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink)
|
||||
: TIntermTraverser(true, true, true),
|
||||
mObjSink(objSink),
|
||||
mDeclaringVariables(false)
|
||||
{
|
||||
}
|
||||
|
||||
void TOutputGLSLBase::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr)
|
||||
{
|
||||
TInfoSinkBase& out = objSink();
|
||||
if (visit == PreVisit && preStr)
|
||||
{
|
||||
out << preStr;
|
||||
}
|
||||
else if (visit == InVisit && inStr)
|
||||
{
|
||||
out << inStr;
|
||||
}
|
||||
else if (visit == PostVisit && postStr)
|
||||
{
|
||||
out << postStr;
|
||||
}
|
||||
}
|
||||
|
||||
void TOutputGLSLBase::writeVariableType(const TType& type)
|
||||
{
|
||||
TInfoSinkBase& out = objSink();
|
||||
TQualifier qualifier = type.getQualifier();
|
||||
// TODO(alokp): Validate qualifier for variable declarations.
|
||||
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
|
||||
out << type.getQualifierString() << " ";
|
||||
// Declare the struct if we have not done so already.
|
||||
if ((type.getBasicType() == EbtStruct) &&
|
||||
(mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
|
||||
{
|
||||
out << "struct " << type.getTypeName() << "{\n";
|
||||
const TTypeList* structure = type.getStruct();
|
||||
ASSERT(structure != NULL);
|
||||
for (size_t i = 0; i < structure->size(); ++i)
|
||||
{
|
||||
const TType* fieldType = (*structure)[i].type;
|
||||
ASSERT(fieldType != NULL);
|
||||
if (writeVariablePrecision(fieldType->getPrecision()))
|
||||
out << " ";
|
||||
out << getTypeName(*fieldType) << " " << fieldType->getFieldName();
|
||||
if (fieldType->isArray())
|
||||
out << arrayBrackets(*fieldType);
|
||||
out << ";\n";
|
||||
}
|
||||
out << "}";
|
||||
mDeclaredStructs.insert(type.getTypeName());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (writeVariablePrecision(type.getPrecision()))
|
||||
out << " ";
|
||||
out << getTypeName(type);
|
||||
}
|
||||
}
|
||||
|
||||
void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence& args)
|
||||
{
|
||||
TInfoSinkBase& out = objSink();
|
||||
for (TIntermSequence::const_iterator iter = args.begin();
|
||||
iter != args.end(); ++iter)
|
||||
{
|
||||
const TIntermSymbol* arg = (*iter)->getAsSymbolNode();
|
||||
ASSERT(arg != NULL);
|
||||
|
||||
const TType& type = arg->getType();
|
||||
writeVariableType(type);
|
||||
|
||||
const TString& name = arg->getSymbol();
|
||||
if (!name.empty())
|
||||
out << " " << name;
|
||||
if (type.isArray())
|
||||
out << arrayBrackets(type);
|
||||
|
||||
// Put a comma if this is not the last argument.
|
||||
if (iter != args.end() - 1)
|
||||
out << ", ";
|
||||
}
|
||||
}
|
||||
|
||||
const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
|
||||
const ConstantUnion* pConstUnion)
|
||||
{
|
||||
TInfoSinkBase& out = objSink();
|
||||
|
||||
if (type.getBasicType() == EbtStruct)
|
||||
{
|
||||
out << type.getTypeName() << "(";
|
||||
const TTypeList* structure = type.getStruct();
|
||||
ASSERT(structure != NULL);
|
||||
for (size_t i = 0; i < structure->size(); ++i)
|
||||
{
|
||||
const TType* fieldType = (*structure)[i].type;
|
||||
ASSERT(fieldType != NULL);
|
||||
pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
|
||||
if (i != structure->size() - 1) out << ", ";
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
int size = type.getObjectSize();
|
||||
bool writeType = size > 1;
|
||||
if (writeType) out << getTypeName(type) << "(";
|
||||
for (int i = 0; i < size; ++i, ++pConstUnion)
|
||||
{
|
||||
switch (pConstUnion->getType())
|
||||
{
|
||||
case EbtFloat: out << pConstUnion->getFConst(); break;
|
||||
case EbtInt: out << pConstUnion->getIConst(); break;
|
||||
case EbtBool: out << pConstUnion->getBConst(); break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
if (i != size - 1) out << ", ";
|
||||
}
|
||||
if (writeType) out << ")";
|
||||
}
|
||||
return pConstUnion;
|
||||
}
|
||||
|
||||
void TOutputGLSLBase::visitSymbol(TIntermSymbol* node)
|
||||
{
|
||||
TInfoSinkBase& out = objSink();
|
||||
if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node))
|
||||
out << mLoopUnroll.GetLoopIndexValue(node);
|
||||
else
|
||||
out << node->getSymbol();
|
||||
|
||||
if (mDeclaringVariables && node->getType().isArray())
|
||||
out << arrayBrackets(node->getType());
|
||||
}
|
||||
|
||||
void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion* node)
|
||||
{
|
||||
writeConstantUnion(node->getType(), node->getUnionArrayPointer());
|
||||
}
|
||||
|
||||
bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
|
||||
{
|
||||
bool visitChildren = true;
|
||||
TInfoSinkBase& out = objSink();
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpInitialize:
|
||||
if (visit == InVisit)
|
||||
{
|
||||
out << " = ";
|
||||
// RHS of initialize is not being declared.
|
||||
mDeclaringVariables = false;
|
||||
}
|
||||
break;
|
||||
case EOpAssign: writeTriplet(visit, "(", " = ", ")"); break;
|
||||
case EOpAddAssign: writeTriplet(visit, "(", " += ", ")"); break;
|
||||
case EOpSubAssign: writeTriplet(visit, "(", " -= ", ")"); break;
|
||||
case EOpDivAssign: writeTriplet(visit, "(", " /= ", ")"); break;
|
||||
// Notice the fall-through.
|
||||
case EOpMulAssign:
|
||||
case EOpVectorTimesMatrixAssign:
|
||||
case EOpVectorTimesScalarAssign:
|
||||
case EOpMatrixTimesScalarAssign:
|
||||
case EOpMatrixTimesMatrixAssign:
|
||||
writeTriplet(visit, "(", " *= ", ")");
|
||||
break;
|
||||
|
||||
case EOpIndexDirect:
|
||||
case EOpIndexIndirect:
|
||||
writeTriplet(visit, NULL, "[", "]");
|
||||
break;
|
||||
case EOpIndexDirectStruct:
|
||||
if (visit == InVisit)
|
||||
{
|
||||
out << ".";
|
||||
// TODO(alokp): ASSERT
|
||||
out << node->getType().getFieldName();
|
||||
visitChildren = false;
|
||||
}
|
||||
break;
|
||||
case EOpVectorSwizzle:
|
||||
if (visit == InVisit)
|
||||
{
|
||||
out << ".";
|
||||
TIntermAggregate* rightChild = node->getRight()->getAsAggregate();
|
||||
TIntermSequence& sequence = rightChild->getSequence();
|
||||
for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit)
|
||||
{
|
||||
TIntermConstantUnion* element = (*sit)->getAsConstantUnion();
|
||||
ASSERT(element->getBasicType() == EbtInt);
|
||||
ASSERT(element->getNominalSize() == 1);
|
||||
const ConstantUnion& data = element->getUnionArrayPointer()[0];
|
||||
ASSERT(data.getType() == EbtInt);
|
||||
switch (data.getIConst())
|
||||
{
|
||||
case 0: out << "x"; break;
|
||||
case 1: out << "y"; break;
|
||||
case 2: out << "z"; break;
|
||||
case 3: out << "w"; break;
|
||||
default: UNREACHABLE(); break;
|
||||
}
|
||||
}
|
||||
visitChildren = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpAdd: writeTriplet(visit, "(", " + ", ")"); break;
|
||||
case EOpSub: writeTriplet(visit, "(", " - ", ")"); break;
|
||||
case EOpMul: writeTriplet(visit, "(", " * ", ")"); break;
|
||||
case EOpDiv: writeTriplet(visit, "(", " / ", ")"); break;
|
||||
case EOpMod: UNIMPLEMENTED(); break;
|
||||
case EOpEqual: writeTriplet(visit, "(", " == ", ")"); break;
|
||||
case EOpNotEqual: writeTriplet(visit, "(", " != ", ")"); break;
|
||||
case EOpLessThan: writeTriplet(visit, "(", " < ", ")"); break;
|
||||
case EOpGreaterThan: writeTriplet(visit, "(", " > ", ")"); break;
|
||||
case EOpLessThanEqual: writeTriplet(visit, "(", " <= ", ")"); break;
|
||||
case EOpGreaterThanEqual: writeTriplet(visit, "(", " >= ", ")"); break;
|
||||
|
||||
// Notice the fall-through.
|
||||
case EOpVectorTimesScalar:
|
||||
case EOpVectorTimesMatrix:
|
||||
case EOpMatrixTimesVector:
|
||||
case EOpMatrixTimesScalar:
|
||||
case EOpMatrixTimesMatrix:
|
||||
writeTriplet(visit, "(", " * ", ")");
|
||||
break;
|
||||
|
||||
case EOpLogicalOr: writeTriplet(visit, "(", " || ", ")"); break;
|
||||
case EOpLogicalXor: writeTriplet(visit, "(", " ^^ ", ")"); break;
|
||||
case EOpLogicalAnd: writeTriplet(visit, "(", " && ", ")"); break;
|
||||
default: UNREACHABLE(); break;
|
||||
}
|
||||
|
||||
return visitChildren;
|
||||
}
|
||||
|
||||
bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary* node)
|
||||
{
|
||||
TString preString;
|
||||
TString postString = ")";
|
||||
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpNegative: preString = "(-"; break;
|
||||
case EOpVectorLogicalNot: preString = "not("; break;
|
||||
case EOpLogicalNot: preString = "(!"; break;
|
||||
|
||||
case EOpPostIncrement: preString = "("; postString = "++)"; break;
|
||||
case EOpPostDecrement: preString = "("; postString = "--)"; break;
|
||||
case EOpPreIncrement: preString = "(++"; break;
|
||||
case EOpPreDecrement: preString = "(--"; break;
|
||||
|
||||
case EOpConvIntToBool:
|
||||
case EOpConvFloatToBool:
|
||||
switch (node->getOperand()->getType().getNominalSize())
|
||||
{
|
||||
case 1: preString = "bool("; break;
|
||||
case 2: preString = "bvec2("; break;
|
||||
case 3: preString = "bvec3("; break;
|
||||
case 4: preString = "bvec4("; break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
case EOpConvBoolToFloat:
|
||||
case EOpConvIntToFloat:
|
||||
switch (node->getOperand()->getType().getNominalSize())
|
||||
{
|
||||
case 1: preString = "float("; break;
|
||||
case 2: preString = "vec2("; break;
|
||||
case 3: preString = "vec3("; break;
|
||||
case 4: preString = "vec4("; break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
case EOpConvFloatToInt:
|
||||
case EOpConvBoolToInt:
|
||||
switch (node->getOperand()->getType().getNominalSize())
|
||||
{
|
||||
case 1: preString = "int("; break;
|
||||
case 2: preString = "ivec2("; break;
|
||||
case 3: preString = "ivec3("; break;
|
||||
case 4: preString = "ivec4("; break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpRadians: preString = "radians("; break;
|
||||
case EOpDegrees: preString = "degrees("; break;
|
||||
case EOpSin: preString = "sin("; break;
|
||||
case EOpCos: preString = "cos("; break;
|
||||
case EOpTan: preString = "tan("; break;
|
||||
case EOpAsin: preString = "asin("; break;
|
||||
case EOpAcos: preString = "acos("; break;
|
||||
case EOpAtan: preString = "atan("; break;
|
||||
|
||||
case EOpExp: preString = "exp("; break;
|
||||
case EOpLog: preString = "log("; break;
|
||||
case EOpExp2: preString = "exp2("; break;
|
||||
case EOpLog2: preString = "log2("; break;
|
||||
case EOpSqrt: preString = "sqrt("; break;
|
||||
case EOpInverseSqrt: preString = "inversesqrt("; break;
|
||||
|
||||
case EOpAbs: preString = "abs("; break;
|
||||
case EOpSign: preString = "sign("; break;
|
||||
case EOpFloor: preString = "floor("; break;
|
||||
case EOpCeil: preString = "ceil("; break;
|
||||
case EOpFract: preString = "fract("; break;
|
||||
|
||||
case EOpLength: preString = "length("; break;
|
||||
case EOpNormalize: preString = "normalize("; break;
|
||||
|
||||
case EOpDFdx: preString = "dFdx("; break;
|
||||
case EOpDFdy: preString = "dFdy("; break;
|
||||
case EOpFwidth: preString = "fwidth("; break;
|
||||
|
||||
case EOpAny: preString = "any("; break;
|
||||
case EOpAll: preString = "all("; break;
|
||||
|
||||
default: UNREACHABLE(); break;
|
||||
}
|
||||
|
||||
if (visit == PreVisit && node->getUseEmulatedFunction())
|
||||
preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString);
|
||||
writeTriplet(visit, preString.c_str(), NULL, postString.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection* node)
|
||||
{
|
||||
TInfoSinkBase& out = objSink();
|
||||
|
||||
if (node->usesTernaryOperator())
|
||||
{
|
||||
// Notice two brackets at the beginning and end. The outer ones
|
||||
// encapsulate the whole ternary expression. This preserves the
|
||||
// order of precedence when ternary expressions are used in a
|
||||
// compound expression, i.e., c = 2 * (a < b ? 1 : 2).
|
||||
out << "((";
|
||||
node->getCondition()->traverse(this);
|
||||
out << ") ? (";
|
||||
node->getTrueBlock()->traverse(this);
|
||||
out << ") : (";
|
||||
node->getFalseBlock()->traverse(this);
|
||||
out << "))";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "if (";
|
||||
node->getCondition()->traverse(this);
|
||||
out << ")\n";
|
||||
|
||||
incrementDepth();
|
||||
visitCodeBlock(node->getTrueBlock());
|
||||
|
||||
if (node->getFalseBlock())
|
||||
{
|
||||
out << "else\n";
|
||||
visitCodeBlock(node->getFalseBlock());
|
||||
}
|
||||
decrementDepth();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
|
||||
{
|
||||
bool visitChildren = true;
|
||||
TInfoSinkBase& out = objSink();
|
||||
TString preString;
|
||||
bool delayedWrite = false;
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpSequence: {
|
||||
// Scope the sequences except when at the global scope.
|
||||
if (depth > 0) out << "{\n";
|
||||
|
||||
incrementDepth();
|
||||
const TIntermSequence& sequence = node->getSequence();
|
||||
for (TIntermSequence::const_iterator iter = sequence.begin();
|
||||
iter != sequence.end(); ++iter)
|
||||
{
|
||||
TIntermNode* node = *iter;
|
||||
ASSERT(node != NULL);
|
||||
node->traverse(this);
|
||||
|
||||
if (isSingleStatement(node))
|
||||
out << ";\n";
|
||||
}
|
||||
decrementDepth();
|
||||
|
||||
// Scope the sequences except when at the global scope.
|
||||
if (depth > 0) out << "}\n";
|
||||
visitChildren = false;
|
||||
break;
|
||||
}
|
||||
case EOpPrototype: {
|
||||
// Function declaration.
|
||||
ASSERT(visit == PreVisit);
|
||||
writeVariableType(node->getType());
|
||||
out << " " << node->getName();
|
||||
|
||||
out << "(";
|
||||
writeFunctionParameters(node->getSequence());
|
||||
out << ")";
|
||||
|
||||
visitChildren = false;
|
||||
break;
|
||||
}
|
||||
case EOpFunction: {
|
||||
// Function definition.
|
||||
ASSERT(visit == PreVisit);
|
||||
writeVariableType(node->getType());
|
||||
out << " " << TFunction::unmangleName(node->getName());
|
||||
|
||||
incrementDepth();
|
||||
// Function definition node contains one or two children nodes
|
||||
// representing function parameters and function body. The latter
|
||||
// is not present in case of empty function bodies.
|
||||
const TIntermSequence& sequence = node->getSequence();
|
||||
ASSERT((sequence.size() == 1) || (sequence.size() == 2));
|
||||
TIntermSequence::const_iterator seqIter = sequence.begin();
|
||||
|
||||
// Traverse function parameters.
|
||||
TIntermAggregate* params = (*seqIter)->getAsAggregate();
|
||||
ASSERT(params != NULL);
|
||||
ASSERT(params->getOp() == EOpParameters);
|
||||
params->traverse(this);
|
||||
|
||||
// Traverse function body.
|
||||
TIntermAggregate* body = ++seqIter != sequence.end() ?
|
||||
(*seqIter)->getAsAggregate() : NULL;
|
||||
visitCodeBlock(body);
|
||||
decrementDepth();
|
||||
|
||||
// Fully processed; no need to visit children.
|
||||
visitChildren = false;
|
||||
break;
|
||||
}
|
||||
case EOpFunctionCall:
|
||||
// Function call.
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
TString functionName = TFunction::unmangleName(node->getName());
|
||||
out << functionName << "(";
|
||||
}
|
||||
else if (visit == InVisit)
|
||||
{
|
||||
out << ", ";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << ")";
|
||||
}
|
||||
break;
|
||||
case EOpParameters: {
|
||||
// Function parameters.
|
||||
ASSERT(visit == PreVisit);
|
||||
out << "(";
|
||||
writeFunctionParameters(node->getSequence());
|
||||
out << ")";
|
||||
visitChildren = false;
|
||||
break;
|
||||
}
|
||||
case EOpDeclaration: {
|
||||
// Variable declaration.
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
const TIntermSequence& sequence = node->getSequence();
|
||||
const TIntermTyped* variable = sequence.front()->getAsTyped();
|
||||
writeVariableType(variable->getType());
|
||||
out << " ";
|
||||
mDeclaringVariables = true;
|
||||
}
|
||||
else if (visit == InVisit)
|
||||
{
|
||||
out << ", ";
|
||||
mDeclaringVariables = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDeclaringVariables = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break;
|
||||
case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break;
|
||||
case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break;
|
||||
case EOpConstructVec4: writeTriplet(visit, "vec4(", ", ", ")"); break;
|
||||
case EOpConstructBool: writeTriplet(visit, "bool(", NULL, ")"); break;
|
||||
case EOpConstructBVec2: writeTriplet(visit, "bvec2(", ", ", ")"); break;
|
||||
case EOpConstructBVec3: writeTriplet(visit, "bvec3(", ", ", ")"); break;
|
||||
case EOpConstructBVec4: writeTriplet(visit, "bvec4(", ", ", ")"); break;
|
||||
case EOpConstructInt: writeTriplet(visit, "int(", NULL, ")"); break;
|
||||
case EOpConstructIVec2: writeTriplet(visit, "ivec2(", ", ", ")"); break;
|
||||
case EOpConstructIVec3: writeTriplet(visit, "ivec3(", ", ", ")"); break;
|
||||
case EOpConstructIVec4: writeTriplet(visit, "ivec4(", ", ", ")"); break;
|
||||
case EOpConstructMat2: writeTriplet(visit, "mat2(", ", ", ")"); break;
|
||||
case EOpConstructMat3: writeTriplet(visit, "mat3(", ", ", ")"); break;
|
||||
case EOpConstructMat4: writeTriplet(visit, "mat4(", ", ", ")"); break;
|
||||
case EOpConstructStruct:
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
const TType& type = node->getType();
|
||||
ASSERT(type.getBasicType() == EbtStruct);
|
||||
out << type.getTypeName() << "(";
|
||||
}
|
||||
else if (visit == InVisit)
|
||||
{
|
||||
out << ", ";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << ")";
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpLessThan: preString = "lessThan("; delayedWrite = true; break;
|
||||
case EOpGreaterThan: preString = "greaterThan("; delayedWrite = true; break;
|
||||
case EOpLessThanEqual: preString = "lessThanEqual("; delayedWrite = true; break;
|
||||
case EOpGreaterThanEqual: preString = "greaterThanEqual("; delayedWrite = true; break;
|
||||
case EOpVectorEqual: preString = "equal("; delayedWrite = true; break;
|
||||
case EOpVectorNotEqual: preString = "notEqual("; delayedWrite = true; break;
|
||||
case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break;
|
||||
|
||||
case EOpMod: preString = "mod("; delayedWrite = true; break;
|
||||
case EOpPow: preString = "pow("; delayedWrite = true; break;
|
||||
case EOpAtan: preString = "atan("; delayedWrite = true; break;
|
||||
case EOpMin: preString = "min("; delayedWrite = true; break;
|
||||
case EOpMax: preString = "max("; delayedWrite = true; break;
|
||||
case EOpClamp: preString = "clamp("; delayedWrite = true; break;
|
||||
case EOpMix: preString = "mix("; delayedWrite = true; break;
|
||||
case EOpStep: preString = "step("; delayedWrite = true; break;
|
||||
case EOpSmoothStep: preString = "smoothstep("; delayedWrite = true; break;
|
||||
|
||||
case EOpDistance: preString = "distance("; delayedWrite = true; break;
|
||||
case EOpDot: preString = "dot("; delayedWrite = true; break;
|
||||
case EOpCross: preString = "cross("; delayedWrite = true; break;
|
||||
case EOpFaceForward: preString = "faceforward("; delayedWrite = true; break;
|
||||
case EOpReflect: preString = "reflect("; delayedWrite = true; break;
|
||||
case EOpRefract: preString = "refract("; delayedWrite = true; break;
|
||||
case EOpMul: preString = "matrixCompMult("; delayedWrite = true; break;
|
||||
|
||||
default: UNREACHABLE(); break;
|
||||
}
|
||||
if (delayedWrite && visit == PreVisit && node->getUseEmulatedFunction())
|
||||
preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString);
|
||||
if (delayedWrite)
|
||||
writeTriplet(visit, preString.c_str(), ", ", ")");
|
||||
return visitChildren;
|
||||
}
|
||||
|
||||
bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop* node)
|
||||
{
|
||||
TInfoSinkBase& out = objSink();
|
||||
|
||||
incrementDepth();
|
||||
// Loop header.
|
||||
TLoopType loopType = node->getType();
|
||||
if (loopType == ELoopFor) // for loop
|
||||
{
|
||||
if (!node->getUnrollFlag()) {
|
||||
out << "for (";
|
||||
if (node->getInit())
|
||||
node->getInit()->traverse(this);
|
||||
out << "; ";
|
||||
|
||||
if (node->getCondition())
|
||||
node->getCondition()->traverse(this);
|
||||
out << "; ";
|
||||
|
||||
if (node->getExpression())
|
||||
node->getExpression()->traverse(this);
|
||||
out << ")\n";
|
||||
}
|
||||
}
|
||||
else if (loopType == ELoopWhile) // while loop
|
||||
{
|
||||
out << "while (";
|
||||
ASSERT(node->getCondition() != NULL);
|
||||
node->getCondition()->traverse(this);
|
||||
out << ")\n";
|
||||
}
|
||||
else // do-while loop
|
||||
{
|
||||
ASSERT(loopType == ELoopDoWhile);
|
||||
out << "do\n";
|
||||
}
|
||||
|
||||
// Loop body.
|
||||
if (node->getUnrollFlag())
|
||||
{
|
||||
TLoopIndexInfo indexInfo;
|
||||
mLoopUnroll.FillLoopIndexInfo(node, indexInfo);
|
||||
mLoopUnroll.Push(indexInfo);
|
||||
while (mLoopUnroll.SatisfiesLoopCondition())
|
||||
{
|
||||
visitCodeBlock(node->getBody());
|
||||
mLoopUnroll.Step();
|
||||
}
|
||||
mLoopUnroll.Pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
visitCodeBlock(node->getBody());
|
||||
}
|
||||
|
||||
// Loop footer.
|
||||
if (loopType == ELoopDoWhile) // do-while loop
|
||||
{
|
||||
out << "while (";
|
||||
ASSERT(node->getCondition() != NULL);
|
||||
node->getCondition()->traverse(this);
|
||||
out << ");\n";
|
||||
}
|
||||
decrementDepth();
|
||||
|
||||
// No need to visit children. They have been already processed in
|
||||
// this function.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch* node)
|
||||
{
|
||||
switch (node->getFlowOp())
|
||||
{
|
||||
case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break;
|
||||
case EOpBreak: writeTriplet(visit, "break", NULL, NULL); break;
|
||||
case EOpContinue: writeTriplet(visit, "continue", NULL, NULL); break;
|
||||
case EOpReturn: writeTriplet(visit, "return ", NULL, NULL); break;
|
||||
default: UNREACHABLE(); break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) {
|
||||
TInfoSinkBase &out = objSink();
|
||||
if (node != NULL)
|
||||
{
|
||||
node->traverse(this);
|
||||
// Single statements not part of a sequence need to be terminated
|
||||
// with semi-colon.
|
||||
if (isSingleStatement(node))
|
||||
out << ";\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "{\n}\n"; // Empty code block.
|
||||
}
|
||||
}
|
53
src/3rdparty/angle/src/compiler/OutputGLSLBase.h
vendored
Normal file
53
src/3rdparty/angle/src/compiler/OutputGLSLBase.h
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
|
||||
#define CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "compiler/ForLoopUnroll.h"
|
||||
#include "compiler/intermediate.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
|
||||
class TOutputGLSLBase : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
TOutputGLSLBase(TInfoSinkBase& objSink);
|
||||
|
||||
protected:
|
||||
TInfoSinkBase& objSink() { return mObjSink; }
|
||||
void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr);
|
||||
void writeVariableType(const TType& type);
|
||||
virtual bool writeVariablePrecision(TPrecision precision) = 0;
|
||||
void writeFunctionParameters(const TIntermSequence& args);
|
||||
const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion);
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol* node);
|
||||
virtual void visitConstantUnion(TIntermConstantUnion* node);
|
||||
virtual bool visitBinary(Visit visit, TIntermBinary* node);
|
||||
virtual bool visitUnary(Visit visit, TIntermUnary* node);
|
||||
virtual bool visitSelection(Visit visit, TIntermSelection* node);
|
||||
virtual bool visitAggregate(Visit visit, TIntermAggregate* node);
|
||||
virtual bool visitLoop(Visit visit, TIntermLoop* node);
|
||||
virtual bool visitBranch(Visit visit, TIntermBranch* node);
|
||||
|
||||
void visitCodeBlock(TIntermNode* node);
|
||||
|
||||
private:
|
||||
TInfoSinkBase& mObjSink;
|
||||
bool mDeclaringVariables;
|
||||
|
||||
// Structs are declared as the tree is traversed. This set contains all
|
||||
// the structs already declared. It is maintained so that a struct is
|
||||
// declared only once.
|
||||
typedef std::set<TString> DeclaredStructs;
|
||||
DeclaredStructs mDeclaredStructs;
|
||||
|
||||
ForLoopUnroll mLoopUnroll;
|
||||
};
|
||||
|
||||
#endif // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
|
2664
src/3rdparty/angle/src/compiler/OutputHLSL.cpp
vendored
Normal file
2664
src/3rdparty/angle/src/compiler/OutputHLSL.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
152
src/3rdparty/angle/src/compiler/OutputHLSL.h
vendored
Normal file
152
src/3rdparty/angle/src/compiler/OutputHLSL.h
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
//
|
||||
// Copyright (c) 2002-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 COMPILER_OUTPUTHLSL_H_
|
||||
#define COMPILER_OUTPUTHLSL_H_
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
class UnfoldShortCircuit;
|
||||
|
||||
class OutputHLSL : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
explicit OutputHLSL(TParseContext &context);
|
||||
~OutputHLSL();
|
||||
|
||||
void output();
|
||||
|
||||
TInfoSinkBase &getBodyStream();
|
||||
|
||||
TString typeString(const TType &type);
|
||||
static TString qualifierString(TQualifier qualifier);
|
||||
static TString arrayString(const TType &type);
|
||||
static TString initializer(const TType &type);
|
||||
static TString decorate(const TString &string); // Prepends an underscore to avoid naming clashes
|
||||
static TString decorateUniform(const TString &string, const TType &type);
|
||||
static TString decorateField(const TString &string, const TType &structure);
|
||||
|
||||
protected:
|
||||
void header();
|
||||
|
||||
// Visit AST nodes and output their code to the body stream
|
||||
void visitSymbol(TIntermSymbol*);
|
||||
void visitConstantUnion(TIntermConstantUnion*);
|
||||
bool visitBinary(Visit visit, TIntermBinary*);
|
||||
bool visitUnary(Visit visit, TIntermUnary*);
|
||||
bool visitSelection(Visit visit, TIntermSelection*);
|
||||
bool visitAggregate(Visit visit, TIntermAggregate*);
|
||||
bool visitLoop(Visit visit, TIntermLoop*);
|
||||
bool visitBranch(Visit visit, TIntermBranch*);
|
||||
|
||||
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);
|
||||
void outputLineDirective(int line);
|
||||
TString argumentString(const TIntermSymbol *symbol);
|
||||
int vectorSize(const TType &type) const;
|
||||
|
||||
void addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters);
|
||||
const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *constUnion);
|
||||
|
||||
TString scopeString(unsigned int depthLimit);
|
||||
TString scopedStruct(const TString &typeName);
|
||||
TString structLookup(const TString &typeName);
|
||||
|
||||
TParseContext &mContext;
|
||||
UnfoldShortCircuit *mUnfoldShortCircuit;
|
||||
bool mInsideFunction;
|
||||
|
||||
// Output streams
|
||||
TInfoSinkBase mHeader;
|
||||
TInfoSinkBase mBody;
|
||||
TInfoSinkBase mFooter;
|
||||
|
||||
std::set<std::string> mReferencedUniforms;
|
||||
std::set<std::string> mReferencedAttributes;
|
||||
std::set<std::string> mReferencedVaryings;
|
||||
|
||||
// Parameters determining what goes in the header output
|
||||
bool mUsesTexture2D;
|
||||
bool mUsesTexture2D_bias;
|
||||
bool mUsesTexture2DLod;
|
||||
bool mUsesTexture2DProj;
|
||||
bool mUsesTexture2DProj_bias;
|
||||
bool mUsesTexture2DProjLod;
|
||||
bool mUsesTextureCube;
|
||||
bool mUsesTextureCube_bias;
|
||||
bool mUsesTextureCubeLod;
|
||||
bool mUsesTexture2DLod0;
|
||||
bool mUsesTexture2DLod0_bias;
|
||||
bool mUsesTexture2DProjLod0;
|
||||
bool mUsesTexture2DProjLod0_bias;
|
||||
bool mUsesTextureCubeLod0;
|
||||
bool mUsesTextureCubeLod0_bias;
|
||||
bool mUsesDepthRange;
|
||||
bool mUsesFragCoord;
|
||||
bool mUsesPointCoord;
|
||||
bool mUsesFrontFacing;
|
||||
bool mUsesPointSize;
|
||||
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 mUsesEqualMat2;
|
||||
bool mUsesEqualMat3;
|
||||
bool mUsesEqualMat4;
|
||||
bool mUsesEqualVec2;
|
||||
bool mUsesEqualVec3;
|
||||
bool mUsesEqualVec4;
|
||||
bool mUsesEqualIVec2;
|
||||
bool mUsesEqualIVec3;
|
||||
bool mUsesEqualIVec4;
|
||||
bool mUsesEqualBVec2;
|
||||
bool mUsesEqualBVec3;
|
||||
bool mUsesEqualBVec4;
|
||||
bool mUsesAtan2_1;
|
||||
bool mUsesAtan2_2;
|
||||
bool mUsesAtan2_3;
|
||||
bool mUsesAtan2_4;
|
||||
|
||||
typedef std::set<TString> Constructors;
|
||||
Constructors mConstructors;
|
||||
|
||||
typedef std::set<TString> StructNames;
|
||||
StructNames mStructNames;
|
||||
|
||||
typedef std::list<TString> StructDeclarations;
|
||||
StructDeclarations mStructDeclarations;
|
||||
|
||||
typedef std::vector<int> ScopeBracket;
|
||||
ScopeBracket mScopeBracket;
|
||||
unsigned int mScopeDepth;
|
||||
|
||||
int mUniqueIndex; // For creating unique names
|
||||
|
||||
bool mContainsLoopDiscontinuity;
|
||||
bool mOutputLod0Function;
|
||||
bool mInsideDiscontinuousLoop;
|
||||
|
||||
TIntermSymbol *mExcessiveLoopIndex;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // COMPILER_OUTPUTHLSL_H_
|
1528
src/3rdparty/angle/src/compiler/ParseHelper.cpp
vendored
Normal file
1528
src/3rdparty/angle/src/compiler/ParseHelper.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
140
src/3rdparty/angle/src/compiler/ParseHelper.h
vendored
Normal file
140
src/3rdparty/angle/src/compiler/ParseHelper.h
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
//
|
||||
// Copyright (c) 2002-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 _PARSER_HELPER_INCLUDED_
|
||||
#define _PARSER_HELPER_INCLUDED_
|
||||
|
||||
#include "compiler/Diagnostics.h"
|
||||
#include "compiler/DirectiveHandler.h"
|
||||
#include "compiler/localintermediate.h"
|
||||
#include "compiler/preprocessor/new/Preprocessor.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/SymbolTable.h"
|
||||
|
||||
struct TMatrixFields {
|
||||
bool wholeRow;
|
||||
bool wholeCol;
|
||||
int row;
|
||||
int col;
|
||||
};
|
||||
|
||||
//
|
||||
// The following are extra variables needed during parsing, grouped together so
|
||||
// they can be passed to the parser without needing a global.
|
||||
//
|
||||
struct TParseContext {
|
||||
TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
|
||||
intermediate(interm),
|
||||
symbolTable(symt),
|
||||
shaderType(type),
|
||||
shaderSpec(spec),
|
||||
compileOptions(options),
|
||||
sourcePath(sourcePath),
|
||||
treeRoot(0),
|
||||
lexAfterType(false),
|
||||
loopNestingLevel(0),
|
||||
structNestingLevel(0),
|
||||
inTypeParen(false),
|
||||
currentFunctionType(NULL),
|
||||
functionReturnsValue(false),
|
||||
checksPrecisionErrors(checksPrecErrors),
|
||||
diagnostics(is),
|
||||
directiveHandler(ext, diagnostics),
|
||||
preprocessor(&diagnostics, &directiveHandler),
|
||||
scanner(NULL) { }
|
||||
TIntermediate& intermediate; // to hold and build a parse tree
|
||||
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
|
||||
ShShaderType shaderType; // vertex or fragment language (future: pack or unpack)
|
||||
ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
|
||||
int compileOptions;
|
||||
const char* sourcePath; // Path of source file or NULL.
|
||||
TIntermNode* treeRoot; // root of parse tree being created
|
||||
bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier
|
||||
int loopNestingLevel; // 0 if outside all loops
|
||||
int structNestingLevel; // incremented while parsing a struct declaration
|
||||
bool inTypeParen; // true if in parentheses, looking only for an identifier
|
||||
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 checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
|
||||
TString HashErrMsg;
|
||||
bool AfterEOF;
|
||||
TDiagnostics diagnostics;
|
||||
TDirectiveHandler directiveHandler;
|
||||
pp::Preprocessor preprocessor;
|
||||
void* scanner;
|
||||
|
||||
int numErrors() const { return diagnostics.numErrors(); }
|
||||
TInfoSink& infoSink() { return diagnostics.infoSink(); }
|
||||
void error(TSourceLoc loc, const char *reason, const char* token,
|
||||
const char* extraInfo="");
|
||||
void warning(TSourceLoc loc, const char* reason, const char* token,
|
||||
const char* extraInfo="");
|
||||
void trace(const char* str);
|
||||
void recover();
|
||||
|
||||
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
|
||||
bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
|
||||
|
||||
bool reservedErrorCheck(int line, const TString& identifier);
|
||||
void assignError(int line, const char* op, TString left, TString right);
|
||||
void unaryOpError(int line, const char* op, TString operand);
|
||||
void binaryOpError(int line, const char* op, TString left, TString right);
|
||||
bool precisionErrorCheck(int line, TPrecision precision, TBasicType type);
|
||||
bool lValueErrorCheck(int line, const char* op, TIntermTyped*);
|
||||
bool constErrorCheck(TIntermTyped* node);
|
||||
bool integerErrorCheck(TIntermTyped* node, const char* token);
|
||||
bool globalErrorCheck(int line, bool global, const char* token);
|
||||
bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*);
|
||||
bool arraySizeErrorCheck(int line, TIntermTyped* expr, int& size);
|
||||
bool arrayQualifierErrorCheck(int line, TPublicType type);
|
||||
bool arrayTypeErrorCheck(int line, TPublicType type);
|
||||
bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable);
|
||||
bool voidErrorCheck(int, const TString&, const TPublicType&);
|
||||
bool boolErrorCheck(int, const TIntermTyped*);
|
||||
bool boolErrorCheck(int, const TPublicType&);
|
||||
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
|
||||
bool structQualifierErrorCheck(int line, const TPublicType& pType);
|
||||
bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type);
|
||||
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array);
|
||||
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable);
|
||||
bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
|
||||
bool extensionErrorCheck(int line, const TString&);
|
||||
|
||||
const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
|
||||
bool supportsExtension(const char* extension);
|
||||
void handleExtensionDirective(int line, const char* extName, const char* behavior);
|
||||
|
||||
const TPragma& pragma() const { return directiveHandler.pragma(); }
|
||||
void handlePragmaDirective(int line, const char* name, const char* value);
|
||||
|
||||
bool containsSampler(TType& type);
|
||||
bool areAllChildConst(TIntermAggregate* aggrNode);
|
||||
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
|
||||
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
|
||||
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
|
||||
bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
|
||||
|
||||
TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
|
||||
TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
|
||||
TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset);
|
||||
TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, TSourceLoc, bool subset);
|
||||
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
|
||||
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
|
||||
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
|
||||
TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
|
||||
|
||||
// Performs an error check for embedded struct declarations.
|
||||
// Returns true if an error was raised due to the declaration of
|
||||
// this struct.
|
||||
bool enterStructDeclaration(TSourceLoc line, const TString& identifier);
|
||||
void exitStructDeclaration();
|
||||
|
||||
bool structNestingErrorCheck(TSourceLoc line, const TType& fieldType);
|
||||
};
|
||||
|
||||
int PaParseStrings(int count, const char* const string[], const int length[],
|
||||
TParseContext* context);
|
||||
|
||||
#endif // _PARSER_HELPER_INCLUDED_
|
310
src/3rdparty/angle/src/compiler/PoolAlloc.cpp
vendored
Normal file
310
src/3rdparty/angle/src/compiler/PoolAlloc.cpp
vendored
Normal file
@ -0,0 +1,310 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/PoolAlloc.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/InitializeGlobals.h"
|
||||
#include "compiler/osinclude.h"
|
||||
|
||||
OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
void InitializeGlobalPools()
|
||||
{
|
||||
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
|
||||
if (globalPools)
|
||||
return;
|
||||
|
||||
TThreadGlobalPools* threadData = new TThreadGlobalPools();
|
||||
threadData->globalPoolAllocator = 0;
|
||||
|
||||
OS_SetTLSValue(PoolIndex, threadData);
|
||||
}
|
||||
|
||||
void FreeGlobalPools()
|
||||
{
|
||||
// Release the allocated memory for this thread.
|
||||
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
|
||||
if (!globalPools)
|
||||
return;
|
||||
|
||||
delete globalPools;
|
||||
}
|
||||
|
||||
bool InitializePoolIndex()
|
||||
{
|
||||
// Allocate a TLS index.
|
||||
if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreePoolIndex()
|
||||
{
|
||||
// Release the TLS index.
|
||||
OS_FreeTLSIndex(PoolIndex);
|
||||
}
|
||||
|
||||
TPoolAllocator& GetGlobalPoolAllocator()
|
||||
{
|
||||
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
|
||||
|
||||
return *threadData->globalPoolAllocator;
|
||||
}
|
||||
|
||||
void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
|
||||
{
|
||||
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
|
||||
|
||||
threadData->globalPoolAllocator = poolAllocator;
|
||||
}
|
||||
|
||||
//
|
||||
// Implement the functionality of the TPoolAllocator class, which
|
||||
// is documented in PoolAlloc.h.
|
||||
//
|
||||
TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
|
||||
pageSize(growthIncrement),
|
||||
alignment(allocationAlignment),
|
||||
freeList(0),
|
||||
inUseList(0),
|
||||
numCalls(0),
|
||||
totalBytes(0)
|
||||
{
|
||||
//
|
||||
// Don't allow page sizes we know are smaller than all common
|
||||
// OS page sizes.
|
||||
//
|
||||
if (pageSize < 4*1024)
|
||||
pageSize = 4*1024;
|
||||
|
||||
//
|
||||
// A large currentPageOffset indicates a new page needs to
|
||||
// be obtained to allocate memory.
|
||||
//
|
||||
currentPageOffset = pageSize;
|
||||
|
||||
//
|
||||
// Adjust alignment to be at least pointer aligned and
|
||||
// power of 2.
|
||||
//
|
||||
size_t minAlign = sizeof(void*);
|
||||
alignment &= ~(minAlign - 1);
|
||||
if (alignment < minAlign)
|
||||
alignment = minAlign;
|
||||
size_t a = 1;
|
||||
while (a < alignment)
|
||||
a <<= 1;
|
||||
alignment = a;
|
||||
alignmentMask = a - 1;
|
||||
|
||||
//
|
||||
// Align header skip
|
||||
//
|
||||
headerSkip = minAlign;
|
||||
if (headerSkip < sizeof(tHeader)) {
|
||||
headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask;
|
||||
}
|
||||
}
|
||||
|
||||
TPoolAllocator::~TPoolAllocator()
|
||||
{
|
||||
while (inUseList) {
|
||||
tHeader* next = inUseList->nextPage;
|
||||
inUseList->~tHeader();
|
||||
delete [] reinterpret_cast<char*>(inUseList);
|
||||
inUseList = next;
|
||||
}
|
||||
|
||||
// We should not check the guard blocks
|
||||
// here, because we did it already when the block was
|
||||
// placed into the free list.
|
||||
//
|
||||
while (freeList) {
|
||||
tHeader* next = freeList->nextPage;
|
||||
delete [] reinterpret_cast<char*>(freeList);
|
||||
freeList = next;
|
||||
}
|
||||
}
|
||||
|
||||
// Support MSVC++ 6.0
|
||||
const unsigned char TAllocation::guardBlockBeginVal = 0xfb;
|
||||
const unsigned char TAllocation::guardBlockEndVal = 0xfe;
|
||||
const unsigned char TAllocation::userDataFill = 0xcd;
|
||||
|
||||
#ifdef GUARD_BLOCKS
|
||||
const size_t TAllocation::guardBlockSize = 16;
|
||||
#else
|
||||
const size_t TAllocation::guardBlockSize = 0;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Check a single guard block for damage
|
||||
//
|
||||
void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const
|
||||
{
|
||||
#ifdef GUARD_BLOCKS
|
||||
for (size_t x = 0; x < guardBlockSize; x++) {
|
||||
if (blockMem[x] != val) {
|
||||
char assertMsg[80];
|
||||
|
||||
// We don't print the assert message. It's here just to be helpful.
|
||||
#if defined(_MSC_VER)
|
||||
snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n",
|
||||
locText, size, data());
|
||||
#else
|
||||
snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n",
|
||||
locText, size, data());
|
||||
#endif
|
||||
assert(0 && "PoolAlloc: Damage in guard block");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void TPoolAllocator::push()
|
||||
{
|
||||
tAllocState state = { currentPageOffset, inUseList };
|
||||
|
||||
stack.push_back(state);
|
||||
|
||||
//
|
||||
// Indicate there is no current page to allocate from.
|
||||
//
|
||||
currentPageOffset = pageSize;
|
||||
}
|
||||
|
||||
//
|
||||
// Do a mass-deallocation of all the individual allocations
|
||||
// that have occurred since the last push(), or since the
|
||||
// last pop(), or since the object's creation.
|
||||
//
|
||||
// The deallocated pages are saved for future allocations.
|
||||
//
|
||||
void TPoolAllocator::pop()
|
||||
{
|
||||
if (stack.size() < 1)
|
||||
return;
|
||||
|
||||
tHeader* page = stack.back().page;
|
||||
currentPageOffset = stack.back().offset;
|
||||
|
||||
while (inUseList != page) {
|
||||
// invoke destructor to free allocation list
|
||||
inUseList->~tHeader();
|
||||
|
||||
tHeader* nextInUse = inUseList->nextPage;
|
||||
if (inUseList->pageCount > 1)
|
||||
delete [] reinterpret_cast<char*>(inUseList);
|
||||
else {
|
||||
inUseList->nextPage = freeList;
|
||||
freeList = inUseList;
|
||||
}
|
||||
inUseList = nextInUse;
|
||||
}
|
||||
|
||||
stack.pop_back();
|
||||
}
|
||||
|
||||
//
|
||||
// Do a mass-deallocation of all the individual allocations
|
||||
// that have occurred.
|
||||
//
|
||||
void TPoolAllocator::popAll()
|
||||
{
|
||||
while (stack.size() > 0)
|
||||
pop();
|
||||
}
|
||||
|
||||
void* TPoolAllocator::allocate(size_t numBytes)
|
||||
{
|
||||
// If we are using guard blocks, all allocations are bracketed by
|
||||
// them: [guardblock][allocation][guardblock]. numBytes is how
|
||||
// much memory the caller asked for. allocationSize is the total
|
||||
// size including guard blocks. In release build,
|
||||
// guardBlockSize=0 and this all gets optimized away.
|
||||
size_t allocationSize = TAllocation::allocationSize(numBytes);
|
||||
|
||||
//
|
||||
// Just keep some interesting statistics.
|
||||
//
|
||||
++numCalls;
|
||||
totalBytes += numBytes;
|
||||
|
||||
//
|
||||
// Do the allocation, most likely case first, for efficiency.
|
||||
// This step could be moved to be inline sometime.
|
||||
//
|
||||
if (currentPageOffset + allocationSize <= pageSize) {
|
||||
//
|
||||
// Safe to allocate from currentPageOffset.
|
||||
//
|
||||
unsigned char* memory = reinterpret_cast<unsigned char *>(inUseList) + currentPageOffset;
|
||||
currentPageOffset += allocationSize;
|
||||
currentPageOffset = (currentPageOffset + alignmentMask) & ~alignmentMask;
|
||||
|
||||
return initializeAllocation(inUseList, memory, numBytes);
|
||||
}
|
||||
|
||||
if (allocationSize + headerSkip > pageSize) {
|
||||
//
|
||||
// Do a multi-page allocation. Don't mix these with the others.
|
||||
// The OS is efficient and allocating and free-ing multiple pages.
|
||||
//
|
||||
size_t numBytesToAlloc = allocationSize + headerSkip;
|
||||
tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]);
|
||||
if (memory == 0)
|
||||
return 0;
|
||||
|
||||
// Use placement-new to initialize header
|
||||
new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize);
|
||||
inUseList = memory;
|
||||
|
||||
currentPageOffset = pageSize; // make next allocation come from a new page
|
||||
|
||||
// No guard blocks for multi-page allocations (yet)
|
||||
return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(memory) + headerSkip);
|
||||
}
|
||||
|
||||
//
|
||||
// Need a simple page to allocate from.
|
||||
//
|
||||
tHeader* memory;
|
||||
if (freeList) {
|
||||
memory = freeList;
|
||||
freeList = freeList->nextPage;
|
||||
} else {
|
||||
memory = reinterpret_cast<tHeader*>(::new char[pageSize]);
|
||||
if (memory == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Use placement-new to initialize header
|
||||
new(memory) tHeader(inUseList, 1);
|
||||
inUseList = memory;
|
||||
|
||||
unsigned char* ret = reinterpret_cast<unsigned char *>(inUseList) + headerSkip;
|
||||
currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
|
||||
|
||||
return initializeAllocation(inUseList, ret, numBytes);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Check all allocations in a list for damage by calling check on each.
|
||||
//
|
||||
void TAllocation::checkAllocList() const
|
||||
{
|
||||
for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc)
|
||||
alloc->check();
|
||||
}
|
306
src/3rdparty/angle/src/compiler/PoolAlloc.h
vendored
Normal file
306
src/3rdparty/angle/src/compiler/PoolAlloc.h
vendored
Normal file
@ -0,0 +1,306 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef _POOLALLOC_INCLUDED_
|
||||
#define _POOLALLOC_INCLUDED_
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define GUARD_BLOCKS // define to enable guard block sanity checking
|
||||
#endif
|
||||
|
||||
//
|
||||
// This header defines an allocator that can be used to efficiently
|
||||
// allocate a large number of small requests for heap memory, with the
|
||||
// intention that they are not individually deallocated, but rather
|
||||
// collectively deallocated at one time.
|
||||
//
|
||||
// This simultaneously
|
||||
//
|
||||
// * Makes each individual allocation much more efficient; the
|
||||
// typical allocation is trivial.
|
||||
// * Completely avoids the cost of doing individual deallocation.
|
||||
// * Saves the trouble of tracking down and plugging a large class of leaks.
|
||||
//
|
||||
// Individual classes can use this allocator by supplying their own
|
||||
// new and delete methods.
|
||||
//
|
||||
// STL containers can use this allocator by using the pool_allocator
|
||||
// class as the allocator (second) template argument.
|
||||
//
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
// If we are using guard blocks, we must track each indivual
|
||||
// allocation. If we aren't using guard blocks, these
|
||||
// never get instantiated, so won't have any impact.
|
||||
//
|
||||
|
||||
class TAllocation {
|
||||
public:
|
||||
TAllocation(size_t size, unsigned char* mem, TAllocation* prev = 0) :
|
||||
size(size), mem(mem), prevAlloc(prev) {
|
||||
// Allocations are bracketed:
|
||||
// [allocationHeader][initialGuardBlock][userData][finalGuardBlock]
|
||||
// This would be cleaner with if (guardBlockSize)..., but that
|
||||
// makes the compiler print warnings about 0 length memsets,
|
||||
// even with the if() protecting them.
|
||||
#ifdef GUARD_BLOCKS
|
||||
memset(preGuard(), guardBlockBeginVal, guardBlockSize);
|
||||
memset(data(), userDataFill, size);
|
||||
memset(postGuard(), guardBlockEndVal, guardBlockSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
void check() const {
|
||||
checkGuardBlock(preGuard(), guardBlockBeginVal, "before");
|
||||
checkGuardBlock(postGuard(), guardBlockEndVal, "after");
|
||||
}
|
||||
|
||||
void checkAllocList() const;
|
||||
|
||||
// Return total size needed to accomodate user buffer of 'size',
|
||||
// plus our tracking data.
|
||||
inline static size_t allocationSize(size_t size) {
|
||||
return size + 2 * guardBlockSize + headerSize();
|
||||
}
|
||||
|
||||
// Offset from surrounding buffer to get to user data buffer.
|
||||
inline static unsigned char* offsetAllocation(unsigned char* m) {
|
||||
return m + guardBlockSize + headerSize();
|
||||
}
|
||||
|
||||
private:
|
||||
void checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const;
|
||||
|
||||
// Find offsets to pre and post guard blocks, and user data buffer
|
||||
unsigned char* preGuard() const { return mem + headerSize(); }
|
||||
unsigned char* data() const { return preGuard() + guardBlockSize; }
|
||||
unsigned char* postGuard() const { return data() + size; }
|
||||
|
||||
size_t size; // size of the user data area
|
||||
unsigned char* mem; // beginning of our allocation (pts to header)
|
||||
TAllocation* prevAlloc; // prior allocation in the chain
|
||||
|
||||
// Support MSVC++ 6.0
|
||||
const static unsigned char guardBlockBeginVal;
|
||||
const static unsigned char guardBlockEndVal;
|
||||
const static unsigned char userDataFill;
|
||||
|
||||
const static size_t guardBlockSize;
|
||||
#ifdef GUARD_BLOCKS
|
||||
inline static size_t headerSize() { return sizeof(TAllocation); }
|
||||
#else
|
||||
inline static size_t headerSize() { return 0; }
|
||||
#endif
|
||||
};
|
||||
|
||||
//
|
||||
// There are several stacks. One is to track the pushing and popping
|
||||
// of the user, and not yet implemented. The others are simply a
|
||||
// repositories of free pages or used pages.
|
||||
//
|
||||
// Page stacks are linked together with a simple header at the beginning
|
||||
// of each allocation obtained from the underlying OS. Multi-page allocations
|
||||
// are returned to the OS. Individual page allocations are kept for future
|
||||
// re-use.
|
||||
//
|
||||
// The "page size" used is not, nor must it match, the underlying OS
|
||||
// page size. But, having it be about that size or equal to a set of
|
||||
// pages is likely most optimal.
|
||||
//
|
||||
class TPoolAllocator {
|
||||
public:
|
||||
TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16);
|
||||
|
||||
//
|
||||
// Don't call the destructor just to free up the memory, call pop()
|
||||
//
|
||||
~TPoolAllocator();
|
||||
|
||||
//
|
||||
// Call push() to establish a new place to pop memory too. Does not
|
||||
// have to be called to get things started.
|
||||
//
|
||||
void push();
|
||||
|
||||
//
|
||||
// Call pop() to free all memory allocated since the last call to push(),
|
||||
// or if no last call to push, frees all memory since first allocation.
|
||||
//
|
||||
void pop();
|
||||
|
||||
//
|
||||
// Call popAll() to free all memory allocated.
|
||||
//
|
||||
void popAll();
|
||||
|
||||
//
|
||||
// Call allocate() to actually acquire memory. Returns 0 if no memory
|
||||
// available, otherwise a properly aligned pointer to 'numBytes' of memory.
|
||||
//
|
||||
void* allocate(size_t numBytes);
|
||||
|
||||
//
|
||||
// There is no deallocate. The point of this class is that
|
||||
// deallocation can be skipped by the user of it, as the model
|
||||
// of use is to simultaneously deallocate everything at once
|
||||
// by calling pop(), and to not have to solve memory leak problems.
|
||||
//
|
||||
|
||||
protected:
|
||||
friend struct tHeader;
|
||||
|
||||
struct tHeader {
|
||||
tHeader(tHeader* nextPage, size_t pageCount) :
|
||||
nextPage(nextPage),
|
||||
pageCount(pageCount)
|
||||
#ifdef GUARD_BLOCKS
|
||||
, lastAllocation(0)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
~tHeader() {
|
||||
#ifdef GUARD_BLOCKS
|
||||
if (lastAllocation)
|
||||
lastAllocation->checkAllocList();
|
||||
#endif
|
||||
}
|
||||
|
||||
tHeader* nextPage;
|
||||
size_t pageCount;
|
||||
#ifdef GUARD_BLOCKS
|
||||
TAllocation* lastAllocation;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct tAllocState {
|
||||
size_t offset;
|
||||
tHeader* page;
|
||||
};
|
||||
typedef std::vector<tAllocState> tAllocStack;
|
||||
|
||||
// Track allocations if and only if we're using guard blocks
|
||||
void* initializeAllocation(tHeader* block, unsigned char* memory, size_t numBytes) {
|
||||
#ifdef GUARD_BLOCKS
|
||||
new(memory) TAllocation(numBytes, memory, block->lastAllocation);
|
||||
block->lastAllocation = reinterpret_cast<TAllocation*>(memory);
|
||||
#endif
|
||||
// This is optimized entirely away if GUARD_BLOCKS is not defined.
|
||||
return TAllocation::offsetAllocation(memory);
|
||||
}
|
||||
|
||||
size_t pageSize; // granularity of allocation from the OS
|
||||
size_t alignment; // all returned allocations will be aligned at
|
||||
// this granularity, which will be a power of 2
|
||||
size_t alignmentMask;
|
||||
size_t headerSkip; // amount of memory to skip to make room for the
|
||||
// header (basically, size of header, rounded
|
||||
// up to make it aligned
|
||||
size_t currentPageOffset; // next offset in top of inUseList to allocate from
|
||||
tHeader* freeList; // list of popped memory
|
||||
tHeader* inUseList; // list of all memory currently being used
|
||||
tAllocStack stack; // stack of where to allocate from, to partition pool
|
||||
|
||||
int numCalls; // just an interesting statistic
|
||||
size_t totalBytes; // just an interesting statistic
|
||||
private:
|
||||
TPoolAllocator& operator=(const TPoolAllocator&); // dont allow assignment operator
|
||||
TPoolAllocator(const TPoolAllocator&); // dont allow default copy constructor
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// There could potentially be many pools with pops happening at
|
||||
// different times. But a simple use is to have a global pop
|
||||
// with everyone using the same global allocator.
|
||||
//
|
||||
extern TPoolAllocator& GetGlobalPoolAllocator();
|
||||
extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
|
||||
#define GlobalPoolAllocator GetGlobalPoolAllocator()
|
||||
|
||||
struct TThreadGlobalPools
|
||||
{
|
||||
TPoolAllocator* globalPoolAllocator;
|
||||
};
|
||||
|
||||
//
|
||||
// This STL compatible allocator is intended to be used as the allocator
|
||||
// parameter to templatized STL containers, like vector and map.
|
||||
//
|
||||
// It will use the pools for allocation, and not
|
||||
// do any deallocation, but will still do destruction.
|
||||
//
|
||||
template<class T>
|
||||
class pool_allocator {
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
|
||||
template<class Other>
|
||||
struct rebind {
|
||||
typedef pool_allocator<Other> other;
|
||||
};
|
||||
pointer address(reference x) const { return &x; }
|
||||
const_pointer address(const_reference x) const { return &x; }
|
||||
|
||||
pool_allocator() : allocator(&GlobalPoolAllocator) { }
|
||||
pool_allocator(TPoolAllocator& a) : allocator(&a) { }
|
||||
pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
|
||||
|
||||
template <class Other>
|
||||
pool_allocator<T>& operator=(const pool_allocator<Other>& p) {
|
||||
allocator = p.allocator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Other>
|
||||
pool_allocator(const pool_allocator<Other>& p) : allocator(&p.getAllocator()) { }
|
||||
|
||||
#if defined(__SUNPRO_CC) && !defined(_RWSTD_ALLOCATOR)
|
||||
// libCStd on some platforms have a different allocate/deallocate interface.
|
||||
// Caller pre-bakes sizeof(T) into 'n' which is the number of bytes to be
|
||||
// allocated, not the number of elements.
|
||||
void* allocate(size_type n) {
|
||||
return getAllocator().allocate(n);
|
||||
}
|
||||
void* allocate(size_type n, const void*) {
|
||||
return getAllocator().allocate(n);
|
||||
}
|
||||
void deallocate(void*, size_type) {}
|
||||
#else
|
||||
pointer allocate(size_type n) {
|
||||
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
|
||||
}
|
||||
pointer allocate(size_type n, const void*) {
|
||||
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
|
||||
}
|
||||
void deallocate(pointer, size_type) {}
|
||||
#endif // _RWSTD_ALLOCATOR
|
||||
|
||||
void construct(pointer p, const T& val) { new ((void *)p) T(val); }
|
||||
void destroy(pointer p) { p->T::~T(); }
|
||||
|
||||
bool operator==(const pool_allocator& rhs) const { return &getAllocator() == &rhs.getAllocator(); }
|
||||
bool operator!=(const pool_allocator& rhs) const { return &getAllocator() != &rhs.getAllocator(); }
|
||||
|
||||
size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
|
||||
size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
|
||||
|
||||
void setAllocator(TPoolAllocator* a) { allocator = a; }
|
||||
TPoolAllocator& getAllocator() const { return *allocator; }
|
||||
|
||||
protected:
|
||||
TPoolAllocator* allocator;
|
||||
};
|
||||
|
||||
#endif // _POOLALLOC_INCLUDED_
|
19
src/3rdparty/angle/src/compiler/Pragma.h
vendored
Normal file
19
src/3rdparty/angle/src/compiler/Pragma.h
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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 COMPILER_PRAGMA_H_
|
||||
#define COMPILER_PRAGMA_H_
|
||||
|
||||
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) { }
|
||||
|
||||
bool optimize;
|
||||
bool debug;
|
||||
};
|
||||
|
||||
#endif // COMPILER_PRAGMA_H_
|
58
src/3rdparty/angle/src/compiler/QualifierAlive.cpp
vendored
Normal file
58
src/3rdparty/angle/src/compiler/QualifierAlive.cpp
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
class TAliveTraverser : public TIntermTraverser {
|
||||
public:
|
||||
TAliveTraverser(TQualifier q) : TIntermTraverser(true, false, false, true), found(false), qualifier(q)
|
||||
{
|
||||
}
|
||||
|
||||
bool wasFound() { return found; }
|
||||
|
||||
protected:
|
||||
bool found;
|
||||
TQualifier qualifier;
|
||||
|
||||
void visitSymbol(TIntermSymbol*);
|
||||
bool visitSelection(Visit, TIntermSelection*);
|
||||
};
|
||||
|
||||
//
|
||||
// Report whether or not a variable of the given qualifier type
|
||||
// is guaranteed written. Not always possible to determine if
|
||||
// it is written conditionally.
|
||||
//
|
||||
// ?? It does not do this well yet, this is just a place holder
|
||||
// that simply determines if it was reference at all, anywhere.
|
||||
//
|
||||
bool QualifierWritten(TIntermNode* node, TQualifier qualifier)
|
||||
{
|
||||
TAliveTraverser it(qualifier);
|
||||
|
||||
if (node)
|
||||
node->traverse(&it);
|
||||
|
||||
return it.wasFound();
|
||||
}
|
||||
|
||||
void TAliveTraverser::visitSymbol(TIntermSymbol* node)
|
||||
{
|
||||
//
|
||||
// If it's what we're looking for, record it.
|
||||
//
|
||||
if (node->getQualifier() == qualifier)
|
||||
found = true;
|
||||
}
|
||||
|
||||
bool TAliveTraverser::visitSelection(Visit preVisit, TIntermSelection* node)
|
||||
{
|
||||
if (wasFound())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
7
src/3rdparty/angle/src/compiler/QualifierAlive.h
vendored
Normal file
7
src/3rdparty/angle/src/compiler/QualifierAlive.h
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
bool QualifierWritten(TIntermNode* root, TQualifier);
|
77
src/3rdparty/angle/src/compiler/RemoveTree.cpp
vendored
Normal file
77
src/3rdparty/angle/src/compiler/RemoveTree.cpp
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
#include "compiler/RemoveTree.h"
|
||||
|
||||
//
|
||||
// Code to recursively delete the intermediate tree.
|
||||
//
|
||||
|
||||
class RemoveTree : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
RemoveTree() : TIntermTraverser(false, false, true)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
void visitSymbol(TIntermSymbol*);
|
||||
void visitConstantUnion(TIntermConstantUnion*);
|
||||
bool visitBinary(Visit visit, TIntermBinary*);
|
||||
bool visitUnary(Visit visit, TIntermUnary*);
|
||||
bool visitSelection(Visit visit, TIntermSelection*);
|
||||
bool visitAggregate(Visit visit, TIntermAggregate*);
|
||||
};
|
||||
|
||||
void RemoveTree::visitSymbol(TIntermSymbol* node)
|
||||
{
|
||||
delete node;
|
||||
}
|
||||
|
||||
bool RemoveTree::visitBinary(Visit visit, TIntermBinary* node)
|
||||
{
|
||||
delete node;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoveTree::visitUnary(Visit visit, TIntermUnary* node)
|
||||
{
|
||||
delete node;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoveTree::visitAggregate(Visit visit, TIntermAggregate* node)
|
||||
{
|
||||
delete node;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoveTree::visitSelection(Visit visit, TIntermSelection* node)
|
||||
{
|
||||
delete node;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoveTree::visitConstantUnion(TIntermConstantUnion* node)
|
||||
{
|
||||
delete node;
|
||||
}
|
||||
|
||||
//
|
||||
// Entry point.
|
||||
//
|
||||
void RemoveAllTreeNodes(TIntermNode* root)
|
||||
{
|
||||
RemoveTree it;
|
||||
|
||||
root->traverse(&it);
|
||||
}
|
||||
|
7
src/3rdparty/angle/src/compiler/RemoveTree.h
vendored
Normal file
7
src/3rdparty/angle/src/compiler/RemoveTree.h
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
void RemoveAllTreeNodes(TIntermNode*);
|
36
src/3rdparty/angle/src/compiler/RenameFunction.h
vendored
Normal file
36
src/3rdparty/angle/src/compiler/RenameFunction.h
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
//
|
||||
// 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 COMPILER_RENAME_FUNCTION
|
||||
#define COMPILER_RENAME_FUNCTION
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
//
|
||||
// Renames a function, including its declaration and any calls to it.
|
||||
//
|
||||
class RenameFunction : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
RenameFunction(const TString& oldFunctionName, const TString& newFunctionName)
|
||||
: TIntermTraverser(true, false, false)
|
||||
, mOldFunctionName(oldFunctionName)
|
||||
, mNewFunctionName(newFunctionName) {}
|
||||
|
||||
virtual bool visitAggregate(Visit visit, TIntermAggregate* node)
|
||||
{
|
||||
TOperator op = node->getOp();
|
||||
if ((op == EOpFunction || op == EOpFunctionCall) && node->getName() == mOldFunctionName)
|
||||
node->setName(mNewFunctionName);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const TString mOldFunctionName;
|
||||
const TString mNewFunctionName;
|
||||
};
|
||||
|
||||
#endif // COMPILER_RENAME_FUNCTION
|
38
src/3rdparty/angle/src/compiler/SearchSymbol.cpp
vendored
Normal file
38
src/3rdparty/angle/src/compiler/SearchSymbol.cpp
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// SearchSymbol is an AST traverser to detect the use of a given symbol name
|
||||
//
|
||||
|
||||
#include "compiler/SearchSymbol.h"
|
||||
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/OutputHLSL.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
SearchSymbol::SearchSymbol(const TString &symbol) : mSymbol(symbol)
|
||||
{
|
||||
match = false;
|
||||
}
|
||||
|
||||
void SearchSymbol::traverse(TIntermNode *node)
|
||||
{
|
||||
node->traverse(this);
|
||||
}
|
||||
|
||||
void SearchSymbol::visitSymbol(TIntermSymbol *symbolNode)
|
||||
{
|
||||
if (symbolNode->getSymbol() == mSymbol)
|
||||
{
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool SearchSymbol::foundMatch() const
|
||||
{
|
||||
return match;
|
||||
}
|
||||
}
|
33
src/3rdparty/angle/src/compiler/SearchSymbol.h
vendored
Normal file
33
src/3rdparty/angle/src/compiler/SearchSymbol.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// SearchSymbol is an AST traverser to detect the use of a given symbol name
|
||||
//
|
||||
|
||||
#ifndef COMPILER_SEARCHSYMBOL_H_
|
||||
#define COMPILER_SEARCHSYMBOL_H_
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
class SearchSymbol : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
SearchSymbol(const TString &symbol);
|
||||
|
||||
void traverse(TIntermNode *node);
|
||||
void visitSymbol(TIntermSymbol *symbolNode);
|
||||
|
||||
bool foundMatch() const;
|
||||
|
||||
protected:
|
||||
const TString &mSymbol;
|
||||
bool match;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // COMPILER_SEARCHSYMBOL_H_
|
142
src/3rdparty/angle/src/compiler/ShHandle.h
vendored
Normal file
142
src/3rdparty/angle/src/compiler/ShHandle.h
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
//
|
||||
// Copyright (c) 2002-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 _SHHANDLE_INCLUDED_
|
||||
#define _SHHANDLE_INCLUDED_
|
||||
|
||||
//
|
||||
// Machine independent part of the compiler private objects
|
||||
// sent as ShHandle to the driver.
|
||||
//
|
||||
// This should not be included by driver code.
|
||||
//
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include "compiler/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/ExtensionBehavior.h"
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/SymbolTable.h"
|
||||
#include "compiler/VariableInfo.h"
|
||||
|
||||
class LongNameMap;
|
||||
class TCompiler;
|
||||
class TDependencyGraph;
|
||||
|
||||
//
|
||||
// Helper function to identify specs that are based on the WebGL spec,
|
||||
// like the CSS Shaders spec.
|
||||
//
|
||||
bool isWebGLBasedSpec(ShShaderSpec spec);
|
||||
|
||||
//
|
||||
// The base class used to back handles returned to the driver.
|
||||
//
|
||||
class TShHandleBase {
|
||||
public:
|
||||
TShHandleBase();
|
||||
virtual ~TShHandleBase();
|
||||
virtual TCompiler* getAsCompiler() { return 0; }
|
||||
|
||||
protected:
|
||||
// Memory allocator. Allocates and tracks memory required by the compiler.
|
||||
// Deallocates all memory when compiler is destructed.
|
||||
TPoolAllocator allocator;
|
||||
};
|
||||
|
||||
//
|
||||
// The base class for the machine dependent compiler to derive from
|
||||
// for managing object code from the compile.
|
||||
//
|
||||
class TCompiler : public TShHandleBase {
|
||||
public:
|
||||
TCompiler(ShShaderType type, ShShaderSpec spec);
|
||||
virtual ~TCompiler();
|
||||
virtual TCompiler* getAsCompiler() { return this; }
|
||||
|
||||
bool Init(const ShBuiltInResources& resources);
|
||||
bool compile(const char* const shaderStrings[],
|
||||
const int numStrings,
|
||||
int compileOptions);
|
||||
|
||||
// Get results of the last compilation.
|
||||
TInfoSink& getInfoSink() { return infoSink; }
|
||||
const TVariableInfoList& getAttribs() const { return attribs; }
|
||||
const TVariableInfoList& getUniforms() const { return uniforms; }
|
||||
int getMappedNameMaxLength() const;
|
||||
|
||||
protected:
|
||||
ShShaderType getShaderType() const { return shaderType; }
|
||||
ShShaderSpec getShaderSpec() const { return shaderSpec; }
|
||||
// Initialize symbol-table with built-in symbols.
|
||||
bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
|
||||
// Clears the results from the previous compilation.
|
||||
void clearResults();
|
||||
// Return true if function recursion is detected.
|
||||
bool detectRecursion(TIntermNode* root);
|
||||
// Rewrites a shader's intermediate tree according to the CSS Shaders spec.
|
||||
void rewriteCSSShader(TIntermNode* root);
|
||||
// Returns true if the given shader does not exceed the minimum
|
||||
// functionality mandated in GLSL 1.0 spec Appendix A.
|
||||
bool validateLimitations(TIntermNode* root);
|
||||
// Collect info for all attribs and uniforms.
|
||||
void collectAttribsUniforms(TIntermNode* root);
|
||||
// Map long variable names into shorter ones.
|
||||
void mapLongVariableNames(TIntermNode* root);
|
||||
// Translate to object code.
|
||||
virtual void translate(TIntermNode* root) = 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();
|
||||
// Returns true if the shader passes the restrictions that aim to prevent timing attacks.
|
||||
bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph);
|
||||
// Returns true if the shader does not use samplers.
|
||||
bool enforceVertexShaderTimingRestrictions(TIntermNode* root);
|
||||
// Returns true if the shader does not use sampler dependent values to affect control
|
||||
// flow or in operations whose time can depend on the input values.
|
||||
bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph);
|
||||
// Get built-in extensions with default behavior.
|
||||
const TExtensionBehavior& getExtensionBehavior() const;
|
||||
|
||||
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
|
||||
|
||||
private:
|
||||
ShShaderType shaderType;
|
||||
ShShaderSpec shaderSpec;
|
||||
|
||||
int maxUniformVectors;
|
||||
|
||||
// Built-in symbol table for the given language, spec, and resources.
|
||||
// It is preserved from compile-to-compile.
|
||||
TSymbolTable symbolTable;
|
||||
// Built-in extensions with default behavior.
|
||||
TExtensionBehavior extensionBehavior;
|
||||
|
||||
BuiltInFunctionEmulator builtInFunctionEmulator;
|
||||
|
||||
// Results of compilation.
|
||||
TInfoSink infoSink; // Output sink.
|
||||
TVariableInfoList attribs; // Active attributes in the compiled shader.
|
||||
TVariableInfoList uniforms; // Active uniforms in the compiled shader.
|
||||
|
||||
// Cached copy of the ref-counted singleton.
|
||||
LongNameMap* longNameMap;
|
||||
};
|
||||
|
||||
//
|
||||
// This is the interface between the machine independent code
|
||||
// and the machine dependent code.
|
||||
//
|
||||
// The machine dependent code should derive from the classes
|
||||
// above. Then Construct*() and Delete*() will create and
|
||||
// destroy the machine dependent objects, which contain the
|
||||
// above machine independent information.
|
||||
//
|
||||
TCompiler* ConstructCompiler(
|
||||
ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
|
||||
void DeleteCompiler(TCompiler*);
|
||||
|
||||
#endif // _SHHANDLE_INCLUDED_
|
285
src/3rdparty/angle/src/compiler/ShaderLang.cpp
vendored
Normal file
285
src/3rdparty/angle/src/compiler/ShaderLang.cpp
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
//
|
||||
// Implement the top-level of interface to the compiler,
|
||||
// as defined in ShaderLang.h
|
||||
//
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
#include "compiler/InitializeDll.h"
|
||||
#include "compiler/preprocessor/length_limits.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
|
||||
//
|
||||
// This is the platform independent interface between an OGL driver
|
||||
// and the shading language compiler.
|
||||
//
|
||||
|
||||
static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
|
||||
int expectedValue)
|
||||
{
|
||||
int activeUniformLimit = 0;
|
||||
ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
|
||||
int activeAttribLimit = 0;
|
||||
ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
|
||||
return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
|
||||
}
|
||||
|
||||
static bool checkMappedNameMaxLength(const ShHandle handle, int expectedValue)
|
||||
{
|
||||
int mappedNameMaxLength = 0;
|
||||
ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
|
||||
return (expectedValue == mappedNameMaxLength);
|
||||
}
|
||||
|
||||
static void getVariableInfo(ShShaderInfo varType,
|
||||
const ShHandle handle,
|
||||
int index,
|
||||
int* length,
|
||||
int* size,
|
||||
ShDataType* type,
|
||||
char* name,
|
||||
char* mappedName)
|
||||
{
|
||||
if (!handle || !size || !type || !name)
|
||||
return;
|
||||
ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
|
||||
(varType == SH_ACTIVE_UNIFORMS));
|
||||
|
||||
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
return;
|
||||
|
||||
const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
|
||||
compiler->getAttribs() : compiler->getUniforms();
|
||||
if (index < 0 || index >= static_cast<int>(varList.size()))
|
||||
return;
|
||||
|
||||
const TVariableInfo& varInfo = varList[index];
|
||||
if (length) *length = varInfo.name.size();
|
||||
*size = varInfo.size;
|
||||
*type = varInfo.type;
|
||||
|
||||
// This size must match that queried by
|
||||
// SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH
|
||||
// in ShGetInfo, below.
|
||||
int activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
|
||||
ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
|
||||
strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
|
||||
name[activeUniformAndAttribLength - 1] = 0;
|
||||
if (mappedName) {
|
||||
// This size must match that queried by
|
||||
// SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
|
||||
int maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
|
||||
ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
|
||||
strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
|
||||
mappedName[maxMappedNameLength - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler operations.
|
||||
//
|
||||
int ShInitialize()
|
||||
{
|
||||
if (!InitProcess())
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup symbol tables
|
||||
//
|
||||
int ShFinalize()
|
||||
{
|
||||
if (!DetachProcess())
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize built-in resources with minimum expected values.
|
||||
//
|
||||
void ShInitBuiltInResources(ShBuiltInResources* resources)
|
||||
{
|
||||
// Constants.
|
||||
resources->MaxVertexAttribs = 8;
|
||||
resources->MaxVertexUniformVectors = 128;
|
||||
resources->MaxVaryingVectors = 8;
|
||||
resources->MaxVertexTextureImageUnits = 0;
|
||||
resources->MaxCombinedTextureImageUnits = 8;
|
||||
resources->MaxTextureImageUnits = 8;
|
||||
resources->MaxFragmentUniformVectors = 16;
|
||||
resources->MaxDrawBuffers = 1;
|
||||
|
||||
// Extensions.
|
||||
resources->OES_standard_derivatives = 0;
|
||||
resources->OES_EGL_image_external = 0;
|
||||
resources->ARB_texture_rectangle = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Driver calls these to create and destroy compiler objects.
|
||||
//
|
||||
ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
|
||||
ShShaderOutput output,
|
||||
const ShBuiltInResources* resources)
|
||||
{
|
||||
if (!InitThread())
|
||||
return 0;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
return 0;
|
||||
|
||||
// Generate built-in symbol table.
|
||||
if (!compiler->Init(*resources)) {
|
||||
ShDestruct(base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return reinterpret_cast<void*>(base);
|
||||
}
|
||||
|
||||
void ShDestruct(ShHandle handle)
|
||||
{
|
||||
if (handle == 0)
|
||||
return;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
|
||||
if (base->getAsCompiler())
|
||||
DeleteCompiler(base->getAsCompiler());
|
||||
}
|
||||
|
||||
//
|
||||
// Do an actual compile on the given strings. The result is left
|
||||
// in the given compile object.
|
||||
//
|
||||
// Return: The return value of ShCompile is really boolean, indicating
|
||||
// success or failure.
|
||||
//
|
||||
int ShCompile(
|
||||
const ShHandle handle,
|
||||
const char* const shaderStrings[],
|
||||
const int numStrings,
|
||||
int compileOptions)
|
||||
{
|
||||
if (!InitThread())
|
||||
return 0;
|
||||
|
||||
if (handle == 0)
|
||||
return 0;
|
||||
|
||||
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
return 0;
|
||||
|
||||
bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
|
||||
return success ? 1 : 0;
|
||||
}
|
||||
|
||||
void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
|
||||
{
|
||||
if (!handle || !params)
|
||||
return;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
case SH_INFO_LOG_LENGTH:
|
||||
*params = compiler->getInfoSink().info.size() + 1;
|
||||
break;
|
||||
case SH_OBJECT_CODE_LENGTH:
|
||||
*params = compiler->getInfoSink().obj.size() + 1;
|
||||
break;
|
||||
case SH_ACTIVE_UNIFORMS:
|
||||
*params = compiler->getUniforms().size();
|
||||
break;
|
||||
case SH_ACTIVE_UNIFORM_MAX_LENGTH:
|
||||
*params = 1 + MAX_SYMBOL_NAME_LEN;
|
||||
break;
|
||||
case SH_ACTIVE_ATTRIBUTES:
|
||||
*params = compiler->getAttribs().size();
|
||||
break;
|
||||
case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
|
||||
*params = 1 + MAX_SYMBOL_NAME_LEN;
|
||||
break;
|
||||
case SH_MAPPED_NAME_MAX_LENGTH:
|
||||
// Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
|
||||
// handle array and struct dereferences.
|
||||
*params = 1 + MAX_SYMBOL_NAME_LEN;
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return any compiler log of messages for the application.
|
||||
//
|
||||
void ShGetInfoLog(const ShHandle handle, char* infoLog)
|
||||
{
|
||||
if (!handle || !infoLog)
|
||||
return;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
TInfoSink& infoSink = compiler->getInfoSink();
|
||||
strcpy(infoLog, infoSink.info.c_str());
|
||||
}
|
||||
|
||||
//
|
||||
// Return any object code.
|
||||
//
|
||||
void ShGetObjectCode(const ShHandle handle, char* objCode)
|
||||
{
|
||||
if (!handle || !objCode)
|
||||
return;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
TInfoSink& infoSink = compiler->getInfoSink();
|
||||
strcpy(objCode, infoSink.obj.c_str());
|
||||
}
|
||||
|
||||
void ShGetActiveAttrib(const ShHandle handle,
|
||||
int index,
|
||||
int* length,
|
||||
int* size,
|
||||
ShDataType* type,
|
||||
char* name,
|
||||
char* mappedName)
|
||||
{
|
||||
getVariableInfo(SH_ACTIVE_ATTRIBUTES,
|
||||
handle, index, length, size, type, name, mappedName);
|
||||
}
|
||||
|
||||
void ShGetActiveUniform(const ShHandle handle,
|
||||
int index,
|
||||
int* length,
|
||||
int* size,
|
||||
ShDataType* type,
|
||||
char* name,
|
||||
char* mappedName)
|
||||
{
|
||||
getVariableInfo(SH_ACTIVE_UNIFORMS,
|
||||
handle, index, length, size, type, name, mappedName);
|
||||
}
|
279
src/3rdparty/angle/src/compiler/SymbolTable.cpp
vendored
Normal file
279
src/3rdparty/angle/src/compiler/SymbolTable.cpp
vendored
Normal file
@ -0,0 +1,279 @@
|
||||
//
|
||||
// Copyright (c) 2002-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.
|
||||
//
|
||||
|
||||
//
|
||||
// Symbol table for parsing. Most functionaliy and main ideas
|
||||
// are documented in the header file.
|
||||
//
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4718)
|
||||
#endif
|
||||
|
||||
#include "compiler/SymbolTable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
TType::TType(const TPublicType &p) :
|
||||
type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
|
||||
maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
|
||||
{
|
||||
if (p.userDef) {
|
||||
structure = p.userDef->getStruct();
|
||||
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
|
||||
computeDeepestStructNesting();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Recursively generate mangled names.
|
||||
//
|
||||
void TType::buildMangledName(TString& mangledName)
|
||||
{
|
||||
if (isMatrix())
|
||||
mangledName += 'm';
|
||||
else if (isVector())
|
||||
mangledName += 'v';
|
||||
|
||||
switch (type) {
|
||||
case EbtFloat: mangledName += 'f'; break;
|
||||
case EbtInt: mangledName += 'i'; break;
|
||||
case EbtBool: mangledName += 'b'; break;
|
||||
case EbtSampler2D: mangledName += "s2"; break;
|
||||
case EbtSamplerCube: mangledName += "sC"; break;
|
||||
case EbtStruct:
|
||||
mangledName += "struct-";
|
||||
if (typeName)
|
||||
mangledName += *typeName;
|
||||
{// support MSVC++6.0
|
||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
||||
mangledName += '-';
|
||||
(*structure)[i].type->buildMangledName(mangledName);
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mangledName += static_cast<char>('0' + getNominalSize());
|
||||
if (isArray()) {
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "%d", arraySize);
|
||||
mangledName += '[';
|
||||
mangledName += buf;
|
||||
mangledName += ']';
|
||||
}
|
||||
}
|
||||
|
||||
int TType::getStructSize() const
|
||||
{
|
||||
if (!getStruct()) {
|
||||
assert(false && "Not a struct");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (structureSize == 0)
|
||||
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
|
||||
structureSize += ((*tl).type)->getObjectSize();
|
||||
|
||||
return structureSize;
|
||||
}
|
||||
|
||||
void TType::computeDeepestStructNesting()
|
||||
{
|
||||
if (!getStruct()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int maxNesting = 0;
|
||||
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
|
||||
maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
|
||||
}
|
||||
|
||||
deepestStructNesting = 1 + maxNesting;
|
||||
}
|
||||
|
||||
bool TType::isStructureContainingArrays() const
|
||||
{
|
||||
if (!structure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++)
|
||||
{
|
||||
if (member->type->isArray() ||
|
||||
member->type->isStructureContainingArrays())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Dump functions.
|
||||
//
|
||||
|
||||
void TVariable::dump(TInfoSink& infoSink) const
|
||||
{
|
||||
infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString();
|
||||
if (type.isArray()) {
|
||||
infoSink.debug << "[0]";
|
||||
}
|
||||
infoSink.debug << "\n";
|
||||
}
|
||||
|
||||
void TFunction::dump(TInfoSink &infoSink) const
|
||||
{
|
||||
infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
|
||||
}
|
||||
|
||||
void TSymbolTableLevel::dump(TInfoSink &infoSink) const
|
||||
{
|
||||
tLevel::const_iterator it;
|
||||
for (it = level.begin(); it != level.end(); ++it)
|
||||
(*it).second->dump(infoSink);
|
||||
}
|
||||
|
||||
void TSymbolTable::dump(TInfoSink &infoSink) const
|
||||
{
|
||||
for (int level = currentLevel(); level >= 0; --level) {
|
||||
infoSink.debug << "LEVEL " << level << "\n";
|
||||
table[level]->dump(infoSink);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Functions have buried pointers to delete.
|
||||
//
|
||||
TFunction::~TFunction()
|
||||
{
|
||||
for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
|
||||
delete (*i).type;
|
||||
}
|
||||
|
||||
//
|
||||
// Symbol table levels are a map of pointers to symbols that have to be deleted.
|
||||
//
|
||||
TSymbolTableLevel::~TSymbolTableLevel()
|
||||
{
|
||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
|
||||
delete (*it).second;
|
||||
}
|
||||
|
||||
//
|
||||
// Change all function entries in the table with the non-mangled name
|
||||
// to be related to the provided built-in operation. This is a low
|
||||
// performance operation, and only intended for symbol tables that
|
||||
// live across a large number of compiles.
|
||||
//
|
||||
void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
|
||||
{
|
||||
tLevel::iterator it;
|
||||
for (it = level.begin(); it != level.end(); ++it) {
|
||||
if ((*it).second->isFunction()) {
|
||||
TFunction* function = static_cast<TFunction*>((*it).second);
|
||||
if (function->getName() == name)
|
||||
function->relateToOperator(op);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Change all function entries in the table with the non-mangled name
|
||||
// to be related to the provided built-in extension. This is a low
|
||||
// performance operation, and only intended for symbol tables that
|
||||
// live across a large number of compiles.
|
||||
//
|
||||
void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
|
||||
{
|
||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
|
||||
if (it->second->isFunction()) {
|
||||
TFunction* function = static_cast<TFunction*>(it->second);
|
||||
if (function->getName() == name)
|
||||
function->relateToExtension(ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TSymbol::TSymbol(const TSymbol& copyOf)
|
||||
{
|
||||
name = NewPoolTString(copyOf.name->c_str());
|
||||
uniqueId = copyOf.uniqueId;
|
||||
}
|
||||
|
||||
TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
|
||||
{
|
||||
type.copyType(copyOf.type, remapper);
|
||||
userType = copyOf.userType;
|
||||
// for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
|
||||
assert(copyOf.arrayInformationType == 0);
|
||||
arrayInformationType = 0;
|
||||
|
||||
if (copyOf.unionArray) {
|
||||
assert(!copyOf.type.getStruct());
|
||||
assert(copyOf.type.getObjectSize() == 1);
|
||||
unionArray = new ConstantUnion[1];
|
||||
unionArray[0] = copyOf.unionArray[0];
|
||||
} else
|
||||
unionArray = 0;
|
||||
}
|
||||
|
||||
TVariable* TVariable::clone(TStructureMap& remapper)
|
||||
{
|
||||
TVariable *variable = new TVariable(*this, remapper);
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
|
||||
{
|
||||
for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
|
||||
TParameter param;
|
||||
parameters.push_back(param);
|
||||
parameters.back().copyParam(copyOf.parameters[i], remapper);
|
||||
}
|
||||
|
||||
returnType.copyType(copyOf.returnType, remapper);
|
||||
mangledName = copyOf.mangledName;
|
||||
op = copyOf.op;
|
||||
defined = copyOf.defined;
|
||||
}
|
||||
|
||||
TFunction* TFunction::clone(TStructureMap& remapper)
|
||||
{
|
||||
TFunction *function = new TFunction(*this, remapper);
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
|
||||
{
|
||||
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
||||
tLevel::iterator iter;
|
||||
for (iter = level.begin(); iter != level.end(); ++iter) {
|
||||
symTableLevel->insert(*iter->second->clone(remapper));
|
||||
}
|
||||
|
||||
return symTableLevel;
|
||||
}
|
||||
|
||||
void TSymbolTable::copyTable(const TSymbolTable& copyOf)
|
||||
{
|
||||
TStructureMap remapper;
|
||||
uniqueId = copyOf.uniqueId;
|
||||
for (unsigned int i = 0; i < copyOf.table.size(); ++i) {
|
||||
table.push_back(copyOf.table[i]->clone(remapper));
|
||||
}
|
||||
for( unsigned int i = 0; i < copyOf.precisionStack.size(); i++) {
|
||||
precisionStack.push_back( copyOf.precisionStack[i] );
|
||||
}
|
||||
}
|
359
src/3rdparty/angle/src/compiler/SymbolTable.h
vendored
Normal file
359
src/3rdparty/angle/src/compiler/SymbolTable.h
vendored
Normal file
@ -0,0 +1,359 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef _SYMBOL_TABLE_INCLUDED_
|
||||
#define _SYMBOL_TABLE_INCLUDED_
|
||||
|
||||
//
|
||||
// Symbol table for parsing. Has these design characteristics:
|
||||
//
|
||||
// * Same symbol table can be used to compile many shaders, to preserve
|
||||
// effort of creating and loading with the large numbers of built-in
|
||||
// symbols.
|
||||
//
|
||||
// * Name mangling will be used to give each function a unique name
|
||||
// so that symbol table lookups are never ambiguous. This allows
|
||||
// a simpler symbol table structure.
|
||||
//
|
||||
// * Pushing and popping of scope, so symbol table will really be a stack
|
||||
// of symbol tables. Searched from the top, with new inserts going into
|
||||
// the top.
|
||||
//
|
||||
// * Constants: Compile time constant symbols will keep their values
|
||||
// in the symbol table. The parser can substitute constants at parse
|
||||
// time, including doing constant folding and constant propagation.
|
||||
//
|
||||
// * No temporaries: Temporaries made from operations (+, --, .xy, etc.)
|
||||
// are tracked in the intermediate representation, not the symbol table.
|
||||
//
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
//
|
||||
// Symbol base class. (Can build functions or variables out of these...)
|
||||
//
|
||||
class TSymbol {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
TSymbol(const TString *n) : name(n) { }
|
||||
virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
|
||||
const TString& getName() const { return *name; }
|
||||
virtual const TString& getMangledName() const { return getName(); }
|
||||
virtual bool isFunction() const { return false; }
|
||||
virtual bool isVariable() const { return false; }
|
||||
void setUniqueId(int id) { uniqueId = id; }
|
||||
int getUniqueId() const { return uniqueId; }
|
||||
virtual void dump(TInfoSink &infoSink) const = 0;
|
||||
TSymbol(const TSymbol&);
|
||||
virtual TSymbol* clone(TStructureMap& remapper) = 0;
|
||||
|
||||
protected:
|
||||
const TString *name;
|
||||
unsigned int uniqueId; // For real comparing during code generation
|
||||
};
|
||||
|
||||
//
|
||||
// Variable class, meaning a symbol that's not a function.
|
||||
//
|
||||
// There could be a separate class heirarchy for Constant variables;
|
||||
// Only one of int, bool, or float, (or none) is correct for
|
||||
// any particular use, but it's easy to do this way, and doesn't
|
||||
// seem worth having separate classes, and "getConst" can't simply return
|
||||
// different values for different types polymorphically, so this is
|
||||
// just simple and pragmatic.
|
||||
//
|
||||
class TVariable : public TSymbol {
|
||||
public:
|
||||
TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
|
||||
virtual ~TVariable() { }
|
||||
virtual bool isVariable() const { return true; }
|
||||
TType& getType() { return type; }
|
||||
const TType& getType() const { return type; }
|
||||
bool isUserType() const { return userType; }
|
||||
void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
|
||||
void updateArrayInformationType(TType *t) { arrayInformationType = t; }
|
||||
TType* getArrayInformationType() { return arrayInformationType; }
|
||||
|
||||
virtual void dump(TInfoSink &infoSink) const;
|
||||
|
||||
ConstantUnion* getConstPointer()
|
||||
{
|
||||
if (!unionArray)
|
||||
unionArray = new ConstantUnion[type.getObjectSize()];
|
||||
|
||||
return unionArray;
|
||||
}
|
||||
|
||||
ConstantUnion* getConstPointer() const { return unionArray; }
|
||||
|
||||
void shareConstPointer( ConstantUnion *constArray)
|
||||
{
|
||||
if (unionArray == constArray)
|
||||
return;
|
||||
|
||||
delete[] unionArray;
|
||||
unionArray = constArray;
|
||||
}
|
||||
TVariable(const TVariable&, TStructureMap& remapper); // copy constructor
|
||||
virtual TVariable* clone(TStructureMap& remapper);
|
||||
|
||||
protected:
|
||||
TType type;
|
||||
bool userType;
|
||||
// we are assuming that Pool Allocator will free the memory allocated to unionArray
|
||||
// when this object is destroyed
|
||||
ConstantUnion *unionArray;
|
||||
TType *arrayInformationType; // this is used for updating maxArraySize in all the references to a given symbol
|
||||
};
|
||||
|
||||
//
|
||||
// The function sub-class of symbols and the parser will need to
|
||||
// share this definition of a function parameter.
|
||||
//
|
||||
struct TParameter {
|
||||
TString *name;
|
||||
TType* type;
|
||||
void copyParam(const TParameter& param, TStructureMap& remapper)
|
||||
{
|
||||
name = NewPoolTString(param.name->c_str());
|
||||
type = param.type->clone(remapper);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// The function sub-class of a symbol.
|
||||
//
|
||||
class TFunction : public TSymbol {
|
||||
public:
|
||||
TFunction(TOperator o) :
|
||||
TSymbol(0),
|
||||
returnType(TType(EbtVoid, EbpUndefined)),
|
||||
op(o),
|
||||
defined(false) { }
|
||||
TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) :
|
||||
TSymbol(name),
|
||||
returnType(retType),
|
||||
mangledName(TFunction::mangleName(*name)),
|
||||
op(tOp),
|
||||
defined(false) { }
|
||||
virtual ~TFunction();
|
||||
virtual bool isFunction() const { return true; }
|
||||
|
||||
static TString mangleName(const TString& name) { return name + '('; }
|
||||
static TString unmangleName(const TString& mangledName)
|
||||
{
|
||||
return TString(mangledName.c_str(), mangledName.find_first_of('('));
|
||||
}
|
||||
|
||||
void addParameter(TParameter& p)
|
||||
{
|
||||
parameters.push_back(p);
|
||||
mangledName = mangledName + p.type->getMangledName();
|
||||
}
|
||||
|
||||
const TString& getMangledName() const { return mangledName; }
|
||||
const TType& getReturnType() const { return returnType; }
|
||||
|
||||
void relateToOperator(TOperator o) { op = o; }
|
||||
TOperator getBuiltInOp() const { return op; }
|
||||
|
||||
void relateToExtension(const TString& ext) { extension = ext; }
|
||||
const TString& getExtension() const { return extension; }
|
||||
|
||||
void setDefined() { defined = true; }
|
||||
bool isDefined() { return defined; }
|
||||
|
||||
int getParamCount() const { return static_cast<int>(parameters.size()); }
|
||||
const TParameter& getParam(int i) const { return parameters[i]; }
|
||||
|
||||
virtual void dump(TInfoSink &infoSink) const;
|
||||
TFunction(const TFunction&, TStructureMap& remapper);
|
||||
virtual TFunction* clone(TStructureMap& remapper);
|
||||
|
||||
protected:
|
||||
typedef TVector<TParameter> TParamList;
|
||||
TParamList parameters;
|
||||
TType returnType;
|
||||
TString mangledName;
|
||||
TOperator op;
|
||||
TString extension;
|
||||
bool defined;
|
||||
};
|
||||
|
||||
|
||||
class TSymbolTableLevel {
|
||||
public:
|
||||
typedef TMap<TString, TSymbol*> tLevel;
|
||||
typedef tLevel::const_iterator const_iterator;
|
||||
typedef const tLevel::value_type tLevelPair;
|
||||
typedef std::pair<tLevel::iterator, bool> tInsertResult;
|
||||
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
TSymbolTableLevel() { }
|
||||
~TSymbolTableLevel();
|
||||
|
||||
bool insert(TSymbol& symbol)
|
||||
{
|
||||
//
|
||||
// returning true means symbol was added to the table
|
||||
//
|
||||
tInsertResult result;
|
||||
result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
|
||||
|
||||
return result.second;
|
||||
}
|
||||
|
||||
TSymbol* find(const TString& name) const
|
||||
{
|
||||
tLevel::const_iterator it = level.find(name);
|
||||
if (it == level.end())
|
||||
return 0;
|
||||
else
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return level.begin();
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return level.end();
|
||||
}
|
||||
|
||||
void relateToOperator(const char* name, TOperator op);
|
||||
void relateToExtension(const char* name, const TString& ext);
|
||||
void dump(TInfoSink &infoSink) const;
|
||||
TSymbolTableLevel* clone(TStructureMap& remapper);
|
||||
|
||||
protected:
|
||||
tLevel level;
|
||||
};
|
||||
|
||||
class TSymbolTable {
|
||||
public:
|
||||
TSymbolTable() : uniqueId(0)
|
||||
{
|
||||
//
|
||||
// The symbol table cannot be used until push() is called, but
|
||||
// the lack of an initial call to push() can be used to detect
|
||||
// that the symbol table has not been preloaded with built-ins.
|
||||
//
|
||||
}
|
||||
|
||||
~TSymbolTable()
|
||||
{
|
||||
// level 0 is always built In symbols, so we never pop that out
|
||||
while (table.size() > 1)
|
||||
pop();
|
||||
}
|
||||
|
||||
//
|
||||
// When the symbol table is initialized with the built-ins, there should
|
||||
// 'push' calls, so that built-ins are at level 0 and the shader
|
||||
// globals are at level 1.
|
||||
//
|
||||
bool isEmpty() { return table.size() == 0; }
|
||||
bool atBuiltInLevel() { return table.size() == 1; }
|
||||
bool atGlobalLevel() { return table.size() <= 2; }
|
||||
void push()
|
||||
{
|
||||
table.push_back(new TSymbolTableLevel);
|
||||
precisionStack.push_back( PrecisionStackLevel() );
|
||||
}
|
||||
|
||||
void pop()
|
||||
{
|
||||
delete table[currentLevel()];
|
||||
table.pop_back();
|
||||
precisionStack.pop_back();
|
||||
}
|
||||
|
||||
bool insert(TSymbol& symbol)
|
||||
{
|
||||
symbol.setUniqueId(++uniqueId);
|
||||
return table[currentLevel()]->insert(symbol);
|
||||
}
|
||||
|
||||
TSymbol* find(const TString& name, bool* builtIn = 0, bool *sameScope = 0)
|
||||
{
|
||||
int level = currentLevel();
|
||||
TSymbol* symbol;
|
||||
do {
|
||||
symbol = table[level]->find(name);
|
||||
--level;
|
||||
} while (symbol == 0 && level >= 0);
|
||||
level++;
|
||||
if (builtIn)
|
||||
*builtIn = level == 0;
|
||||
if (sameScope)
|
||||
*sameScope = level == currentLevel();
|
||||
return symbol;
|
||||
}
|
||||
|
||||
TSymbol *findBuiltIn(const TString &name)
|
||||
{
|
||||
return table[0]->find(name);
|
||||
}
|
||||
|
||||
TSymbolTableLevel* getGlobalLevel() {
|
||||
assert(table.size() >= 2);
|
||||
return table[1];
|
||||
}
|
||||
|
||||
TSymbolTableLevel* getOuterLevel() {
|
||||
assert(table.size() >= 2);
|
||||
return table[currentLevel() - 1];
|
||||
}
|
||||
|
||||
void relateToOperator(const char* name, TOperator op) {
|
||||
table[0]->relateToOperator(name, op);
|
||||
}
|
||||
void relateToExtension(const char* name, const TString& ext) {
|
||||
table[0]->relateToExtension(name, ext);
|
||||
}
|
||||
int getMaxSymbolId() { return uniqueId; }
|
||||
void dump(TInfoSink &infoSink) const;
|
||||
void copyTable(const TSymbolTable& copyOf);
|
||||
|
||||
void setDefaultPrecision( TBasicType type, TPrecision prec ){
|
||||
if( type != EbtFloat && type != EbtInt ) return; // Only set default precision for int/float
|
||||
int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
|
||||
precisionStack[indexOfLastElement][type] = prec; // Uses map operator [], overwrites the current value
|
||||
}
|
||||
|
||||
// Searches down the precisionStack for a precision qualifier for the specified TBasicType
|
||||
TPrecision getDefaultPrecision( TBasicType type){
|
||||
if( type != EbtFloat && type != EbtInt ) return EbpUndefined;
|
||||
int level = static_cast<int>(precisionStack.size()) - 1;
|
||||
assert( level >= 0); // Just to be safe. Should not happen.
|
||||
PrecisionStackLevel::iterator it;
|
||||
TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this?
|
||||
while( level >= 0 ){
|
||||
it = precisionStack[level].find( type );
|
||||
if( it != precisionStack[level].end() ){
|
||||
prec = (*it).second;
|
||||
break;
|
||||
}
|
||||
level--;
|
||||
}
|
||||
return prec;
|
||||
}
|
||||
|
||||
protected:
|
||||
int currentLevel() const { return static_cast<int>(table.size()) - 1; }
|
||||
|
||||
std::vector<TSymbolTableLevel*> table;
|
||||
typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
|
||||
std::vector< PrecisionStackLevel > precisionStack;
|
||||
int uniqueId; // for unique identification in code generation
|
||||
};
|
||||
|
||||
#endif // _SYMBOL_TABLE_INCLUDED_
|
40
src/3rdparty/angle/src/compiler/TranslatorESSL.cpp
vendored
Normal file
40
src/3rdparty/angle/src/compiler/TranslatorESSL.cpp
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// 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 "compiler/TranslatorESSL.h"
|
||||
|
||||
#include "compiler/OutputESSL.h"
|
||||
|
||||
TranslatorESSL::TranslatorESSL(ShShaderType type, ShShaderSpec spec)
|
||||
: TCompiler(type, spec) {
|
||||
}
|
||||
|
||||
void TranslatorESSL::translate(TIntermNode* root) {
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
|
||||
// Write built-in extension behaviors.
|
||||
writeExtensionBehavior();
|
||||
|
||||
// Write emulated built-in functions if needed.
|
||||
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
|
||||
sink, getShaderType() == SH_FRAGMENT_SHADER);
|
||||
|
||||
// Write translated shader.
|
||||
TOutputESSL outputESSL(sink);
|
||||
root->traverse(&outputESSL);
|
||||
}
|
||||
|
||||
void TranslatorESSL::writeExtensionBehavior() {
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
|
||||
for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
|
||||
iter != extensionBehavior.end(); ++iter) {
|
||||
if (iter->second != EBhUndefined) {
|
||||
sink << "#extension " << iter->first << " : "
|
||||
<< getBehaviorString(iter->second) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
23
src/3rdparty/angle/src/compiler/TranslatorESSL.h
vendored
Normal file
23
src/3rdparty/angle/src/compiler/TranslatorESSL.h
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_TRANSLATORESSL_H_
|
||||
#define COMPILER_TRANSLATORESSL_H_
|
||||
|
||||
#include "compiler/ShHandle.h"
|
||||
|
||||
class TranslatorESSL : public TCompiler {
|
||||
public:
|
||||
TranslatorESSL(ShShaderType type, ShShaderSpec spec);
|
||||
|
||||
protected:
|
||||
virtual void translate(TIntermNode* root);
|
||||
|
||||
private:
|
||||
void writeExtensionBehavior();
|
||||
};
|
||||
|
||||
#endif // COMPILER_TRANSLATORESSL_H_
|
41
src/3rdparty/angle/src/compiler/TranslatorGLSL.cpp
vendored
Normal file
41
src/3rdparty/angle/src/compiler/TranslatorGLSL.cpp
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/TranslatorGLSL.h"
|
||||
|
||||
#include "compiler/OutputGLSL.h"
|
||||
#include "compiler/VersionGLSL.h"
|
||||
|
||||
static void writeVersion(ShShaderType type, TIntermNode* root,
|
||||
TInfoSinkBase& sink) {
|
||||
TVersionGLSL versionGLSL(type);
|
||||
root->traverse(&versionGLSL);
|
||||
int version = versionGLSL.getVersion();
|
||||
// We need to write version directive only if it is greater than 110.
|
||||
// If there is no version directive in the shader, 110 is implied.
|
||||
if (version > 110) {
|
||||
sink << "#version " << version << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
TranslatorGLSL::TranslatorGLSL(ShShaderType type, ShShaderSpec spec)
|
||||
: TCompiler(type, spec) {
|
||||
}
|
||||
|
||||
void TranslatorGLSL::translate(TIntermNode* root) {
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
|
||||
// Write GLSL version.
|
||||
writeVersion(getShaderType(), root, sink);
|
||||
|
||||
// Write emulated built-in functions if needed.
|
||||
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
|
||||
sink, false);
|
||||
|
||||
// Write translated shader.
|
||||
TOutputGLSL outputGLSL(sink);
|
||||
root->traverse(&outputGLSL);
|
||||
}
|
20
src/3rdparty/angle/src/compiler/TranslatorGLSL.h
vendored
Normal file
20
src/3rdparty/angle/src/compiler/TranslatorGLSL.h
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_TRANSLATORGLSL_H_
|
||||
#define COMPILER_TRANSLATORGLSL_H_
|
||||
|
||||
#include "compiler/ShHandle.h"
|
||||
|
||||
class TranslatorGLSL : public TCompiler {
|
||||
public:
|
||||
TranslatorGLSL(ShShaderType type, ShShaderSpec spec);
|
||||
|
||||
protected:
|
||||
virtual void translate(TIntermNode* root);
|
||||
};
|
||||
|
||||
#endif // COMPILER_TRANSLATORGLSL_H_
|
23
src/3rdparty/angle/src/compiler/TranslatorHLSL.cpp
vendored
Normal file
23
src/3rdparty/angle/src/compiler/TranslatorHLSL.cpp
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/TranslatorHLSL.h"
|
||||
|
||||
#include "compiler/InitializeParseContext.h"
|
||||
#include "compiler/OutputHLSL.h"
|
||||
|
||||
TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec)
|
||||
: TCompiler(type, spec)
|
||||
{
|
||||
}
|
||||
|
||||
void TranslatorHLSL::translate(TIntermNode *root)
|
||||
{
|
||||
TParseContext& parseContext = *GetGlobalParseContext();
|
||||
sh::OutputHLSL outputHLSL(parseContext);
|
||||
|
||||
outputHLSL.output();
|
||||
}
|
20
src/3rdparty/angle/src/compiler/TranslatorHLSL.h
vendored
Normal file
20
src/3rdparty/angle/src/compiler/TranslatorHLSL.h
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_TRANSLATORHLSL_H_
|
||||
#define COMPILER_TRANSLATORHLSL_H_
|
||||
|
||||
#include "compiler/ShHandle.h"
|
||||
|
||||
class TranslatorHLSL : public TCompiler {
|
||||
public:
|
||||
TranslatorHLSL(ShShaderType type, ShShaderSpec spec);
|
||||
|
||||
protected:
|
||||
virtual void translate(TIntermNode* root);
|
||||
};
|
||||
|
||||
#endif // COMPILER_TRANSLATORHLSL_H_
|
318
src/3rdparty/angle/src/compiler/Types.h
vendored
Normal file
318
src/3rdparty/angle/src/compiler/Types.h
vendored
Normal file
@ -0,0 +1,318 @@
|
||||
//
|
||||
// Copyright (c) 2002-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 _TYPES_INCLUDED
|
||||
#define _TYPES_INCLUDED
|
||||
|
||||
#include "compiler/BaseTypes.h"
|
||||
#include "compiler/Common.h"
|
||||
#include "compiler/debug.h"
|
||||
|
||||
class TType;
|
||||
struct TPublicType;
|
||||
|
||||
//
|
||||
// Need to have association of line numbers to types in a list for building structs.
|
||||
//
|
||||
struct TTypeLine {
|
||||
TType* type;
|
||||
int line;
|
||||
};
|
||||
typedef TVector<TTypeLine> TTypeList;
|
||||
|
||||
inline TTypeList* NewPoolTTypeList()
|
||||
{
|
||||
void* memory = GlobalPoolAllocator.allocate(sizeof(TTypeList));
|
||||
return new(memory) TTypeList;
|
||||
}
|
||||
|
||||
typedef TMap<TTypeList*, TTypeList*> TStructureMap;
|
||||
typedef TMap<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
|
||||
|
||||
//
|
||||
// Base class for things that have a type.
|
||||
//
|
||||
class TType
|
||||
{
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
TType() {}
|
||||
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
|
||||
type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
|
||||
maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
|
||||
{
|
||||
}
|
||||
explicit TType(const TPublicType &p);
|
||||
TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
|
||||
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
|
||||
maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)
|
||||
{
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
}
|
||||
|
||||
void copyType(const TType& copyOf, TStructureMap& remapper)
|
||||
{
|
||||
type = copyOf.type;
|
||||
precision = copyOf.precision;
|
||||
qualifier = copyOf.qualifier;
|
||||
size = copyOf.size;
|
||||
matrix = copyOf.matrix;
|
||||
array = copyOf.array;
|
||||
arraySize = copyOf.arraySize;
|
||||
|
||||
TStructureMapIterator iter;
|
||||
if (copyOf.structure) {
|
||||
if ((iter = remapper.find(structure)) == remapper.end()) {
|
||||
// create the new structure here
|
||||
structure = NewPoolTTypeList();
|
||||
for (unsigned int i = 0; i < copyOf.structure->size(); ++i) {
|
||||
TTypeLine typeLine;
|
||||
typeLine.line = (*copyOf.structure)[i].line;
|
||||
typeLine.type = (*copyOf.structure)[i].type->clone(remapper);
|
||||
structure->push_back(typeLine);
|
||||
}
|
||||
} else {
|
||||
structure = iter->second;
|
||||
}
|
||||
} else
|
||||
structure = 0;
|
||||
|
||||
fieldName = 0;
|
||||
if (copyOf.fieldName)
|
||||
fieldName = NewPoolTString(copyOf.fieldName->c_str());
|
||||
typeName = 0;
|
||||
if (copyOf.typeName)
|
||||
typeName = NewPoolTString(copyOf.typeName->c_str());
|
||||
|
||||
mangled = 0;
|
||||
if (copyOf.mangled)
|
||||
mangled = NewPoolTString(copyOf.mangled->c_str());
|
||||
|
||||
structureSize = copyOf.structureSize;
|
||||
maxArraySize = copyOf.maxArraySize;
|
||||
deepestStructNesting = copyOf.deepestStructNesting;
|
||||
assert(copyOf.arrayInformationType == 0);
|
||||
arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
|
||||
}
|
||||
|
||||
TType* clone(TStructureMap& remapper)
|
||||
{
|
||||
TType *newType = new TType();
|
||||
newType->copyType(*this, remapper);
|
||||
|
||||
return newType;
|
||||
}
|
||||
|
||||
TBasicType getBasicType() const { return type; }
|
||||
void setBasicType(TBasicType t) { type = t; }
|
||||
|
||||
TPrecision getPrecision() const { return precision; }
|
||||
void setPrecision(TPrecision p) { precision = p; }
|
||||
|
||||
TQualifier getQualifier() const { return qualifier; }
|
||||
void setQualifier(TQualifier q) { qualifier = q; }
|
||||
|
||||
// One-dimensional size of single instance type
|
||||
int getNominalSize() const { return size; }
|
||||
void setNominalSize(int s) { size = s; }
|
||||
// Full size of single instance of type
|
||||
int getObjectSize() const
|
||||
{
|
||||
int totalSize;
|
||||
|
||||
if (getBasicType() == EbtStruct)
|
||||
totalSize = getStructSize();
|
||||
else if (matrix)
|
||||
totalSize = size * size;
|
||||
else
|
||||
totalSize = size;
|
||||
|
||||
if (isArray())
|
||||
totalSize *= std::max(getArraySize(), getMaxArraySize());
|
||||
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
bool isMatrix() const { return matrix ? true : false; }
|
||||
void setMatrix(bool m) { matrix = m; }
|
||||
|
||||
bool isArray() const { return array ? true : false; }
|
||||
int getArraySize() const { return arraySize; }
|
||||
void setArraySize(int s) { array = true; arraySize = s; }
|
||||
int getMaxArraySize () const { return maxArraySize; }
|
||||
void setMaxArraySize (int s) { maxArraySize = s; }
|
||||
void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
|
||||
void setArrayInformationType(TType* t) { arrayInformationType = t; }
|
||||
TType* getArrayInformationType() const { return arrayInformationType; }
|
||||
|
||||
bool isVector() const { return size > 1 && !matrix; }
|
||||
bool isScalar() const { return size == 1 && !matrix && !structure; }
|
||||
|
||||
TTypeList* getStruct() const { return structure; }
|
||||
void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
|
||||
|
||||
const TString& getTypeName() const
|
||||
{
|
||||
assert(typeName);
|
||||
return *typeName;
|
||||
}
|
||||
void setTypeName(const TString& n)
|
||||
{
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
}
|
||||
|
||||
bool isField() const { return fieldName != 0; }
|
||||
const TString& getFieldName() const
|
||||
{
|
||||
assert(fieldName);
|
||||
return *fieldName;
|
||||
}
|
||||
void setFieldName(const TString& n)
|
||||
{
|
||||
fieldName = NewPoolTString(n.c_str());
|
||||
}
|
||||
|
||||
TString& getMangledName() {
|
||||
if (!mangled) {
|
||||
mangled = NewPoolTString("");
|
||||
buildMangledName(*mangled);
|
||||
*mangled += ';' ;
|
||||
}
|
||||
|
||||
return *mangled;
|
||||
}
|
||||
|
||||
bool sameElementType(const TType& right) const {
|
||||
return type == right.type &&
|
||||
size == right.size &&
|
||||
matrix == right.matrix &&
|
||||
structure == right.structure;
|
||||
}
|
||||
bool operator==(const TType& right) const {
|
||||
return type == right.type &&
|
||||
size == right.size &&
|
||||
matrix == right.matrix &&
|
||||
array == right.array && (!array || arraySize == right.arraySize) &&
|
||||
structure == right.structure;
|
||||
// don't check the qualifier, it's not ever what's being sought after
|
||||
}
|
||||
bool operator!=(const TType& right) const {
|
||||
return !operator==(right);
|
||||
}
|
||||
bool operator<(const TType& right) const {
|
||||
if (type != right.type) return type < right.type;
|
||||
if (size != right.size) return size < right.size;
|
||||
if (matrix != right.matrix) return matrix < right.matrix;
|
||||
if (array != right.array) return array < right.array;
|
||||
if (arraySize != right.arraySize) return arraySize < right.arraySize;
|
||||
if (structure != right.structure) return structure < right.structure;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* getBasicString() const { return ::getBasicString(type); }
|
||||
const char* getPrecisionString() const { return ::getPrecisionString(precision); }
|
||||
const char* getQualifierString() const { return ::getQualifierString(qualifier); }
|
||||
TString getCompleteString() const;
|
||||
|
||||
// If this type is a struct, returns the deepest struct nesting of
|
||||
// any field in the struct. For example:
|
||||
// struct nesting1 {
|
||||
// vec4 position;
|
||||
// };
|
||||
// struct nesting2 {
|
||||
// nesting1 field1;
|
||||
// vec4 field2;
|
||||
// };
|
||||
// For type "nesting2", this method would return 2 -- the number
|
||||
// of structures through which indirection must occur to reach the
|
||||
// deepest field (nesting2.field1.position).
|
||||
int getDeepestStructNesting() const { return deepestStructNesting; }
|
||||
|
||||
bool isStructureContainingArrays() const;
|
||||
|
||||
protected:
|
||||
void buildMangledName(TString&);
|
||||
int getStructSize() const;
|
||||
void computeDeepestStructNesting();
|
||||
|
||||
TBasicType type : 6;
|
||||
TPrecision precision;
|
||||
TQualifier qualifier : 7;
|
||||
int size : 8; // size of vector or matrix, not size of array
|
||||
unsigned int matrix : 1;
|
||||
unsigned int array : 1;
|
||||
int arraySize;
|
||||
int maxArraySize;
|
||||
TType* arrayInformationType;
|
||||
|
||||
TTypeList* structure; // 0 unless this is a struct
|
||||
mutable int structureSize;
|
||||
int deepestStructNesting;
|
||||
|
||||
TString *fieldName; // for structure field names
|
||||
TString *mangled;
|
||||
TString *typeName; // for structure field type name
|
||||
};
|
||||
|
||||
//
|
||||
// This is a workaround for a problem with the yacc stack, It can't have
|
||||
// types that it thinks have non-trivial constructors. It should
|
||||
// just be used while recognizing the grammar, not anything else. Pointers
|
||||
// could be used, but also trying to avoid lots of memory management overhead.
|
||||
//
|
||||
// Not as bad as it looks, there is no actual assumption that the fields
|
||||
// match up or are name the same or anything like that.
|
||||
//
|
||||
struct TPublicType
|
||||
{
|
||||
TBasicType type;
|
||||
TQualifier qualifier;
|
||||
TPrecision precision;
|
||||
int size; // size of vector or matrix, not size of array
|
||||
bool matrix;
|
||||
bool array;
|
||||
int arraySize;
|
||||
TType* userDef;
|
||||
int line;
|
||||
|
||||
void setBasic(TBasicType bt, TQualifier q, int ln = 0)
|
||||
{
|
||||
type = bt;
|
||||
qualifier = q;
|
||||
precision = EbpUndefined;
|
||||
size = 1;
|
||||
matrix = false;
|
||||
array = false;
|
||||
arraySize = 0;
|
||||
userDef = 0;
|
||||
line = ln;
|
||||
}
|
||||
|
||||
void setAggregate(int s, bool m = false)
|
||||
{
|
||||
size = s;
|
||||
matrix = m;
|
||||
}
|
||||
|
||||
void setArray(bool a, int s = 0)
|
||||
{
|
||||
array = a;
|
||||
arraySize = s;
|
||||
}
|
||||
|
||||
bool isStructureContainingArrays() const
|
||||
{
|
||||
if (!userDef)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return userDef->isStructureContainingArrays();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _TYPES_INCLUDED_
|
172
src/3rdparty/angle/src/compiler/UnfoldShortCircuit.cpp
vendored
Normal file
172
src/3rdparty/angle/src/compiler/UnfoldShortCircuit.cpp
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
//
|
||||
// Copyright (c) 2002-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.
|
||||
//
|
||||
// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements.
|
||||
// The results are assigned to s# temporaries, which are used by the main translator instead of
|
||||
// the original expression.
|
||||
//
|
||||
|
||||
#include "compiler/UnfoldShortCircuit.h"
|
||||
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/OutputHLSL.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
UnfoldShortCircuit::UnfoldShortCircuit(TParseContext &context, OutputHLSL *outputHLSL) : mContext(context), mOutputHLSL(outputHLSL)
|
||||
{
|
||||
mTemporaryIndex = 0;
|
||||
}
|
||||
|
||||
void UnfoldShortCircuit::traverse(TIntermNode *node)
|
||||
{
|
||||
int rewindIndex = mTemporaryIndex;
|
||||
node->traverse(this);
|
||||
mTemporaryIndex = rewindIndex;
|
||||
}
|
||||
|
||||
bool UnfoldShortCircuit::visitBinary(Visit visit, TIntermBinary *node)
|
||||
{
|
||||
TInfoSinkBase &out = mOutputHLSL->getBodyStream();
|
||||
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpLogicalOr:
|
||||
// "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; else s = y;",
|
||||
// and then further simplifies down to "bool s = x; if(!s) s = y;".
|
||||
{
|
||||
int i = mTemporaryIndex;
|
||||
|
||||
out << "bool s" << i << ";\n";
|
||||
|
||||
out << "{\n";
|
||||
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getLeft()->traverse(this);
|
||||
out << "s" << i << " = ";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getLeft()->traverse(mOutputHLSL);
|
||||
out << ";\n";
|
||||
out << "if(!s" << i << ")\n"
|
||||
"{\n";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getRight()->traverse(this);
|
||||
out << " s" << i << " = ";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getRight()->traverse(mOutputHLSL);
|
||||
out << ";\n"
|
||||
"}\n";
|
||||
|
||||
out << "}\n";
|
||||
|
||||
mTemporaryIndex = i + 1;
|
||||
}
|
||||
return false;
|
||||
case EOpLogicalAnd:
|
||||
// "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; else s = false;",
|
||||
// and then further simplifies down to "bool s = x; if(s) s = y;".
|
||||
{
|
||||
int i = mTemporaryIndex;
|
||||
|
||||
out << "bool s" << i << ";\n";
|
||||
|
||||
out << "{\n";
|
||||
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getLeft()->traverse(this);
|
||||
out << "s" << i << " = ";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getLeft()->traverse(mOutputHLSL);
|
||||
out << ";\n";
|
||||
out << "if(s" << i << ")\n"
|
||||
"{\n";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getRight()->traverse(this);
|
||||
out << " s" << i << " = ";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getRight()->traverse(mOutputHLSL);
|
||||
out << ";\n"
|
||||
"}\n";
|
||||
|
||||
out << "}\n";
|
||||
|
||||
mTemporaryIndex = i + 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node)
|
||||
{
|
||||
TInfoSinkBase &out = mOutputHLSL->getBodyStream();
|
||||
|
||||
// Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;"
|
||||
if (node->usesTernaryOperator())
|
||||
{
|
||||
int i = mTemporaryIndex;
|
||||
|
||||
out << mOutputHLSL->typeString(node->getType()) << " s" << i << ";\n";
|
||||
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getCondition()->traverse(this);
|
||||
out << "if(";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getCondition()->traverse(mOutputHLSL);
|
||||
out << ")\n"
|
||||
"{\n";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getTrueBlock()->traverse(this);
|
||||
out << " s" << i << " = ";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getTrueBlock()->traverse(mOutputHLSL);
|
||||
out << ";\n"
|
||||
"}\n"
|
||||
"else\n"
|
||||
"{\n";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getFalseBlock()->traverse(this);
|
||||
out << " s" << i << " = ";
|
||||
mTemporaryIndex = i + 1;
|
||||
node->getFalseBlock()->traverse(mOutputHLSL);
|
||||
out << ";\n"
|
||||
"}\n";
|
||||
|
||||
mTemporaryIndex = i + 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UnfoldShortCircuit::visitLoop(Visit visit, TIntermLoop *node)
|
||||
{
|
||||
int rewindIndex = mTemporaryIndex;
|
||||
|
||||
if (node->getInit())
|
||||
{
|
||||
node->getInit()->traverse(this);
|
||||
}
|
||||
|
||||
if (node->getCondition())
|
||||
{
|
||||
node->getCondition()->traverse(this);
|
||||
}
|
||||
|
||||
if (node->getExpression())
|
||||
{
|
||||
node->getExpression()->traverse(this);
|
||||
}
|
||||
|
||||
mTemporaryIndex = rewindIndex;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int UnfoldShortCircuit::getNextTemporaryIndex()
|
||||
{
|
||||
return mTemporaryIndex++;
|
||||
}
|
||||
}
|
39
src/3rdparty/angle/src/compiler/UnfoldShortCircuit.h
vendored
Normal file
39
src/3rdparty/angle/src/compiler/UnfoldShortCircuit.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (c) 2002-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.
|
||||
//
|
||||
// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements
|
||||
//
|
||||
|
||||
#ifndef COMPILER_UNFOLDSHORTCIRCUIT_H_
|
||||
#define COMPILER_UNFOLDSHORTCIRCUIT_H_
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
class OutputHLSL;
|
||||
|
||||
class UnfoldShortCircuit : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
UnfoldShortCircuit(TParseContext &context, OutputHLSL *outputHLSL);
|
||||
|
||||
void traverse(TIntermNode *node);
|
||||
bool visitBinary(Visit visit, TIntermBinary*);
|
||||
bool visitSelection(Visit visit, TIntermSelection *node);
|
||||
bool visitLoop(Visit visit, TIntermLoop *node);
|
||||
|
||||
int getNextTemporaryIndex();
|
||||
|
||||
protected:
|
||||
TParseContext &mContext;
|
||||
OutputHLSL *const mOutputHLSL;
|
||||
|
||||
int mTemporaryIndex;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // COMPILER_UNFOLDSHORTCIRCUIT_H_
|
512
src/3rdparty/angle/src/compiler/ValidateLimitations.cpp
vendored
Normal file
512
src/3rdparty/angle/src/compiler/ValidateLimitations.cpp
vendored
Normal file
@ -0,0 +1,512 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/ValidateLimitations.h"
|
||||
#include "compiler/InfoSink.h"
|
||||
#include "compiler/InitializeParseContext.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
|
||||
namespace {
|
||||
bool IsLoopIndex(const TIntermSymbol* symbol, const TLoopStack& stack) {
|
||||
for (TLoopStack::const_iterator i = stack.begin(); i != stack.end(); ++i) {
|
||||
if (i->index.id == symbol->getId())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MarkLoopForUnroll(const TIntermSymbol* symbol, TLoopStack& stack) {
|
||||
for (TLoopStack::iterator i = stack.begin(); i != stack.end(); ++i) {
|
||||
if (i->index.id == symbol->getId()) {
|
||||
ASSERT(i->loop != NULL);
|
||||
i->loop->setUnrollFlag(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// Traverses a node to check if it represents a constant index expression.
|
||||
// Definition:
|
||||
// constant-index-expressions are a superset of constant-expressions.
|
||||
// Constant-index-expressions can include loop indices as defined in
|
||||
// GLSL ES 1.0 spec, Appendix A, section 4.
|
||||
// The following are constant-index-expressions:
|
||||
// - Constant expressions
|
||||
// - Loop indices as defined in section 4
|
||||
// - Expressions composed of both of the above
|
||||
class ValidateConstIndexExpr : public TIntermTraverser {
|
||||
public:
|
||||
ValidateConstIndexExpr(const TLoopStack& stack)
|
||||
: mValid(true), mLoopStack(stack) {}
|
||||
|
||||
// Returns true if the parsed node represents a constant index expression.
|
||||
bool isValid() const { return mValid; }
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol* symbol) {
|
||||
// Only constants and loop indices are allowed in a
|
||||
// constant index expression.
|
||||
if (mValid) {
|
||||
mValid = (symbol->getQualifier() == EvqConst) ||
|
||||
IsLoopIndex(symbol, mLoopStack);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool mValid;
|
||||
const TLoopStack& mLoopStack;
|
||||
};
|
||||
|
||||
// Traverses a node to check if it uses a loop index.
|
||||
// If an int loop index is used in its body as a sampler array index,
|
||||
// mark the loop for unroll.
|
||||
class ValidateLoopIndexExpr : public TIntermTraverser {
|
||||
public:
|
||||
ValidateLoopIndexExpr(TLoopStack& stack)
|
||||
: mUsesFloatLoopIndex(false),
|
||||
mUsesIntLoopIndex(false),
|
||||
mLoopStack(stack) {}
|
||||
|
||||
bool usesFloatLoopIndex() const { return mUsesFloatLoopIndex; }
|
||||
bool usesIntLoopIndex() const { return mUsesIntLoopIndex; }
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol* symbol) {
|
||||
if (IsLoopIndex(symbol, mLoopStack)) {
|
||||
switch (symbol->getBasicType()) {
|
||||
case EbtFloat:
|
||||
mUsesFloatLoopIndex = true;
|
||||
break;
|
||||
case EbtInt:
|
||||
mUsesIntLoopIndex = true;
|
||||
MarkLoopForUnroll(symbol, mLoopStack);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool mUsesFloatLoopIndex;
|
||||
bool mUsesIntLoopIndex;
|
||||
TLoopStack& mLoopStack;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
ValidateLimitations::ValidateLimitations(ShShaderType shaderType,
|
||||
TInfoSinkBase& sink)
|
||||
: mShaderType(shaderType),
|
||||
mSink(sink),
|
||||
mNumErrors(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node)
|
||||
{
|
||||
// Check if loop index is modified in the loop body.
|
||||
validateOperation(node, node->getLeft());
|
||||
|
||||
// Check indexing.
|
||||
switch (node->getOp()) {
|
||||
case EOpIndexDirect:
|
||||
validateIndexing(node);
|
||||
break;
|
||||
case EOpIndexIndirect:
|
||||
#if defined(__APPLE__)
|
||||
// Loop unrolling is a work-around for a Mac Cg compiler bug where it
|
||||
// crashes when a sampler array's index is also the loop index.
|
||||
// Once Apple fixes this bug, we should remove the code in this CL.
|
||||
// See http://codereview.appspot.com/4331048/.
|
||||
if ((node->getLeft() != NULL) && (node->getRight() != NULL) &&
|
||||
(node->getLeft()->getAsSymbolNode())) {
|
||||
TIntermSymbol* symbol = node->getLeft()->getAsSymbolNode();
|
||||
if (IsSampler(symbol->getBasicType()) && symbol->isArray()) {
|
||||
ValidateLoopIndexExpr validate(mLoopStack);
|
||||
node->getRight()->traverse(&validate);
|
||||
if (validate.usesFloatLoopIndex()) {
|
||||
error(node->getLine(),
|
||||
"sampler array index is float loop index",
|
||||
"for");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
validateIndexing(node);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node)
|
||||
{
|
||||
// Check if loop index is modified in the loop body.
|
||||
validateOperation(node, node->getOperand());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node)
|
||||
{
|
||||
switch (node->getOp()) {
|
||||
case EOpFunctionCall:
|
||||
validateFunctionCall(node);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node)
|
||||
{
|
||||
if (!validateLoopType(node))
|
||||
return false;
|
||||
|
||||
TLoopInfo info;
|
||||
memset(&info, 0, sizeof(TLoopInfo));
|
||||
info.loop = node;
|
||||
if (!validateForLoopHeader(node, &info))
|
||||
return false;
|
||||
|
||||
TIntermNode* body = node->getBody();
|
||||
if (body != NULL) {
|
||||
mLoopStack.push_back(info);
|
||||
body->traverse(this);
|
||||
mLoopStack.pop_back();
|
||||
}
|
||||
|
||||
// The loop is fully processed - no need to visit children.
|
||||
return false;
|
||||
}
|
||||
|
||||
void ValidateLimitations::error(TSourceLoc loc,
|
||||
const char *reason, const char* token)
|
||||
{
|
||||
mSink.prefix(EPrefixError);
|
||||
mSink.location(loc);
|
||||
mSink << "'" << token << "' : " << reason << "\n";
|
||||
++mNumErrors;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::withinLoopBody() const
|
||||
{
|
||||
return !mLoopStack.empty();
|
||||
}
|
||||
|
||||
bool ValidateLimitations::isLoopIndex(const TIntermSymbol* symbol) const
|
||||
{
|
||||
return IsLoopIndex(symbol, mLoopStack);
|
||||
}
|
||||
|
||||
bool ValidateLimitations::validateLoopType(TIntermLoop* node) {
|
||||
TLoopType type = node->getType();
|
||||
if (type == ELoopFor)
|
||||
return true;
|
||||
|
||||
// Reject while and do-while loops.
|
||||
error(node->getLine(),
|
||||
"This type of loop is not allowed",
|
||||
type == ELoopWhile ? "while" : "do");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::validateForLoopHeader(TIntermLoop* node,
|
||||
TLoopInfo* info)
|
||||
{
|
||||
ASSERT(node->getType() == ELoopFor);
|
||||
|
||||
//
|
||||
// The for statement has the form:
|
||||
// for ( init-declaration ; condition ; expression ) statement
|
||||
//
|
||||
if (!validateForLoopInit(node, info))
|
||||
return false;
|
||||
if (!validateForLoopCond(node, info))
|
||||
return false;
|
||||
if (!validateForLoopExpr(node, info))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::validateForLoopInit(TIntermLoop* node,
|
||||
TLoopInfo* info)
|
||||
{
|
||||
TIntermNode* init = node->getInit();
|
||||
if (init == NULL) {
|
||||
error(node->getLine(), "Missing init declaration", "for");
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// init-declaration has the form:
|
||||
// type-specifier identifier = constant-expression
|
||||
//
|
||||
TIntermAggregate* decl = init->getAsAggregate();
|
||||
if ((decl == NULL) || (decl->getOp() != EOpDeclaration)) {
|
||||
error(init->getLine(), "Invalid init declaration", "for");
|
||||
return false;
|
||||
}
|
||||
// To keep things simple do not allow declaration list.
|
||||
TIntermSequence& declSeq = decl->getSequence();
|
||||
if (declSeq.size() != 1) {
|
||||
error(decl->getLine(), "Invalid init declaration", "for");
|
||||
return false;
|
||||
}
|
||||
TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
|
||||
if ((declInit == NULL) || (declInit->getOp() != EOpInitialize)) {
|
||||
error(decl->getLine(), "Invalid init declaration", "for");
|
||||
return false;
|
||||
}
|
||||
TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
|
||||
if (symbol == NULL) {
|
||||
error(declInit->getLine(), "Invalid init declaration", "for");
|
||||
return false;
|
||||
}
|
||||
// The loop index has type int or float.
|
||||
TBasicType type = symbol->getBasicType();
|
||||
if ((type != EbtInt) && (type != EbtFloat)) {
|
||||
error(symbol->getLine(),
|
||||
"Invalid type for loop index", getBasicString(type));
|
||||
return false;
|
||||
}
|
||||
// The loop index is initialized with constant expression.
|
||||
if (!isConstExpr(declInit->getRight())) {
|
||||
error(declInit->getLine(),
|
||||
"Loop index cannot be initialized with non-constant expression",
|
||||
symbol->getSymbol().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
info->index.id = symbol->getId();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::validateForLoopCond(TIntermLoop* node,
|
||||
TLoopInfo* info)
|
||||
{
|
||||
TIntermNode* cond = node->getCondition();
|
||||
if (cond == NULL) {
|
||||
error(node->getLine(), "Missing condition", "for");
|
||||
return false;
|
||||
}
|
||||
//
|
||||
// condition has the form:
|
||||
// loop_index relational_operator constant_expression
|
||||
//
|
||||
TIntermBinary* binOp = cond->getAsBinaryNode();
|
||||
if (binOp == NULL) {
|
||||
error(node->getLine(), "Invalid condition", "for");
|
||||
return false;
|
||||
}
|
||||
// Loop index should be to the left of relational operator.
|
||||
TIntermSymbol* symbol = binOp->getLeft()->getAsSymbolNode();
|
||||
if (symbol == NULL) {
|
||||
error(binOp->getLine(), "Invalid condition", "for");
|
||||
return false;
|
||||
}
|
||||
if (symbol->getId() != info->index.id) {
|
||||
error(symbol->getLine(),
|
||||
"Expected loop index", symbol->getSymbol().c_str());
|
||||
return false;
|
||||
}
|
||||
// Relational operator is one of: > >= < <= == or !=.
|
||||
switch (binOp->getOp()) {
|
||||
case EOpEqual:
|
||||
case EOpNotEqual:
|
||||
case EOpLessThan:
|
||||
case EOpGreaterThan:
|
||||
case EOpLessThanEqual:
|
||||
case EOpGreaterThanEqual:
|
||||
break;
|
||||
default:
|
||||
error(binOp->getLine(),
|
||||
"Invalid relational operator",
|
||||
getOperatorString(binOp->getOp()));
|
||||
break;
|
||||
}
|
||||
// Loop index must be compared with a constant.
|
||||
if (!isConstExpr(binOp->getRight())) {
|
||||
error(binOp->getLine(),
|
||||
"Loop index cannot be compared with non-constant expression",
|
||||
symbol->getSymbol().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::validateForLoopExpr(TIntermLoop* node,
|
||||
TLoopInfo* info)
|
||||
{
|
||||
TIntermNode* expr = node->getExpression();
|
||||
if (expr == NULL) {
|
||||
error(node->getLine(), "Missing expression", "for");
|
||||
return false;
|
||||
}
|
||||
|
||||
// for expression has one of the following forms:
|
||||
// loop_index++
|
||||
// loop_index--
|
||||
// loop_index += constant_expression
|
||||
// loop_index -= constant_expression
|
||||
// ++loop_index
|
||||
// --loop_index
|
||||
// The last two forms are not specified in the spec, but I am assuming
|
||||
// its an oversight.
|
||||
TIntermUnary* unOp = expr->getAsUnaryNode();
|
||||
TIntermBinary* binOp = unOp ? NULL : expr->getAsBinaryNode();
|
||||
|
||||
TOperator op = EOpNull;
|
||||
TIntermSymbol* symbol = NULL;
|
||||
if (unOp != NULL) {
|
||||
op = unOp->getOp();
|
||||
symbol = unOp->getOperand()->getAsSymbolNode();
|
||||
} else if (binOp != NULL) {
|
||||
op = binOp->getOp();
|
||||
symbol = binOp->getLeft()->getAsSymbolNode();
|
||||
}
|
||||
|
||||
// The operand must be loop index.
|
||||
if (symbol == NULL) {
|
||||
error(expr->getLine(), "Invalid expression", "for");
|
||||
return false;
|
||||
}
|
||||
if (symbol->getId() != info->index.id) {
|
||||
error(symbol->getLine(),
|
||||
"Expected loop index", symbol->getSymbol().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// The operator is one of: ++ -- += -=.
|
||||
switch (op) {
|
||||
case EOpPostIncrement:
|
||||
case EOpPostDecrement:
|
||||
case EOpPreIncrement:
|
||||
case EOpPreDecrement:
|
||||
ASSERT((unOp != NULL) && (binOp == NULL));
|
||||
break;
|
||||
case EOpAddAssign:
|
||||
case EOpSubAssign:
|
||||
ASSERT((unOp == NULL) && (binOp != NULL));
|
||||
break;
|
||||
default:
|
||||
error(expr->getLine(), "Invalid operator", getOperatorString(op));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Loop index must be incremented/decremented with a constant.
|
||||
if (binOp != NULL) {
|
||||
if (!isConstExpr(binOp->getRight())) {
|
||||
error(binOp->getLine(),
|
||||
"Loop index cannot be modified by non-constant expression",
|
||||
symbol->getSymbol().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node)
|
||||
{
|
||||
ASSERT(node->getOp() == EOpFunctionCall);
|
||||
|
||||
// If not within loop body, there is nothing to check.
|
||||
if (!withinLoopBody())
|
||||
return true;
|
||||
|
||||
// List of param indices for which loop indices are used as argument.
|
||||
typedef std::vector<int> ParamIndex;
|
||||
ParamIndex pIndex;
|
||||
TIntermSequence& params = node->getSequence();
|
||||
for (TIntermSequence::size_type i = 0; i < params.size(); ++i) {
|
||||
TIntermSymbol* symbol = params[i]->getAsSymbolNode();
|
||||
if (symbol && isLoopIndex(symbol))
|
||||
pIndex.push_back(i);
|
||||
}
|
||||
// If none of the loop indices are used as arguments,
|
||||
// there is nothing to check.
|
||||
if (pIndex.empty())
|
||||
return true;
|
||||
|
||||
bool valid = true;
|
||||
TSymbolTable& symbolTable = GlobalParseContext->symbolTable;
|
||||
TSymbol* symbol = symbolTable.find(node->getName());
|
||||
ASSERT(symbol && symbol->isFunction());
|
||||
TFunction* function = static_cast<TFunction*>(symbol);
|
||||
for (ParamIndex::const_iterator i = pIndex.begin();
|
||||
i != pIndex.end(); ++i) {
|
||||
const TParameter& param = function->getParam(*i);
|
||||
TQualifier qual = param.type->getQualifier();
|
||||
if ((qual == EvqOut) || (qual == EvqInOut)) {
|
||||
error(params[*i]->getLine(),
|
||||
"Loop index cannot be used as argument to a function out or inout parameter",
|
||||
params[*i]->getAsSymbolNode()->getSymbol().c_str());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::validateOperation(TIntermOperator* node,
|
||||
TIntermNode* operand) {
|
||||
// Check if loop index is modified in the loop body.
|
||||
if (!withinLoopBody() || !node->modifiesState())
|
||||
return true;
|
||||
|
||||
const TIntermSymbol* symbol = operand->getAsSymbolNode();
|
||||
if (symbol && isLoopIndex(symbol)) {
|
||||
error(node->getLine(),
|
||||
"Loop index cannot be statically assigned to within the body of the loop",
|
||||
symbol->getSymbol().c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::isConstExpr(TIntermNode* node)
|
||||
{
|
||||
ASSERT(node != NULL);
|
||||
return node->getAsConstantUnion() != NULL;
|
||||
}
|
||||
|
||||
bool ValidateLimitations::isConstIndexExpr(TIntermNode* node)
|
||||
{
|
||||
ASSERT(node != NULL);
|
||||
|
||||
ValidateConstIndexExpr validate(mLoopStack);
|
||||
node->traverse(&validate);
|
||||
return validate.isValid();
|
||||
}
|
||||
|
||||
bool ValidateLimitations::validateIndexing(TIntermBinary* node)
|
||||
{
|
||||
ASSERT((node->getOp() == EOpIndexDirect) ||
|
||||
(node->getOp() == EOpIndexIndirect));
|
||||
|
||||
bool valid = true;
|
||||
TIntermTyped* index = node->getRight();
|
||||
// The index expression must have integral type.
|
||||
if (!index->isScalar() || (index->getBasicType() != EbtInt)) {
|
||||
error(index->getLine(),
|
||||
"Index expression must have integral type",
|
||||
index->getCompleteString().c_str());
|
||||
valid = false;
|
||||
}
|
||||
// The index expession must be a constant-index-expression unless
|
||||
// the operand is a uniform in a vertex shader.
|
||||
TIntermTyped* operand = node->getLeft();
|
||||
bool skip = (mShaderType == SH_VERTEX_SHADER) &&
|
||||
(operand->getQualifier() == EvqUniform);
|
||||
if (!skip && !isConstIndexExpr(index)) {
|
||||
error(index->getLine(), "Index expression must be constant", "[]");
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
59
src/3rdparty/angle/src/compiler/ValidateLimitations.h
vendored
Normal file
59
src/3rdparty/angle/src/compiler/ValidateLimitations.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// Copyright (c) 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.
|
||||
//
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
class TInfoSinkBase;
|
||||
|
||||
struct TLoopInfo {
|
||||
struct TIndex {
|
||||
int id; // symbol id.
|
||||
} index;
|
||||
TIntermLoop* loop;
|
||||
};
|
||||
typedef TVector<TLoopInfo> TLoopStack;
|
||||
|
||||
// Traverses intermediate tree to ensure that the shader does not exceed the
|
||||
// minimum functionality mandated in GLSL 1.0 spec, Appendix A.
|
||||
class ValidateLimitations : public TIntermTraverser {
|
||||
public:
|
||||
ValidateLimitations(ShShaderType shaderType, TInfoSinkBase& sink);
|
||||
|
||||
int numErrors() const { return mNumErrors; }
|
||||
|
||||
virtual bool visitBinary(Visit, TIntermBinary*);
|
||||
virtual bool visitUnary(Visit, TIntermUnary*);
|
||||
virtual bool visitAggregate(Visit, TIntermAggregate*);
|
||||
virtual bool visitLoop(Visit, TIntermLoop*);
|
||||
|
||||
private:
|
||||
void error(TSourceLoc loc, const char *reason, const char* token);
|
||||
|
||||
bool withinLoopBody() const;
|
||||
bool isLoopIndex(const TIntermSymbol* symbol) const;
|
||||
bool validateLoopType(TIntermLoop* node);
|
||||
bool validateForLoopHeader(TIntermLoop* node, TLoopInfo* info);
|
||||
bool validateForLoopInit(TIntermLoop* node, TLoopInfo* info);
|
||||
bool validateForLoopCond(TIntermLoop* node, TLoopInfo* info);
|
||||
bool validateForLoopExpr(TIntermLoop* node, TLoopInfo* info);
|
||||
// Returns true if none of the loop indices is used as the argument to
|
||||
// the given function out or inout parameter.
|
||||
bool validateFunctionCall(TIntermAggregate* node);
|
||||
bool validateOperation(TIntermOperator* node, TIntermNode* operand);
|
||||
|
||||
// Returns true if indexing does not exceed the minimum functionality
|
||||
// mandated in GLSL 1.0 spec, Appendix A, Section 5.
|
||||
bool isConstExpr(TIntermNode* node);
|
||||
bool isConstIndexExpr(TIntermNode* node);
|
||||
bool validateIndexing(TIntermBinary* node);
|
||||
|
||||
ShShaderType mShaderType;
|
||||
TInfoSinkBase& mSink;
|
||||
int mNumErrors;
|
||||
TLoopStack mLoopStack;
|
||||
};
|
||||
|
232
src/3rdparty/angle/src/compiler/VariableInfo.cpp
vendored
Normal file
232
src/3rdparty/angle/src/compiler/VariableInfo.cpp
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include "compiler/VariableInfo.h"
|
||||
|
||||
static TString arrayBrackets(int index)
|
||||
{
|
||||
TStringStream stream;
|
||||
stream << "[" << index << "]";
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
// Returns the data type for an attribute or uniform.
|
||||
static ShDataType getVariableDataType(const TType& type)
|
||||
{
|
||||
switch (type.getBasicType()) {
|
||||
case EbtFloat:
|
||||
if (type.isMatrix()) {
|
||||
switch (type.getNominalSize()) {
|
||||
case 2: return SH_FLOAT_MAT2;
|
||||
case 3: return SH_FLOAT_MAT3;
|
||||
case 4: return SH_FLOAT_MAT4;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
} else if (type.isVector()) {
|
||||
switch (type.getNominalSize()) {
|
||||
case 2: return SH_FLOAT_VEC2;
|
||||
case 3: return SH_FLOAT_VEC3;
|
||||
case 4: return SH_FLOAT_VEC4;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
return SH_FLOAT;
|
||||
}
|
||||
case EbtInt:
|
||||
if (type.isMatrix()) {
|
||||
UNREACHABLE();
|
||||
} else if (type.isVector()) {
|
||||
switch (type.getNominalSize()) {
|
||||
case 2: return SH_INT_VEC2;
|
||||
case 3: return SH_INT_VEC3;
|
||||
case 4: return SH_INT_VEC4;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
return SH_INT;
|
||||
}
|
||||
case EbtBool:
|
||||
if (type.isMatrix()) {
|
||||
UNREACHABLE();
|
||||
} else if (type.isVector()) {
|
||||
switch (type.getNominalSize()) {
|
||||
case 2: return SH_BOOL_VEC2;
|
||||
case 3: return SH_BOOL_VEC3;
|
||||
case 4: return SH_BOOL_VEC4;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
return SH_BOOL;
|
||||
}
|
||||
case EbtSampler2D: return SH_SAMPLER_2D;
|
||||
case EbtSamplerCube: return SH_SAMPLER_CUBE;
|
||||
case EbtSamplerExternalOES: return SH_SAMPLER_EXTERNAL_OES;
|
||||
case EbtSampler2DRect: return SH_SAMPLER_2D_RECT_ARB;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
return SH_NONE;
|
||||
}
|
||||
|
||||
static void getBuiltInVariableInfo(const TType& type,
|
||||
const TString& name,
|
||||
const TString& mappedName,
|
||||
TVariableInfoList& infoList);
|
||||
static void getUserDefinedVariableInfo(const TType& type,
|
||||
const TString& name,
|
||||
const TString& mappedName,
|
||||
TVariableInfoList& infoList);
|
||||
|
||||
// Returns info for an attribute or uniform.
|
||||
static void getVariableInfo(const TType& type,
|
||||
const TString& name,
|
||||
const TString& mappedName,
|
||||
TVariableInfoList& infoList)
|
||||
{
|
||||
if (type.getBasicType() == EbtStruct) {
|
||||
if (type.isArray()) {
|
||||
for (int i = 0; i < type.getArraySize(); ++i) {
|
||||
TString lname = name + arrayBrackets(i);
|
||||
TString lmappedName = mappedName + arrayBrackets(i);
|
||||
getUserDefinedVariableInfo(type, lname, lmappedName, infoList);
|
||||
}
|
||||
} else {
|
||||
getUserDefinedVariableInfo(type, name, mappedName, infoList);
|
||||
}
|
||||
} else {
|
||||
getBuiltInVariableInfo(type, name, mappedName, infoList);
|
||||
}
|
||||
}
|
||||
|
||||
void getBuiltInVariableInfo(const TType& type,
|
||||
const TString& name,
|
||||
const TString& mappedName,
|
||||
TVariableInfoList& infoList)
|
||||
{
|
||||
ASSERT(type.getBasicType() != EbtStruct);
|
||||
|
||||
TVariableInfo varInfo;
|
||||
if (type.isArray()) {
|
||||
varInfo.name = (name + "[0]").c_str();
|
||||
varInfo.mappedName = (mappedName + "[0]").c_str();
|
||||
varInfo.size = type.getArraySize();
|
||||
} else {
|
||||
varInfo.name = name.c_str();
|
||||
varInfo.mappedName = mappedName.c_str();
|
||||
varInfo.size = 1;
|
||||
}
|
||||
varInfo.type = getVariableDataType(type);
|
||||
infoList.push_back(varInfo);
|
||||
}
|
||||
|
||||
void getUserDefinedVariableInfo(const TType& type,
|
||||
const TString& name,
|
||||
const TString& mappedName,
|
||||
TVariableInfoList& infoList)
|
||||
{
|
||||
ASSERT(type.getBasicType() == EbtStruct);
|
||||
|
||||
const TTypeList* structure = type.getStruct();
|
||||
for (size_t i = 0; i < structure->size(); ++i) {
|
||||
const TType* fieldType = (*structure)[i].type;
|
||||
getVariableInfo(*fieldType,
|
||||
name + "." + fieldType->getFieldName(),
|
||||
mappedName + "." + fieldType->getFieldName(),
|
||||
infoList);
|
||||
}
|
||||
}
|
||||
|
||||
TVariableInfo::TVariableInfo()
|
||||
{
|
||||
}
|
||||
|
||||
TVariableInfo::TVariableInfo(ShDataType type, int size)
|
||||
: type(type),
|
||||
size(size)
|
||||
{
|
||||
}
|
||||
|
||||
CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
|
||||
TVariableInfoList& uniforms)
|
||||
: mAttribs(attribs),
|
||||
mUniforms(uniforms)
|
||||
{
|
||||
}
|
||||
|
||||
// We are only interested in attribute and uniform variable declaration.
|
||||
void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
|
||||
{
|
||||
}
|
||||
|
||||
void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
|
||||
{
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
|
||||
{
|
||||
bool visitChildren = false;
|
||||
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpSequence:
|
||||
// We need to visit sequence children to get to variable declarations.
|
||||
visitChildren = true;
|
||||
break;
|
||||
case EOpDeclaration: {
|
||||
const TIntermSequence& sequence = node->getSequence();
|
||||
TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
|
||||
if (qualifier == EvqAttribute || qualifier == EvqUniform)
|
||||
{
|
||||
TVariableInfoList& infoList = qualifier == EvqAttribute ?
|
||||
mAttribs : mUniforms;
|
||||
for (TIntermSequence::const_iterator i = sequence.begin();
|
||||
i != sequence.end(); ++i)
|
||||
{
|
||||
const TIntermSymbol* variable = (*i)->getAsSymbolNode();
|
||||
// The only case in which the sequence will not contain a
|
||||
// TIntermSymbol node is initialization. It will contain a
|
||||
// TInterBinary node in that case. Since attributes and unifroms
|
||||
// cannot be initialized in a shader, we must have only
|
||||
// TIntermSymbol nodes in the sequence.
|
||||
ASSERT(variable != NULL);
|
||||
getVariableInfo(variable->getType(),
|
||||
variable->getOriginalSymbol(),
|
||||
variable->getSymbol(),
|
||||
infoList);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
return visitChildren;
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
46
src/3rdparty/angle/src/compiler/VariableInfo.h
vendored
Normal file
46
src/3rdparty/angle/src/compiler/VariableInfo.h
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_VARIABLE_INFO_H_
|
||||
#define COMPILER_VARIABLE_INFO_H_
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
// Provides information about a variable.
|
||||
// It is currently being used to store info about active attribs and uniforms.
|
||||
struct TVariableInfo {
|
||||
TVariableInfo(ShDataType type, int size);
|
||||
TVariableInfo();
|
||||
|
||||
TPersistString name;
|
||||
TPersistString mappedName;
|
||||
ShDataType type;
|
||||
int size;
|
||||
};
|
||||
typedef std::vector<TVariableInfo> TVariableInfoList;
|
||||
|
||||
// Traverses intermediate tree to collect all attributes and uniforms.
|
||||
class CollectAttribsUniforms : public TIntermTraverser {
|
||||
public:
|
||||
CollectAttribsUniforms(TVariableInfoList& attribs,
|
||||
TVariableInfoList& uniforms);
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol*);
|
||||
virtual void visitConstantUnion(TIntermConstantUnion*);
|
||||
virtual bool visitBinary(Visit, TIntermBinary*);
|
||||
virtual bool visitUnary(Visit, TIntermUnary*);
|
||||
virtual bool visitSelection(Visit, TIntermSelection*);
|
||||
virtual bool visitAggregate(Visit, TIntermAggregate*);
|
||||
virtual bool visitLoop(Visit, TIntermLoop*);
|
||||
virtual bool visitBranch(Visit, TIntermBranch*);
|
||||
|
||||
private:
|
||||
TVariableInfoList& mAttribs;
|
||||
TVariableInfoList& mUniforms;
|
||||
};
|
||||
|
||||
#endif // COMPILER_VARIABLE_INFO_H_
|
297
src/3rdparty/angle/src/compiler/VariablePacker.cpp
vendored
Normal file
297
src/3rdparty/angle/src/compiler/VariablePacker.cpp
vendored
Normal file
@ -0,0 +1,297 @@
|
||||
//
|
||||
// Copyright (c) 2002-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 "compiler/VariablePacker.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "compiler/ShHandle.h"
|
||||
|
||||
namespace {
|
||||
int GetSortOrder(ShDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SH_FLOAT_MAT4:
|
||||
return 0;
|
||||
case SH_FLOAT_MAT2:
|
||||
return 1;
|
||||
case SH_FLOAT_VEC4:
|
||||
case SH_INT_VEC4:
|
||||
case SH_BOOL_VEC4:
|
||||
return 2;
|
||||
case SH_FLOAT_MAT3:
|
||||
return 3;
|
||||
case SH_FLOAT_VEC3:
|
||||
case SH_INT_VEC3:
|
||||
case SH_BOOL_VEC3:
|
||||
return 4;
|
||||
case SH_FLOAT_VEC2:
|
||||
case SH_INT_VEC2:
|
||||
case SH_BOOL_VEC2:
|
||||
return 5;
|
||||
case SH_FLOAT:
|
||||
case SH_INT:
|
||||
case SH_BOOL:
|
||||
case SH_SAMPLER_2D:
|
||||
case SH_SAMPLER_CUBE:
|
||||
case SH_SAMPLER_EXTERNAL_OES:
|
||||
case SH_SAMPLER_2D_RECT_ARB:
|
||||
return 6;
|
||||
default:
|
||||
ASSERT(false);
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int VariablePacker::GetNumComponentsPerRow(ShDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SH_FLOAT_MAT4:
|
||||
case SH_FLOAT_MAT2:
|
||||
case SH_FLOAT_VEC4:
|
||||
case SH_INT_VEC4:
|
||||
case SH_BOOL_VEC4:
|
||||
return 4;
|
||||
case SH_FLOAT_MAT3:
|
||||
case SH_FLOAT_VEC3:
|
||||
case SH_INT_VEC3:
|
||||
case SH_BOOL_VEC3:
|
||||
return 3;
|
||||
case SH_FLOAT_VEC2:
|
||||
case SH_INT_VEC2:
|
||||
case SH_BOOL_VEC2:
|
||||
return 2;
|
||||
case SH_FLOAT:
|
||||
case SH_INT:
|
||||
case SH_BOOL:
|
||||
case SH_SAMPLER_2D:
|
||||
case SH_SAMPLER_CUBE:
|
||||
case SH_SAMPLER_EXTERNAL_OES:
|
||||
case SH_SAMPLER_2D_RECT_ARB:
|
||||
return 1;
|
||||
default:
|
||||
ASSERT(false);
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
int VariablePacker::GetNumRows(ShDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SH_FLOAT_MAT4:
|
||||
return 4;
|
||||
case SH_FLOAT_MAT3:
|
||||
return 3;
|
||||
case SH_FLOAT_MAT2:
|
||||
return 1;
|
||||
case SH_FLOAT_VEC4:
|
||||
case SH_INT_VEC4:
|
||||
case SH_BOOL_VEC4:
|
||||
case SH_FLOAT_VEC3:
|
||||
case SH_INT_VEC3:
|
||||
case SH_BOOL_VEC3:
|
||||
case SH_FLOAT_VEC2:
|
||||
case SH_INT_VEC2:
|
||||
case SH_BOOL_VEC2:
|
||||
case SH_FLOAT:
|
||||
case SH_INT:
|
||||
case SH_BOOL:
|
||||
case SH_SAMPLER_2D:
|
||||
case SH_SAMPLER_CUBE:
|
||||
case SH_SAMPLER_EXTERNAL_OES:
|
||||
case SH_SAMPLER_2D_RECT_ARB:
|
||||
return 1;
|
||||
default:
|
||||
ASSERT(false);
|
||||
return 100000;
|
||||
}
|
||||
}
|
||||
|
||||
struct TVariableInfoComparer {
|
||||
bool operator()(const TVariableInfo& lhs, const TVariableInfo& rhs) const
|
||||
{
|
||||
int lhsSortOrder = GetSortOrder(lhs.type);
|
||||
int rhsSortOrder = GetSortOrder(rhs.type);
|
||||
if (lhsSortOrder != rhsSortOrder) {
|
||||
return lhsSortOrder < rhsSortOrder;
|
||||
}
|
||||
// Sort by largest first.
|
||||
return lhs.size > rhs.size;
|
||||
}
|
||||
};
|
||||
|
||||
unsigned VariablePacker::makeColumnFlags(int column, int numComponentsPerRow)
|
||||
{
|
||||
return ((kColumnMask << (kNumColumns - numComponentsPerRow)) &
|
||||
kColumnMask) >> column;
|
||||
}
|
||||
|
||||
void VariablePacker::fillColumns(int topRow, int numRows, int column, int numComponentsPerRow)
|
||||
{
|
||||
unsigned columnFlags = makeColumnFlags(column, numComponentsPerRow);
|
||||
for (int r = 0; r < numRows; ++r) {
|
||||
int row = topRow + r;
|
||||
ASSERT((rows_[row] & columnFlags) == 0);
|
||||
rows_[row] |= columnFlags;
|
||||
}
|
||||
}
|
||||
|
||||
bool VariablePacker::searchColumn(int column, int numRows, int* destRow, int* destSize)
|
||||
{
|
||||
ASSERT(destRow);
|
||||
|
||||
for (; topNonFullRow_ < maxRows_ && rows_[topNonFullRow_] == kColumnMask;
|
||||
++topNonFullRow_) {
|
||||
}
|
||||
|
||||
for (; bottomNonFullRow_ >= 0 && rows_[bottomNonFullRow_] == kColumnMask;
|
||||
--bottomNonFullRow_) {
|
||||
}
|
||||
|
||||
if (bottomNonFullRow_ - topNonFullRow_ + 1 < numRows) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned columnFlags = makeColumnFlags(column, 1);
|
||||
int topGoodRow = 0;
|
||||
int smallestGoodTop = -1;
|
||||
int smallestGoodSize = maxRows_ + 1;
|
||||
int bottomRow = bottomNonFullRow_ + 1;
|
||||
bool found = false;
|
||||
for (int row = topNonFullRow_; row <= bottomRow; ++row) {
|
||||
bool rowEmpty = row < bottomRow ? ((rows_[row] & columnFlags) == 0) : false;
|
||||
if (rowEmpty) {
|
||||
if (!found) {
|
||||
topGoodRow = row;
|
||||
found = true;
|
||||
}
|
||||
} else {
|
||||
if (found) {
|
||||
int size = row - topGoodRow;
|
||||
if (size >= numRows && size < smallestGoodSize) {
|
||||
smallestGoodSize = size;
|
||||
smallestGoodTop = topGoodRow;
|
||||
}
|
||||
}
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
if (smallestGoodTop < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*destRow = smallestGoodTop;
|
||||
if (destSize) {
|
||||
*destSize = smallestGoodSize;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VariablePacker::CheckVariablesWithinPackingLimits(int maxVectors, const TVariableInfoList& in_variables)
|
||||
{
|
||||
ASSERT(maxVectors > 0);
|
||||
maxRows_ = maxVectors;
|
||||
topNonFullRow_ = 0;
|
||||
bottomNonFullRow_ = maxRows_ - 1;
|
||||
TVariableInfoList variables(in_variables);
|
||||
|
||||
// As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific
|
||||
// order by type, then by size of array, largest first.
|
||||
std::sort(variables.begin(), variables.end(), TVariableInfoComparer());
|
||||
rows_.clear();
|
||||
rows_.resize(maxVectors, 0);
|
||||
|
||||
// Packs the 4 column variables.
|
||||
size_t ii = 0;
|
||||
for (; ii < variables.size(); ++ii) {
|
||||
const TVariableInfo& variable = variables[ii];
|
||||
if (GetNumComponentsPerRow(variable.type) != 4) {
|
||||
break;
|
||||
}
|
||||
topNonFullRow_ += GetNumRows(variable.type) * variable.size;
|
||||
}
|
||||
|
||||
if (topNonFullRow_ > maxRows_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Packs the 3 column variables.
|
||||
int num3ColumnRows = 0;
|
||||
for (; ii < variables.size(); ++ii) {
|
||||
const TVariableInfo& variable = variables[ii];
|
||||
if (GetNumComponentsPerRow(variable.type) != 3) {
|
||||
break;
|
||||
}
|
||||
num3ColumnRows += GetNumRows(variable.type) * variable.size;
|
||||
}
|
||||
|
||||
if (topNonFullRow_ + num3ColumnRows > maxRows_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fillColumns(topNonFullRow_, num3ColumnRows, 0, 3);
|
||||
|
||||
// Packs the 2 column variables.
|
||||
int top2ColumnRow = topNonFullRow_ + num3ColumnRows;
|
||||
int twoColumnRowsAvailable = maxRows_ - top2ColumnRow;
|
||||
int rowsAvailableInColumns01 = twoColumnRowsAvailable;
|
||||
int rowsAvailableInColumns23 = twoColumnRowsAvailable;
|
||||
for (; ii < variables.size(); ++ii) {
|
||||
const TVariableInfo& variable = variables[ii];
|
||||
if (GetNumComponentsPerRow(variable.type) != 2) {
|
||||
break;
|
||||
}
|
||||
int numRows = GetNumRows(variable.type) * variable.size;
|
||||
if (numRows <= rowsAvailableInColumns01) {
|
||||
rowsAvailableInColumns01 -= numRows;
|
||||
} else if (numRows <= rowsAvailableInColumns23) {
|
||||
rowsAvailableInColumns23 -= numRows;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int numRowsUsedInColumns01 =
|
||||
twoColumnRowsAvailable - rowsAvailableInColumns01;
|
||||
int numRowsUsedInColumns23 =
|
||||
twoColumnRowsAvailable - rowsAvailableInColumns23;
|
||||
fillColumns(top2ColumnRow, numRowsUsedInColumns01, 0, 2);
|
||||
fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23,
|
||||
2, 2);
|
||||
|
||||
// Packs the 1 column variables.
|
||||
for (; ii < variables.size(); ++ii) {
|
||||
const TVariableInfo& variable = variables[ii];
|
||||
ASSERT(1 == GetNumComponentsPerRow(variable.type));
|
||||
int numRows = GetNumRows(variable.type) * variable.size;
|
||||
int smallestColumn = -1;
|
||||
int smallestSize = maxRows_ + 1;
|
||||
int topRow = -1;
|
||||
for (int column = 0; column < kNumColumns; ++column) {
|
||||
int row = 0;
|
||||
int size = 0;
|
||||
if (searchColumn(column, numRows, &row, &size)) {
|
||||
if (size < smallestSize) {
|
||||
smallestSize = size;
|
||||
smallestColumn = column;
|
||||
topRow = row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (smallestColumn < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fillColumns(topRow, numRows, smallestColumn, 1);
|
||||
}
|
||||
|
||||
ASSERT(variables.size() == ii);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
41
src/3rdparty/angle/src/compiler/VariablePacker.h
vendored
Normal file
41
src/3rdparty/angle/src/compiler/VariablePacker.h
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright (c) 2002-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 _VARIABLEPACKER_INCLUDED_
|
||||
#define _VARIABLEPACKER_INCLUDED_
|
||||
|
||||
#include <vector>
|
||||
#include "compiler/ShHandle.h"
|
||||
|
||||
class VariablePacker {
|
||||
public:
|
||||
// Returns true if the passed in variables pack in maxVectors following
|
||||
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
|
||||
bool CheckVariablesWithinPackingLimits(
|
||||
int maxVectors,
|
||||
const TVariableInfoList& in_variables);
|
||||
|
||||
// Gets how many components in a row a data type takes.
|
||||
static int GetNumComponentsPerRow(ShDataType type);
|
||||
|
||||
// Gets how many rows a data type takes.
|
||||
static int GetNumRows(ShDataType type);
|
||||
|
||||
private:
|
||||
static const int kNumColumns = 4;
|
||||
static const unsigned kColumnMask = (1 << kNumColumns) - 1;
|
||||
|
||||
unsigned makeColumnFlags(int column, int numComponentsPerRow);
|
||||
void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow);
|
||||
bool searchColumn(int column, int numRows, int* destRow, int* destSize);
|
||||
|
||||
int topNonFullRow_;
|
||||
int bottomNonFullRow_;
|
||||
int maxRows_;
|
||||
std::vector<unsigned> rows_;
|
||||
};
|
||||
|
||||
#endif // _VARIABLEPACKER_INCLUDED_
|
140
src/3rdparty/angle/src/compiler/VersionGLSL.cpp
vendored
Normal file
140
src/3rdparty/angle/src/compiler/VersionGLSL.cpp
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
//
|
||||
// Copyright (c) 2002-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 "compiler/VersionGLSL.h"
|
||||
|
||||
static const int GLSL_VERSION_110 = 110;
|
||||
static const int GLSL_VERSION_120 = 120;
|
||||
|
||||
// We need to scan for the following:
|
||||
// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
|
||||
// but only at the global scope.
|
||||
// 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
|
||||
// but inside any scope.
|
||||
// 3. Call to a matrix constructor with another matrix as argument.
|
||||
// (These constructors were reserved in GLSL version 1.10.)
|
||||
// 4. Arrays as "out" function parameters.
|
||||
// GLSL spec section 6.1.1: "When calling a function, expressions that do
|
||||
// not evaluate to l-values cannot be passed to parameters declared as
|
||||
// out or inout."
|
||||
// GLSL 1.1 section 5.8: "Other binary or unary expressions,
|
||||
// non-dereferenced arrays, function names, swizzles with repeated fields,
|
||||
// and constants cannot be l-values."
|
||||
// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
|
||||
// are built-in types, entire structures or arrays... are all l-values."
|
||||
//
|
||||
// TODO(alokp): The following two cases of invariant decalaration get lost
|
||||
// during parsing - they do not get carried over to the intermediate tree.
|
||||
// Handle these cases:
|
||||
// 1. When a pragma is used to force all output variables to be invariant:
|
||||
// - #pragma STDGL invariant(all)
|
||||
// 2. When a previously decalared or built-in variable is marked invariant:
|
||||
// - invariant gl_Position;
|
||||
// - varying vec3 color; invariant color;
|
||||
//
|
||||
TVersionGLSL::TVersionGLSL(ShShaderType type)
|
||||
: mShaderType(type),
|
||||
mVersion(GLSL_VERSION_110)
|
||||
{
|
||||
}
|
||||
|
||||
void TVersionGLSL::visitSymbol(TIntermSymbol* node)
|
||||
{
|
||||
if (node->getSymbol() == "gl_PointCoord")
|
||||
updateVersion(GLSL_VERSION_120);
|
||||
}
|
||||
|
||||
void TVersionGLSL::visitConstantUnion(TIntermConstantUnion*)
|
||||
{
|
||||
}
|
||||
|
||||
bool TVersionGLSL::visitBinary(Visit, TIntermBinary*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TVersionGLSL::visitUnary(Visit, TIntermUnary*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TVersionGLSL::visitSelection(Visit, TIntermSelection*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate* node)
|
||||
{
|
||||
bool visitChildren = true;
|
||||
|
||||
switch (node->getOp()) {
|
||||
case EOpSequence:
|
||||
// We need to visit sequence children to get to global or inner scope.
|
||||
visitChildren = true;
|
||||
break;
|
||||
case EOpDeclaration: {
|
||||
const TIntermSequence& sequence = node->getSequence();
|
||||
TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
|
||||
if ((qualifier == EvqInvariantVaryingIn) ||
|
||||
(qualifier == EvqInvariantVaryingOut)) {
|
||||
updateVersion(GLSL_VERSION_120);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EOpParameters: {
|
||||
const TIntermSequence& params = node->getSequence();
|
||||
for (TIntermSequence::const_iterator iter = params.begin();
|
||||
iter != params.end(); ++iter)
|
||||
{
|
||||
const TIntermTyped* param = (*iter)->getAsTyped();
|
||||
if (param->isArray())
|
||||
{
|
||||
TQualifier qualifier = param->getQualifier();
|
||||
if ((qualifier == EvqOut) || (qualifier == EvqInOut))
|
||||
{
|
||||
updateVersion(GLSL_VERSION_120);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fully processed. No need to visit children.
|
||||
visitChildren = false;
|
||||
break;
|
||||
}
|
||||
case EOpConstructMat2:
|
||||
case EOpConstructMat3:
|
||||
case EOpConstructMat4: {
|
||||
const TIntermSequence& sequence = node->getSequence();
|
||||
if (sequence.size() == 1) {
|
||||
TIntermTyped* typed = sequence.front()->getAsTyped();
|
||||
if (typed && typed->isMatrix()) {
|
||||
updateVersion(GLSL_VERSION_120);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return visitChildren;
|
||||
}
|
||||
|
||||
bool TVersionGLSL::visitLoop(Visit, TIntermLoop*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TVersionGLSL::visitBranch(Visit, TIntermBranch*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void TVersionGLSL::updateVersion(int version)
|
||||
{
|
||||
mVersion = std::max(version, mVersion);
|
||||
}
|
||||
|
56
src/3rdparty/angle/src/compiler/VersionGLSL.h
vendored
Normal file
56
src/3rdparty/angle/src/compiler/VersionGLSL.h
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef COMPILER_VERSIONGLSL_H_
|
||||
#define COMPILER_VERSIONGLSL_H_
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
// Traverses the intermediate tree to return the minimum GLSL version
|
||||
// required to legally access all built-in features used in the shader.
|
||||
// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
|
||||
// - #version and #extension to declare version and extensions.
|
||||
// - built-in functions refract, exp, and log.
|
||||
// - updated step() to compare x < edge instead of x <= edge.
|
||||
// GLSL 1.2 which is mandated by OpenGL 2.1 provides:
|
||||
// - many changes to reduce differences when compared to the ES specification.
|
||||
// - invariant keyword and its support.
|
||||
// - c++ style name hiding rules.
|
||||
// - built-in variable gl_PointCoord for fragment shaders.
|
||||
// - matrix constructors taking matrix as argument.
|
||||
// - array as "out" function parameters
|
||||
//
|
||||
class TVersionGLSL : public TIntermTraverser {
|
||||
public:
|
||||
TVersionGLSL(ShShaderType type);
|
||||
|
||||
// Returns 120 if the following is used the shader:
|
||||
// - "invariant",
|
||||
// - "gl_PointCoord",
|
||||
// - matrix/matrix constructors
|
||||
// - array "out" parameters
|
||||
// Else 110 is returned.
|
||||
int getVersion() { return mVersion; }
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol*);
|
||||
virtual void visitConstantUnion(TIntermConstantUnion*);
|
||||
virtual bool visitBinary(Visit, TIntermBinary*);
|
||||
virtual bool visitUnary(Visit, TIntermUnary*);
|
||||
virtual bool visitSelection(Visit, TIntermSelection*);
|
||||
virtual bool visitAggregate(Visit, TIntermAggregate*);
|
||||
virtual bool visitLoop(Visit, TIntermLoop*);
|
||||
virtual bool visitBranch(Visit, TIntermBranch*);
|
||||
|
||||
protected:
|
||||
void updateVersion(int version);
|
||||
|
||||
private:
|
||||
ShShaderType mShaderType;
|
||||
int mVersion;
|
||||
};
|
||||
|
||||
#endif // COMPILER_VERSIONGLSL_H_
|
37
src/3rdparty/angle/src/compiler/debug.cpp
vendored
Normal file
37
src/3rdparty/angle/src/compiler/debug.cpp
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// debug.cpp: Debugging utilities.
|
||||
|
||||
#include "compiler/debug.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "compiler/InitializeParseContext.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
|
||||
static const int kTraceBufferLen = 1024;
|
||||
|
||||
#ifdef TRACE_ENABLED
|
||||
extern "C" {
|
||||
void Trace(const char *format, ...) {
|
||||
if (!format) return;
|
||||
|
||||
TParseContext* parseContext = GetGlobalParseContext();
|
||||
if (parseContext) {
|
||||
char buf[kTraceBufferLen];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(buf, kTraceBufferLen, format, args);
|
||||
va_end(args);
|
||||
|
||||
parseContext->trace(buf);
|
||||
}
|
||||
}
|
||||
} // extern "C"
|
||||
#endif // TRACE_ENABLED
|
||||
|
53
src/3rdparty/angle/src/compiler/debug.h
vendored
Normal file
53
src/3rdparty/angle/src/compiler/debug.h
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// debug.h: Debugging utilities.
|
||||
|
||||
#ifndef COMPILER_DEBUG_H_
|
||||
#define COMPILER_DEBUG_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define TRACE_ENABLED // define to enable debug message tracing
|
||||
#endif // _DEBUG
|
||||
|
||||
// Outputs text to the debug log
|
||||
#ifdef TRACE_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
void Trace(const char* format, ...);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#else // TRACE_ENABLED
|
||||
|
||||
#define Trace(...) ((void)0)
|
||||
|
||||
#endif // TRACE_ENABLED
|
||||
|
||||
// A macro asserting a condition and outputting failures to the debug log
|
||||
#define ASSERT(expression) do { \
|
||||
if(!(expression)) \
|
||||
Trace("Assert failed: %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \
|
||||
assert(expression); \
|
||||
} while(0)
|
||||
|
||||
#define UNIMPLEMENTED() do { \
|
||||
Trace("Unimplemented invoked: %s(%d)\n", __FUNCTION__, __LINE__); \
|
||||
assert(false); \
|
||||
} while(0)
|
||||
|
||||
#define UNREACHABLE() do { \
|
||||
Trace("Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \
|
||||
assert(false); \
|
||||
} while(0)
|
||||
|
||||
#endif // COMPILER_DEBUG_H_
|
||||
|
97
src/3rdparty/angle/src/compiler/depgraph/DependencyGraph.cpp
vendored
Normal file
97
src/3rdparty/angle/src/compiler/depgraph/DependencyGraph.cpp
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#pragma warning(disable: 4718)
|
||||
|
||||
#include "compiler/depgraph/DependencyGraph.h"
|
||||
#include "compiler/depgraph/DependencyGraphBuilder.h"
|
||||
|
||||
TDependencyGraph::TDependencyGraph(TIntermNode* intermNode)
|
||||
{
|
||||
TDependencyGraphBuilder::build(intermNode, this);
|
||||
}
|
||||
|
||||
TDependencyGraph::~TDependencyGraph()
|
||||
{
|
||||
for (TGraphNodeVector::const_iterator iter = mAllNodes.begin(); iter != mAllNodes.end(); ++iter)
|
||||
{
|
||||
TGraphNode* node = *iter;
|
||||
delete node;
|
||||
}
|
||||
}
|
||||
|
||||
TGraphArgument* TDependencyGraph::createArgument(TIntermAggregate* intermFunctionCall,
|
||||
int argumentNumber)
|
||||
{
|
||||
TGraphArgument* argument = new TGraphArgument(intermFunctionCall, argumentNumber);
|
||||
mAllNodes.push_back(argument);
|
||||
return argument;
|
||||
}
|
||||
|
||||
TGraphFunctionCall* TDependencyGraph::createFunctionCall(TIntermAggregate* intermFunctionCall)
|
||||
{
|
||||
TGraphFunctionCall* functionCall = new TGraphFunctionCall(intermFunctionCall);
|
||||
mAllNodes.push_back(functionCall);
|
||||
if (functionCall->getIntermFunctionCall()->isUserDefined())
|
||||
mUserDefinedFunctionCalls.push_back(functionCall);
|
||||
return functionCall;
|
||||
}
|
||||
|
||||
TGraphSymbol* TDependencyGraph::getOrCreateSymbol(TIntermSymbol* intermSymbol)
|
||||
{
|
||||
TSymbolIdMap::const_iterator iter = mSymbolIdMap.find(intermSymbol->getId());
|
||||
|
||||
TGraphSymbol* symbol = NULL;
|
||||
|
||||
if (iter != mSymbolIdMap.end()) {
|
||||
TSymbolIdPair pair = *iter;
|
||||
symbol = pair.second;
|
||||
} else {
|
||||
symbol = new TGraphSymbol(intermSymbol);
|
||||
mAllNodes.push_back(symbol);
|
||||
|
||||
TSymbolIdPair pair(intermSymbol->getId(), symbol);
|
||||
mSymbolIdMap.insert(pair);
|
||||
|
||||
// We save all sampler symbols in a collection, so we can start graph traversals from them quickly.
|
||||
if (IsSampler(intermSymbol->getBasicType()))
|
||||
mSamplerSymbols.push_back(symbol);
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
TGraphSelection* TDependencyGraph::createSelection(TIntermSelection* intermSelection)
|
||||
{
|
||||
TGraphSelection* selection = new TGraphSelection(intermSelection);
|
||||
mAllNodes.push_back(selection);
|
||||
return selection;
|
||||
}
|
||||
|
||||
TGraphLoop* TDependencyGraph::createLoop(TIntermLoop* intermLoop)
|
||||
{
|
||||
TGraphLoop* loop = new TGraphLoop(intermLoop);
|
||||
mAllNodes.push_back(loop);
|
||||
return loop;
|
||||
}
|
||||
|
||||
TGraphLogicalOp* TDependencyGraph::createLogicalOp(TIntermBinary* intermLogicalOp)
|
||||
{
|
||||
TGraphLogicalOp* logicalOp = new TGraphLogicalOp(intermLogicalOp);
|
||||
mAllNodes.push_back(logicalOp);
|
||||
return logicalOp;
|
||||
}
|
||||
|
||||
const char* TGraphLogicalOp::getOpString() const
|
||||
{
|
||||
const char* opString = NULL;
|
||||
switch (getIntermLogicalOp()->getOp()) {
|
||||
case EOpLogicalAnd: opString = "and"; break;
|
||||
case EOpLogicalOr: opString = "or"; break;
|
||||
default: opString = "unknown"; break;
|
||||
}
|
||||
return opString;
|
||||
}
|
212
src/3rdparty/angle/src/compiler/depgraph/DependencyGraph.h
vendored
Normal file
212
src/3rdparty/angle/src/compiler/depgraph/DependencyGraph.h
vendored
Normal file
@ -0,0 +1,212 @@
|
||||
//
|
||||
// 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 COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H
|
||||
#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H
|
||||
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
#include <set>
|
||||
#include <stack>
|
||||
|
||||
class TGraphNode;
|
||||
class TGraphParentNode;
|
||||
class TGraphArgument;
|
||||
class TGraphFunctionCall;
|
||||
class TGraphSymbol;
|
||||
class TGraphSelection;
|
||||
class TGraphLoop;
|
||||
class TGraphLogicalOp;
|
||||
class TDependencyGraphTraverser;
|
||||
class TDependencyGraphOutput;
|
||||
|
||||
typedef std::set<TGraphNode*> TGraphNodeSet;
|
||||
typedef std::vector<TGraphNode*> TGraphNodeVector;
|
||||
typedef std::vector<TGraphSymbol*> TGraphSymbolVector;
|
||||
typedef std::vector<TGraphFunctionCall*> TFunctionCallVector;
|
||||
|
||||
//
|
||||
// Base class for all dependency graph nodes.
|
||||
//
|
||||
class TGraphNode {
|
||||
public:
|
||||
TGraphNode(TIntermNode* node) : intermNode(node) {}
|
||||
virtual ~TGraphNode() {}
|
||||
virtual void traverse(TDependencyGraphTraverser* graphTraverser);
|
||||
protected:
|
||||
TIntermNode* intermNode;
|
||||
};
|
||||
|
||||
//
|
||||
// Base class for dependency graph nodes that may have children.
|
||||
//
|
||||
class TGraphParentNode : public TGraphNode {
|
||||
public:
|
||||
TGraphParentNode(TIntermNode* node) : TGraphNode(node) {}
|
||||
virtual ~TGraphParentNode() {}
|
||||
void addDependentNode(TGraphNode* node) { if (node != this) mDependentNodes.insert(node); }
|
||||
virtual void traverse(TDependencyGraphTraverser* graphTraverser);
|
||||
private:
|
||||
TGraphNodeSet mDependentNodes;
|
||||
};
|
||||
|
||||
//
|
||||
// Handle function call arguments.
|
||||
//
|
||||
class TGraphArgument : public TGraphParentNode {
|
||||
public:
|
||||
TGraphArgument(TIntermAggregate* intermFunctionCall, int argumentNumber)
|
||||
: TGraphParentNode(intermFunctionCall)
|
||||
, mArgumentNumber(argumentNumber) {}
|
||||
virtual ~TGraphArgument() {}
|
||||
const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); }
|
||||
int getArgumentNumber() const { return mArgumentNumber; }
|
||||
virtual void traverse(TDependencyGraphTraverser* graphTraverser);
|
||||
private:
|
||||
int mArgumentNumber;
|
||||
};
|
||||
|
||||
//
|
||||
// Handle function calls.
|
||||
//
|
||||
class TGraphFunctionCall : public TGraphParentNode {
|
||||
public:
|
||||
TGraphFunctionCall(TIntermAggregate* intermFunctionCall)
|
||||
: TGraphParentNode(intermFunctionCall) {}
|
||||
virtual ~TGraphFunctionCall() {}
|
||||
const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); }
|
||||
virtual void traverse(TDependencyGraphTraverser* graphTraverser);
|
||||
};
|
||||
|
||||
//
|
||||
// Handle symbols.
|
||||
//
|
||||
class TGraphSymbol : public TGraphParentNode {
|
||||
public:
|
||||
TGraphSymbol(TIntermSymbol* intermSymbol) : TGraphParentNode(intermSymbol) {}
|
||||
virtual ~TGraphSymbol() {}
|
||||
const TIntermSymbol* getIntermSymbol() const { return intermNode->getAsSymbolNode(); }
|
||||
virtual void traverse(TDependencyGraphTraverser* graphTraverser);
|
||||
};
|
||||
|
||||
//
|
||||
// Handle if statements and ternary operators.
|
||||
//
|
||||
class TGraphSelection : public TGraphNode {
|
||||
public:
|
||||
TGraphSelection(TIntermSelection* intermSelection) : TGraphNode(intermSelection) {}
|
||||
virtual ~TGraphSelection() {}
|
||||
const TIntermSelection* getIntermSelection() const { return intermNode->getAsSelectionNode(); }
|
||||
virtual void traverse(TDependencyGraphTraverser* graphTraverser);
|
||||
};
|
||||
|
||||
//
|
||||
// Handle for, do-while, and while loops.
|
||||
//
|
||||
class TGraphLoop : public TGraphNode {
|
||||
public:
|
||||
TGraphLoop(TIntermLoop* intermLoop) : TGraphNode(intermLoop) {}
|
||||
virtual ~TGraphLoop() {}
|
||||
const TIntermLoop* getIntermLoop() const { return intermNode->getAsLoopNode(); }
|
||||
virtual void traverse(TDependencyGraphTraverser* graphTraverser);
|
||||
};
|
||||
|
||||
//
|
||||
// Handle logical and, or.
|
||||
//
|
||||
class TGraphLogicalOp : public TGraphNode {
|
||||
public:
|
||||
TGraphLogicalOp(TIntermBinary* intermLogicalOp) : TGraphNode(intermLogicalOp) {}
|
||||
virtual ~TGraphLogicalOp() {}
|
||||
const TIntermBinary* getIntermLogicalOp() const { return intermNode->getAsBinaryNode(); }
|
||||
const char* getOpString() const;
|
||||
virtual void traverse(TDependencyGraphTraverser* graphTraverser);
|
||||
};
|
||||
|
||||
//
|
||||
// A dependency graph of symbols, function calls, conditions etc.
|
||||
//
|
||||
// This class provides an interface to the entry points of the dependency graph.
|
||||
//
|
||||
// Dependency graph nodes should be created by using one of the provided "create..." methods.
|
||||
// This class (and nobody else) manages the memory of the created nodes.
|
||||
// Nodes may not be removed after being added, so all created nodes will exist while the
|
||||
// TDependencyGraph instance exists.
|
||||
//
|
||||
class TDependencyGraph {
|
||||
public:
|
||||
TDependencyGraph(TIntermNode* intermNode);
|
||||
~TDependencyGraph();
|
||||
TGraphNodeVector::const_iterator begin() const { return mAllNodes.begin(); }
|
||||
TGraphNodeVector::const_iterator end() const { return mAllNodes.end(); }
|
||||
|
||||
TGraphSymbolVector::const_iterator beginSamplerSymbols() const
|
||||
{
|
||||
return mSamplerSymbols.begin();
|
||||
}
|
||||
|
||||
TGraphSymbolVector::const_iterator endSamplerSymbols() const
|
||||
{
|
||||
return mSamplerSymbols.end();
|
||||
}
|
||||
|
||||
TFunctionCallVector::const_iterator beginUserDefinedFunctionCalls() const
|
||||
{
|
||||
return mUserDefinedFunctionCalls.begin();
|
||||
}
|
||||
|
||||
TFunctionCallVector::const_iterator endUserDefinedFunctionCalls() const
|
||||
{
|
||||
return mUserDefinedFunctionCalls.end();
|
||||
}
|
||||
|
||||
TGraphArgument* createArgument(TIntermAggregate* intermFunctionCall, int argumentNumber);
|
||||
TGraphFunctionCall* createFunctionCall(TIntermAggregate* intermFunctionCall);
|
||||
TGraphSymbol* getOrCreateSymbol(TIntermSymbol* intermSymbol);
|
||||
TGraphSelection* createSelection(TIntermSelection* intermSelection);
|
||||
TGraphLoop* createLoop(TIntermLoop* intermLoop);
|
||||
TGraphLogicalOp* createLogicalOp(TIntermBinary* intermLogicalOp);
|
||||
private:
|
||||
typedef TMap<int, TGraphSymbol*> TSymbolIdMap;
|
||||
typedef std::pair<int, TGraphSymbol*> TSymbolIdPair;
|
||||
|
||||
TGraphNodeVector mAllNodes;
|
||||
TGraphSymbolVector mSamplerSymbols;
|
||||
TFunctionCallVector mUserDefinedFunctionCalls;
|
||||
TSymbolIdMap mSymbolIdMap;
|
||||
};
|
||||
|
||||
//
|
||||
// For traversing the dependency graph. Users should derive from this,
|
||||
// put their traversal specific data in it, and then pass it to a
|
||||
// traverse method.
|
||||
//
|
||||
// When using this, just fill in the methods for nodes you want visited.
|
||||
//
|
||||
class TDependencyGraphTraverser {
|
||||
public:
|
||||
TDependencyGraphTraverser() : mDepth(0) {}
|
||||
|
||||
virtual void visitSymbol(TGraphSymbol* symbol) {};
|
||||
virtual void visitArgument(TGraphArgument* selection) {};
|
||||
virtual void visitFunctionCall(TGraphFunctionCall* functionCall) {};
|
||||
virtual void visitSelection(TGraphSelection* selection) {};
|
||||
virtual void visitLoop(TGraphLoop* loop) {};
|
||||
virtual void visitLogicalOp(TGraphLogicalOp* logicalOp) {};
|
||||
|
||||
int getDepth() const { return mDepth; }
|
||||
void incrementDepth() { ++mDepth; }
|
||||
void decrementDepth() { --mDepth; }
|
||||
|
||||
void clearVisited() { mVisited.clear(); }
|
||||
void markVisited(TGraphNode* node) { mVisited.insert(node); }
|
||||
bool isVisited(TGraphNode* node) const { return mVisited.find(node) != mVisited.end(); }
|
||||
private:
|
||||
int mDepth;
|
||||
TGraphNodeSet mVisited;
|
||||
};
|
||||
|
||||
#endif
|
227
src/3rdparty/angle/src/compiler/depgraph/DependencyGraphBuilder.cpp
vendored
Normal file
227
src/3rdparty/angle/src/compiler/depgraph/DependencyGraphBuilder.cpp
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
//
|
||||
// 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 "compiler/depgraph/DependencyGraphBuilder.h"
|
||||
|
||||
void TDependencyGraphBuilder::build(TIntermNode* node, TDependencyGraph* graph)
|
||||
{
|
||||
TDependencyGraphBuilder builder(graph);
|
||||
builder.build(node);
|
||||
}
|
||||
|
||||
bool TDependencyGraphBuilder::visitAggregate(Visit visit, TIntermAggregate* intermAggregate)
|
||||
{
|
||||
switch (intermAggregate->getOp()) {
|
||||
case EOpFunction: visitFunctionDefinition(intermAggregate); break;
|
||||
case EOpFunctionCall: visitFunctionCall(intermAggregate); break;
|
||||
default: visitAggregateChildren(intermAggregate); break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void TDependencyGraphBuilder::visitFunctionDefinition(TIntermAggregate* intermAggregate)
|
||||
{
|
||||
// Currently, we do not support user defined functions.
|
||||
if (intermAggregate->getName() != "main(")
|
||||
return;
|
||||
|
||||
visitAggregateChildren(intermAggregate);
|
||||
}
|
||||
|
||||
// Takes an expression like "f(x)" and creates a dependency graph like
|
||||
// "x -> argument 0 -> function call".
|
||||
void TDependencyGraphBuilder::visitFunctionCall(TIntermAggregate* intermFunctionCall)
|
||||
{
|
||||
TGraphFunctionCall* functionCall = mGraph->createFunctionCall(intermFunctionCall);
|
||||
|
||||
// Run through the function call arguments.
|
||||
int argumentNumber = 0;
|
||||
TIntermSequence& intermArguments = intermFunctionCall->getSequence();
|
||||
for (TIntermSequence::const_iterator iter = intermArguments.begin();
|
||||
iter != intermArguments.end();
|
||||
++iter, ++argumentNumber)
|
||||
{
|
||||
TNodeSetMaintainer nodeSetMaintainer(this);
|
||||
|
||||
TIntermNode* intermArgument = *iter;
|
||||
intermArgument->traverse(this);
|
||||
|
||||
if (TParentNodeSet* argumentNodes = mNodeSets.getTopSet()) {
|
||||
TGraphArgument* argument = mGraph->createArgument(intermFunctionCall, argumentNumber);
|
||||
connectMultipleNodesToSingleNode(argumentNodes, argument);
|
||||
argument->addDependentNode(functionCall);
|
||||
}
|
||||
}
|
||||
|
||||
// Push the leftmost symbol of this function call into the current set of dependent symbols to
|
||||
// represent the result of this function call.
|
||||
// Thus, an expression like "y = f(x)" will yield a dependency graph like
|
||||
// "x -> argument 0 -> function call -> y".
|
||||
// This line essentially passes the function call node back up to an earlier visitAssignment
|
||||
// call, which will create the connection "function call -> y".
|
||||
mNodeSets.insertIntoTopSet(functionCall);
|
||||
}
|
||||
|
||||
void TDependencyGraphBuilder::visitAggregateChildren(TIntermAggregate* intermAggregate)
|
||||
{
|
||||
TIntermSequence& sequence = intermAggregate->getSequence();
|
||||
for(TIntermSequence::const_iterator iter = sequence.begin(); iter != sequence.end(); ++iter)
|
||||
{
|
||||
TIntermNode* intermChild = *iter;
|
||||
intermChild->traverse(this);
|
||||
}
|
||||
}
|
||||
|
||||
void TDependencyGraphBuilder::visitSymbol(TIntermSymbol* intermSymbol)
|
||||
{
|
||||
// Push this symbol into the set of dependent symbols for the current assignment or condition
|
||||
// that we are traversing.
|
||||
TGraphSymbol* symbol = mGraph->getOrCreateSymbol(intermSymbol);
|
||||
mNodeSets.insertIntoTopSet(symbol);
|
||||
|
||||
// If this symbol is the current leftmost symbol under an assignment, replace the previous
|
||||
// leftmost symbol with this symbol.
|
||||
if (!mLeftmostSymbols.empty() && mLeftmostSymbols.top() != &mRightSubtree) {
|
||||
mLeftmostSymbols.pop();
|
||||
mLeftmostSymbols.push(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
bool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary* intermBinary)
|
||||
{
|
||||
TOperator op = intermBinary->getOp();
|
||||
if (op == EOpInitialize || intermBinary->modifiesState())
|
||||
visitAssignment(intermBinary);
|
||||
else if (op == EOpLogicalAnd || op == EOpLogicalOr)
|
||||
visitLogicalOp(intermBinary);
|
||||
else
|
||||
visitBinaryChildren(intermBinary);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void TDependencyGraphBuilder::visitAssignment(TIntermBinary* intermAssignment)
|
||||
{
|
||||
TIntermTyped* intermLeft = intermAssignment->getLeft();
|
||||
if (!intermLeft)
|
||||
return;
|
||||
|
||||
TGraphSymbol* leftmostSymbol = NULL;
|
||||
|
||||
{
|
||||
TNodeSetMaintainer nodeSetMaintainer(this);
|
||||
|
||||
{
|
||||
TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mLeftSubtree);
|
||||
intermLeft->traverse(this);
|
||||
leftmostSymbol = mLeftmostSymbols.top();
|
||||
|
||||
// After traversing the left subtree of this assignment, we should have found a real
|
||||
// leftmost symbol, and the leftmost symbol should not be a placeholder.
|
||||
ASSERT(leftmostSymbol != &mLeftSubtree);
|
||||
ASSERT(leftmostSymbol != &mRightSubtree);
|
||||
}
|
||||
|
||||
if (TIntermTyped* intermRight = intermAssignment->getRight()) {
|
||||
TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
|
||||
intermRight->traverse(this);
|
||||
}
|
||||
|
||||
if (TParentNodeSet* assignmentNodes = mNodeSets.getTopSet())
|
||||
connectMultipleNodesToSingleNode(assignmentNodes, leftmostSymbol);
|
||||
}
|
||||
|
||||
// Push the leftmost symbol of this assignment into the current set of dependent symbols to
|
||||
// represent the result of this assignment.
|
||||
// An expression like "a = (b = c)" will yield a dependency graph like "c -> b -> a".
|
||||
// This line essentially passes the leftmost symbol of the nested assignment ("b" in this
|
||||
// example) back up to the earlier visitAssignment call for the outer assignment, which will
|
||||
// create the connection "b -> a".
|
||||
mNodeSets.insertIntoTopSet(leftmostSymbol);
|
||||
}
|
||||
|
||||
void TDependencyGraphBuilder::visitLogicalOp(TIntermBinary* intermLogicalOp)
|
||||
{
|
||||
if (TIntermTyped* intermLeft = intermLogicalOp->getLeft()) {
|
||||
TNodeSetPropagatingMaintainer nodeSetMaintainer(this);
|
||||
|
||||
intermLeft->traverse(this);
|
||||
if (TParentNodeSet* leftNodes = mNodeSets.getTopSet()) {
|
||||
TGraphLogicalOp* logicalOp = mGraph->createLogicalOp(intermLogicalOp);
|
||||
connectMultipleNodesToSingleNode(leftNodes, logicalOp);
|
||||
}
|
||||
}
|
||||
|
||||
if (TIntermTyped* intermRight = intermLogicalOp->getRight()) {
|
||||
TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
|
||||
intermRight->traverse(this);
|
||||
}
|
||||
}
|
||||
|
||||
void TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary* intermBinary)
|
||||
{
|
||||
if (TIntermTyped* intermLeft = intermBinary->getLeft())
|
||||
intermLeft->traverse(this);
|
||||
|
||||
if (TIntermTyped* intermRight = intermBinary->getRight()) {
|
||||
TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
|
||||
intermRight->traverse(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool TDependencyGraphBuilder::visitSelection(Visit visit, TIntermSelection* intermSelection)
|
||||
{
|
||||
if (TIntermNode* intermCondition = intermSelection->getCondition()) {
|
||||
TNodeSetMaintainer nodeSetMaintainer(this);
|
||||
|
||||
intermCondition->traverse(this);
|
||||
if (TParentNodeSet* conditionNodes = mNodeSets.getTopSet()) {
|
||||
TGraphSelection* selection = mGraph->createSelection(intermSelection);
|
||||
connectMultipleNodesToSingleNode(conditionNodes, selection);
|
||||
}
|
||||
}
|
||||
|
||||
if (TIntermNode* intermTrueBlock = intermSelection->getTrueBlock())
|
||||
intermTrueBlock->traverse(this);
|
||||
|
||||
if (TIntermNode* intermFalseBlock = intermSelection->getFalseBlock())
|
||||
intermFalseBlock->traverse(this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop* intermLoop)
|
||||
{
|
||||
if (TIntermTyped* intermCondition = intermLoop->getCondition()) {
|
||||
TNodeSetMaintainer nodeSetMaintainer(this);
|
||||
|
||||
intermCondition->traverse(this);
|
||||
if (TParentNodeSet* conditionNodes = mNodeSets.getTopSet()) {
|
||||
TGraphLoop* loop = mGraph->createLoop(intermLoop);
|
||||
connectMultipleNodesToSingleNode(conditionNodes, loop);
|
||||
}
|
||||
}
|
||||
|
||||
if (TIntermNode* intermBody = intermLoop->getBody())
|
||||
intermBody->traverse(this);
|
||||
|
||||
if (TIntermTyped* intermExpression = intermLoop->getExpression())
|
||||
intermExpression->traverse(this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void TDependencyGraphBuilder::connectMultipleNodesToSingleNode(TParentNodeSet* nodes,
|
||||
TGraphNode* node) const
|
||||
{
|
||||
for (TParentNodeSet::const_iterator iter = nodes->begin(); iter != nodes->end(); ++iter)
|
||||
{
|
||||
TGraphParentNode* currentNode = *iter;
|
||||
currentNode->addDependentNode(node);
|
||||
}
|
||||
}
|
181
src/3rdparty/angle/src/compiler/depgraph/DependencyGraphBuilder.h
vendored
Normal file
181
src/3rdparty/angle/src/compiler/depgraph/DependencyGraphBuilder.h
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
//
|
||||
// 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 COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
|
||||
#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
|
||||
|
||||
#include "compiler/depgraph/DependencyGraph.h"
|
||||
|
||||
//
|
||||
// Creates a dependency graph of symbols, function calls, conditions etc. by traversing a
|
||||
// intermediate tree.
|
||||
//
|
||||
class TDependencyGraphBuilder : public TIntermTraverser {
|
||||
public:
|
||||
static void build(TIntermNode* node, TDependencyGraph* graph);
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol*);
|
||||
virtual bool visitBinary(Visit visit, TIntermBinary*);
|
||||
virtual bool visitSelection(Visit visit, TIntermSelection*);
|
||||
virtual bool visitAggregate(Visit visit, TIntermAggregate*);
|
||||
virtual bool visitLoop(Visit visit, TIntermLoop*);
|
||||
|
||||
private:
|
||||
typedef std::stack<TGraphSymbol*> TSymbolStack;
|
||||
typedef std::set<TGraphParentNode*> TParentNodeSet;
|
||||
|
||||
//
|
||||
// For collecting the dependent nodes of assignments, conditions, etc.
|
||||
// while traversing the intermediate tree.
|
||||
//
|
||||
// This data structure is stack of sets. Each set contains dependency graph parent nodes.
|
||||
//
|
||||
class TNodeSetStack {
|
||||
public:
|
||||
TNodeSetStack() {};
|
||||
~TNodeSetStack() { clear(); }
|
||||
|
||||
// This should only be called after a pushSet.
|
||||
// Returns NULL if the top set is empty.
|
||||
TParentNodeSet* getTopSet() const
|
||||
{
|
||||
ASSERT(!nodeSets.empty());
|
||||
TParentNodeSet* topSet = nodeSets.top();
|
||||
return !topSet->empty() ? topSet : NULL;
|
||||
}
|
||||
|
||||
void pushSet() { nodeSets.push(new TParentNodeSet()); }
|
||||
void popSet()
|
||||
{
|
||||
ASSERT(!nodeSets.empty());
|
||||
delete nodeSets.top();
|
||||
nodeSets.pop();
|
||||
}
|
||||
|
||||
// Pops the top set and adds its contents to the new top set.
|
||||
// This should only be called after a pushSet.
|
||||
// If there is no set below the top set, the top set is just deleted.
|
||||
void popSetIntoNext()
|
||||
{
|
||||
ASSERT(!nodeSets.empty());
|
||||
TParentNodeSet* oldTopSet = nodeSets.top();
|
||||
nodeSets.pop();
|
||||
|
||||
if (!nodeSets.empty()) {
|
||||
TParentNodeSet* newTopSet = nodeSets.top();
|
||||
newTopSet->insert(oldTopSet->begin(), oldTopSet->end());
|
||||
}
|
||||
|
||||
delete oldTopSet;
|
||||
}
|
||||
|
||||
// Does nothing if there is no top set.
|
||||
// This can be called when there is no top set if we are visiting
|
||||
// symbols that are not under an assignment or condition.
|
||||
// We don't need to track those symbols.
|
||||
void insertIntoTopSet(TGraphParentNode* node)
|
||||
{
|
||||
if (nodeSets.empty())
|
||||
return;
|
||||
|
||||
nodeSets.top()->insert(node);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
while (!nodeSets.empty())
|
||||
popSet();
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::stack<TParentNodeSet*> TParentNodeSetStack;
|
||||
|
||||
TParentNodeSetStack nodeSets;
|
||||
};
|
||||
|
||||
//
|
||||
// An instance of this class pushes a new node set when instantiated.
|
||||
// When the instance goes out of scope, it and pops the node set.
|
||||
//
|
||||
class TNodeSetMaintainer {
|
||||
public:
|
||||
TNodeSetMaintainer(TDependencyGraphBuilder* factory)
|
||||
: sets(factory->mNodeSets) { sets.pushSet(); }
|
||||
~TNodeSetMaintainer() { sets.popSet(); }
|
||||
protected:
|
||||
TNodeSetStack& sets;
|
||||
};
|
||||
|
||||
//
|
||||
// An instance of this class pushes a new node set when instantiated.
|
||||
// When the instance goes out of scope, it and pops the top node set and adds its contents to
|
||||
// the new top node set.
|
||||
//
|
||||
class TNodeSetPropagatingMaintainer {
|
||||
public:
|
||||
TNodeSetPropagatingMaintainer(TDependencyGraphBuilder* factory)
|
||||
: sets(factory->mNodeSets) { sets.pushSet(); }
|
||||
~TNodeSetPropagatingMaintainer() { sets.popSetIntoNext(); }
|
||||
protected:
|
||||
TNodeSetStack& sets;
|
||||
};
|
||||
|
||||
//
|
||||
// An instance of this class keeps track of the leftmost symbol while we're exploring an
|
||||
// assignment.
|
||||
// It will push the placeholder symbol kLeftSubtree when instantiated under a left subtree,
|
||||
// and kRightSubtree under a right subtree.
|
||||
// When it goes out of scope, it will pop the leftmost symbol at the top of the scope.
|
||||
// During traversal, the TDependencyGraphBuilder will replace kLeftSubtree with a real symbol.
|
||||
// kRightSubtree will never be replaced by a real symbol because we are tracking the leftmost
|
||||
// symbol.
|
||||
//
|
||||
class TLeftmostSymbolMaintainer {
|
||||
public:
|
||||
TLeftmostSymbolMaintainer(TDependencyGraphBuilder* factory, TGraphSymbol& subtree)
|
||||
: leftmostSymbols(factory->mLeftmostSymbols)
|
||||
{
|
||||
needsPlaceholderSymbol = leftmostSymbols.empty() || leftmostSymbols.top() != &subtree;
|
||||
if (needsPlaceholderSymbol)
|
||||
leftmostSymbols.push(&subtree);
|
||||
}
|
||||
|
||||
~TLeftmostSymbolMaintainer()
|
||||
{
|
||||
if (needsPlaceholderSymbol)
|
||||
leftmostSymbols.pop();
|
||||
}
|
||||
|
||||
protected:
|
||||
TSymbolStack& leftmostSymbols;
|
||||
bool needsPlaceholderSymbol;
|
||||
};
|
||||
|
||||
TDependencyGraphBuilder(TDependencyGraph* graph)
|
||||
: TIntermTraverser(true, false, false)
|
||||
, mLeftSubtree(NULL)
|
||||
, mRightSubtree(NULL)
|
||||
, mGraph(graph) {}
|
||||
void build(TIntermNode* intermNode) { intermNode->traverse(this); }
|
||||
|
||||
void connectMultipleNodesToSingleNode(TParentNodeSet* nodes, TGraphNode* node) const;
|
||||
|
||||
void visitAssignment(TIntermBinary*);
|
||||
void visitLogicalOp(TIntermBinary*);
|
||||
void visitBinaryChildren(TIntermBinary*);
|
||||
void visitFunctionDefinition(TIntermAggregate*);
|
||||
void visitFunctionCall(TIntermAggregate* intermFunctionCall);
|
||||
void visitAggregateChildren(TIntermAggregate*);
|
||||
|
||||
TGraphSymbol mLeftSubtree;
|
||||
TGraphSymbol mRightSubtree;
|
||||
|
||||
TDependencyGraph* mGraph;
|
||||
TNodeSetStack mNodeSets;
|
||||
TSymbolStack mLeftmostSymbols;
|
||||
};
|
||||
|
||||
#endif // COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
|
65
src/3rdparty/angle/src/compiler/depgraph/DependencyGraphOutput.cpp
vendored
Normal file
65
src/3rdparty/angle/src/compiler/depgraph/DependencyGraphOutput.cpp
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// 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 "compiler/depgraph/DependencyGraphOutput.h"
|
||||
|
||||
void TDependencyGraphOutput::outputIndentation()
|
||||
{
|
||||
for (int i = 0; i < getDepth(); ++i)
|
||||
mSink << " ";
|
||||
}
|
||||
|
||||
void TDependencyGraphOutput::visitArgument(TGraphArgument* parameter)
|
||||
{
|
||||
outputIndentation();
|
||||
mSink << "argument " << parameter->getArgumentNumber() << " of call to "
|
||||
<< parameter->getIntermFunctionCall()->getName() << "\n";
|
||||
}
|
||||
|
||||
void TDependencyGraphOutput::visitFunctionCall(TGraphFunctionCall* functionCall)
|
||||
{
|
||||
outputIndentation();
|
||||
mSink << "function call " << functionCall->getIntermFunctionCall()->getName() << "\n";
|
||||
}
|
||||
|
||||
void TDependencyGraphOutput::visitSymbol(TGraphSymbol* symbol)
|
||||
{
|
||||
outputIndentation();
|
||||
mSink << symbol->getIntermSymbol()->getSymbol() << " (symbol id: "
|
||||
<< symbol->getIntermSymbol()->getId() << ")\n";
|
||||
}
|
||||
|
||||
void TDependencyGraphOutput::visitSelection(TGraphSelection* selection)
|
||||
{
|
||||
outputIndentation();
|
||||
mSink << "selection\n";
|
||||
}
|
||||
|
||||
void TDependencyGraphOutput::visitLoop(TGraphLoop* loop)
|
||||
{
|
||||
outputIndentation();
|
||||
mSink << "loop condition\n";
|
||||
}
|
||||
|
||||
void TDependencyGraphOutput::visitLogicalOp(TGraphLogicalOp* logicalOp)
|
||||
{
|
||||
outputIndentation();
|
||||
mSink << "logical " << logicalOp->getOpString() << "\n";
|
||||
}
|
||||
|
||||
void TDependencyGraphOutput::outputAllSpanningTrees(TDependencyGraph& graph)
|
||||
{
|
||||
mSink << "\n";
|
||||
|
||||
for (TGraphNodeVector::const_iterator iter = graph.begin(); iter != graph.end(); ++iter)
|
||||
{
|
||||
TGraphNode* symbol = *iter;
|
||||
mSink << "--- Dependency graph spanning tree ---\n";
|
||||
clearVisited();
|
||||
symbol->traverse(this);
|
||||
mSink << "\n";
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user