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:
Jason Barron 2012-10-15 14:16:51 +02:00 committed by The Qt Project
parent 84d09214bc
commit e0c0e83fd5
239 changed files with 67207 additions and 29 deletions

35
src/3rdparty/angle/.gitignore vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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
View 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

File diff suppressed because it is too large Load Diff

View 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_ */

View 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_

View 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_ */

View 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;
}

View 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_

View 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
View 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
View 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
View 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)

View 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_

View 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(";
}

View 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_

View 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;
}

View 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;
}

View 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_

View 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;
}

View 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_

View 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);
}
}

View 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_

View 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;
}

View 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_

View 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, "");
}

View 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_

View 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");
}
}

View 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_

View 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_

View 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();
}

View 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;
};

View 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");
}

View 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_

View 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;
}

View 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_

View 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;
}

View 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

View 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_

View 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;
}

View 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_

View 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);
}

File diff suppressed because it is too large Load Diff

56
src/3rdparty/angle/src/compiler/MMap.h vendored Normal file
View 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_

View 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;
}

View 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_

View 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;
}

View 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_

View 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;
}

View 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_

View 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.
}
}

View 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_

File diff suppressed because it is too large Load Diff

View 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_

File diff suppressed because it is too large Load Diff

View 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_

View 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();
}

View 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_

View 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_

View 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;
}

View 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);

View 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);
}

View 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*);

View 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

View 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;
}
}

View 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_

View 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_

View 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);
}

View 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] );
}
}

View 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_

View 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";
}
}
}

View 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_

View 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);
}

View 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_

View 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();
}

View 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
View 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_

View 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++;
}
}

View 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_

View 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;
}

View 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;
};

View 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;
}

View 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_

View 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;
}

View 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_

View 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);
}

View 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_

View 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
View 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_

View 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;
}

View 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

View 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);
}
}

View 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

View 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