Bug 1211774. Update to ANGLE 2522.

--HG--
extra : rebase_source : 61b730037c24fc6d4ce6cd47a7bc176a6336d477
This commit is contained in:
Jeff Muizelaar 2015-10-05 13:48:44 -04:00
parent 3aa7323650
commit 48d057951d
435 changed files with 31792 additions and 13700 deletions

View File

@ -1,9 +1,19 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Copyright 2014-2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# import the use_x11 variable
import("//build/config/ui.gni")
import("//third_party/angle/build/angle_common.gni")
angle_git_is_present = exec_script("src/commit_id.py",
[
"check",
rebase_path(".", root_build_dir),
],
"value")
angle_use_commit_id = angle_git_is_present == 1
gles_gypi = exec_script(
"//build/gypi_to_gn.py",
@ -33,30 +43,11 @@ config("internal_config") {
]
}
angle_enable_d3d9 = false
angle_enable_d3d11 = false
angle_enable_gl = false
if (is_win) {
angle_enable_d3d9 = true
angle_enable_d3d11 = true
angle_enable_gl = true
import("//build/config/win/visual_studio_version.gni")
copy("copy_compiler_dll") {
sources = [ "$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll" ]
outputs = [ "$root_build_dir/d3dcompiler_47.dll" ]
}
} # is_win
if (is_linux) {
angle_enable_gl = true
}
angle_enable_hlsl = false
if (angle_enable_d3d9 || angle_enable_d3d11) {
angle_enable_hlsl = true
}
component("translator") {
@ -93,8 +84,9 @@ source_set("includes") {
"include/GLES2/gl2ext.h",
"include/GLES2/gl2platform.h",
"include/GLES3/gl3.h",
"include/GLES3/gl3ext.h",
"include/GLES3/gl3platform.h",
"include/GLES3/gl31.h",
"include/GLES3/gl32.h",
"include/GLSLANG/ShaderLang.h",
"include/KHR/khrplatform.h",
]
@ -114,6 +106,7 @@ config("translator_static_config") {
defines = [ "ANGLE_TRANSLATOR_STATIC" ]
}
config("debug_annotations_config") {
if (is_debug) {
defines = [
@ -184,19 +177,32 @@ config("commit_id_config") {
include_dirs = [ "$root_gen_dir/angle" ]
}
action("commit_id") {
script = "src/commit_id.py"
commit_id_output_file = "$root_gen_dir/angle/id/commit.h"
if (angle_use_commit_id) {
action("commit_id") {
script = "src/commit_id.py"
outputs = [
commit_id_output_file,
]
output_file = "$root_gen_dir/angle/id/commit.h"
outputs = [ output_file ]
args = [
"gen",
rebase_path(".", root_build_dir),
rebase_path(commit_id_output_file, root_build_dir),
]
args = [
"gen",
rebase_path(".", root_build_dir),
rebase_path(output_file, root_build_dir),
]
public_configs = [ ":commit_id_config" ]
public_configs = [ ":commit_id_config" ]
}
} else {
copy("commit_id") {
sources = [
"src/commit.h",
]
outputs = [
commit_id_output_file,
]
public_configs = [ ":commit_id_config" ]
}
}
config("libANGLE_config") {
@ -215,10 +221,20 @@ config("libANGLE_config") {
defines += [ "ANGLE_USE_X11" ]
}
defines += [
"GL_APICALL=",
"GL_GLEXT_PROTOTYPES=",
"EGLAPI=",
"GL_GLEXT_PROTOTYPES",
]
if (is_win) {
defines += [
"GL_APICALL=",
"EGLAPI=",
]
} else {
defines += [
"GL_APICALL=__attribute__((visibility(\"default\")))",
"EGLAPI=__attribute__((visibility(\"default\")))",
]
}
if (is_win) {
cflags += [ "/wd4530" ] # C++ exception handler used, but unwind semantics are not enabled.
}
@ -333,6 +349,7 @@ shared_library("libEGL") {
configs += [
":internal_config",
":commit_id_config",
":debug_annotations_config",
":libANGLE_config",
"//build/config/compiler:no_chromium_code",
]
@ -346,3 +363,48 @@ shared_library("libEGL") {
":libGLESv2",
]
}
util_gypi = exec_script(
"//build/gypi_to_gn.py",
[ rebase_path("util/util.gyp") ],
"scope",
[ "util/util.gyp" ])
static_library("angle_util") {
sources = rebase_path(util_gypi.util_sources, ".", "util")
if (is_win) {
sources += rebase_path(util_gypi.util_win32_sources, ".", "util")
}
if (is_linux) {
sources += rebase_path(util_gypi.util_linux_sources, ".", "util")
}
if (is_mac) {
sources += rebase_path(util_gypi.util_osx_sources, ".", "util")
}
if (use_x11) {
sources += rebase_path(util_gypi.util_x11_sources, ".", "util")
}
defines = [
"GL_GLEXT_PROTOTYPES",
"EGL_EGLEXT_PROTOTYPES",
]
configs += [
":internal_config",
":debug_annotations_config",
]
include_dirs = [
"util",
]
deps = [
":libEGL",
":libGLESv2",
]
}

View File

@ -104,3 +104,4 @@ NVIDIA Corporation
Opera Software ASA
Daniel Bratell
Tomasz Moniuszko

View File

@ -4,12 +4,12 @@ vars = {
deps = {
"third_party/gyp":
Var('chromium_git') + "/external/gyp@b4781fc38236b0fb1238969c918a75a200cfffdb",
Var('chromium_git') + "/external/gyp@81c2e5ff92af29bab61c982808076ddce3d200a2",
# TODO(kbr): figure out how to better stay in sync with Chromium's
# versions of googletest and googlemock.
"src/tests/third_party/googletest":
Var('chromium_git') + "/external/googletest.git@23574bf2333f834ff665f894c97bef8a5b33a0a9",
Var('chromium_git') + "/external/googletest.git@9855a87157778d39b95eccfb201a9dc90f6d61c6",
"src/tests/third_party/googlemock":
Var('chromium_git') + "/external/googlemock.git@b2cb211e49d872101d991201362d7b97d7d69910",

View File

@ -6,7 +6,7 @@ extern "C" {
#endif
/*
** Copyright (c) 2013-2014 The Khronos Group Inc.
** Copyright (c) 2013-2015 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
@ -33,12 +33,12 @@ extern "C" {
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 29318 $ on $Date: 2015-01-02 03:16:10 -0800 (Fri, 02 Jan 2015) $
** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $
*/
#include <EGL/eglplatform.h>
/* Generated on date 20150102 */
/* Generated on date 20150623 */
/* Generated C header for:
* API: egl

View File

@ -6,7 +6,7 @@ extern "C" {
#endif
/*
** Copyright (c) 2013-2014 The Khronos Group Inc.
** Copyright (c) 2013-2015 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
@ -33,12 +33,12 @@ extern "C" {
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 27018 $ on $Date: 2014-06-10 08:06:12 -0700 (Tue, 10 Jun 2014) $
** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $
*/
#include <EGL/eglplatform.h>
#define EGL_EGLEXT_VERSION 20140610
#define EGL_EGLEXT_VERSION 20150623
/* Generated C header for:
* API: egl
@ -94,12 +94,28 @@ EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type,
#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
#endif /* EGL_KHR_create_context */
#ifndef EGL_KHR_create_context_no_error
#define EGL_KHR_create_context_no_error 1
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3
#endif /* EGL_KHR_create_context_no_error */
#ifndef EGL_KHR_fence_sync
#define EGL_KHR_fence_sync 1
typedef khronos_utime_nanoseconds_t EGLTimeKHR;
#ifdef KHRONOS_SUPPORT_INT64
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
#define EGL_SYNC_CONDITION_KHR 0x30F8
#define EGL_SYNC_FENCE_KHR 0x30F9
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 PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
#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 eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
#endif
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_KHR_fence_sync */
@ -207,6 +223,15 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface s
#endif
#endif /* EGL_KHR_lock_surface3 */
#ifndef EGL_KHR_partial_update
#define EGL_KHR_partial_update 1
#define EGL_BUFFER_AGE_KHR 0x313D
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#endif
#endif /* EGL_KHR_partial_update */
#ifndef EGL_KHR_platform_android
#define EGL_KHR_platform_android 1
#define EGL_PLATFORM_ANDROID_KHR 0x3141
@ -230,7 +255,6 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface s
#ifndef EGL_KHR_reusable_sync
#define EGL_KHR_reusable_sync 1
typedef khronos_utime_nanoseconds_t EGLTimeKHR;
#ifdef KHRONOS_SUPPORT_INT64
#define EGL_SYNC_STATUS_KHR 0x30F1
#define EGL_SIGNALED_KHR 0x30F2
@ -242,17 +266,9 @@ typedef khronos_utime_nanoseconds_t EGLTimeKHR;
#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
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);
#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
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_KHR_reusable_sync */
@ -354,6 +370,14 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy,
#define EGL_KHR_surfaceless_context 1
#endif /* EGL_KHR_surfaceless_context */
#ifndef EGL_KHR_swap_buffers_with_damage
#define EGL_KHR_swap_buffers_with_damage 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#endif
#endif /* EGL_KHR_swap_buffers_with_damage */
#ifndef EGL_KHR_vg_parent_image
#define EGL_KHR_vg_parent_image 1
#define EGL_VG_PARENT_IMAGE_KHR 0x30BA
@ -410,10 +434,16 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR
#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
#ifndef EGL_ANGLE_window_fixed_size
#define EGL_ANGLE_window_fixed_size 1
#define EGL_FIXED_SIZE_ANGLE 0x3201
#endif /* EGL_ANGLE_window_fixed_size */
#ifndef EGL_ANGLE_device_d3d
#define EGL_ANGLE_device_d3d 1
#define EGL_D3D9_DEVICE_ANGLE 0x33A0
#define EGL_D3D11_DEVICE_ANGLE 0x33A1
#endif /* EGL_ANGLE_device_d3d */
#ifndef EGL_ANGLE_keyed_mutex
#define EGL_ANGLE_keyed_mutex 1
#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2
#endif /* EGL_ANGLE_keyed_mutex */
#ifndef EGL_ANGLE_query_surface_pointer
#define EGL_ANGLE_query_surface_pointer 1
@ -464,16 +494,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
#endif /* EGL_ANGLE_platform_angle_opengl */
#ifndef EGL_ANGLE_device_d3d
#define EGL_ANGLE_device_d3d 1
#define EGL_D3D9_DEVICE_ANGLE 0x33A0
#define EGL_D3D11_DEVICE_ANGLE 0x33A1
#endif /* EGL_ANGLE_device_d3d */
#ifndef EGL_ANGLE_keyed_mutex
#define EGL_ANGLE_keyed_mutex 1
#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2
#endif /* EGL_ANGLE_keyed_mutex */
#ifndef EGL_ANGLE_window_fixed_size
#define EGL_ANGLE_window_fixed_size 1
#define EGL_FIXED_SIZE_ANGLE 0x3201
#endif /* EGL_ANGLE_window_fixed_size */
#ifndef EGL_ARM_pixmap_multisample_discard
#define EGL_ARM_pixmap_multisample_discard 1
@ -515,6 +539,20 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a
#endif
#endif /* EGL_EXT_device_base */
#ifndef EGL_EXT_device_drm
#define EGL_EXT_device_drm 1
#define EGL_DRM_DEVICE_FILE_EXT 0x3233
#endif /* EGL_EXT_device_drm */
#ifndef EGL_EXT_device_enumeration
#define EGL_EXT_device_enumeration 1
#endif /* EGL_EXT_device_enumeration */
#ifndef EGL_EXT_device_openwf
#define EGL_EXT_device_openwf 1
#define EGL_OPENWF_DEVICE_ID_EXT 0x3237
#endif /* EGL_EXT_device_openwf */
#ifndef EGL_EXT_device_query
#define EGL_EXT_device_query 1
#endif /* EGL_EXT_device_query */
@ -550,6 +588,48 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a
#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
#endif /* EGL_EXT_multiview_window */
#ifndef EGL_EXT_output_base
#define EGL_EXT_output_base 1
typedef void *EGLOutputLayerEXT;
typedef void *EGLOutputPortEXT;
#define EGL_NO_OUTPUT_LAYER_EXT ((EGLOutputLayerEXT)0)
#define EGL_NO_OUTPUT_PORT_EXT ((EGLOutputPortEXT)0)
#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D
#define EGL_BAD_OUTPUT_PORT_EXT 0x322E
#define EGL_SWAP_INTERVAL_EXT 0x322F
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
#endif
#endif /* EGL_EXT_output_base */
#ifndef EGL_EXT_output_drm
#define EGL_EXT_output_drm 1
#define EGL_DRM_CRTC_EXT 0x3234
#define EGL_DRM_PLANE_EXT 0x3235
#define EGL_DRM_CONNECTOR_EXT 0x3236
#endif /* EGL_EXT_output_drm */
#ifndef EGL_EXT_output_openwf
#define EGL_EXT_output_openwf 1
#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238
#define EGL_OPENWF_PORT_ID_EXT 0x3239
#endif /* EGL_EXT_output_openwf */
#ifndef EGL_EXT_platform_base
#define EGL_EXT_platform_base 1
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
@ -583,6 +663,14 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy,
#define EGL_PROTECTED_CONTENT_EXT 0x32C0
#endif /* EGL_EXT_protected_surface */
#ifndef EGL_EXT_stream_consumer_egloutput
#define EGL_EXT_stream_consumer_egloutput 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
#endif
#endif /* EGL_EXT_stream_consumer_egloutput */
#ifndef EGL_EXT_swap_buffers_with_damage
#define EGL_EXT_swap_buffers_with_damage 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
@ -591,6 +679,35 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSu
#endif
#endif /* EGL_EXT_swap_buffers_with_damage */
#ifndef EGL_EXT_yuv_surface
#define EGL_EXT_yuv_surface 1
#define EGL_YUV_ORDER_EXT 0x3301
#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311
#define EGL_YUV_SUBSAMPLE_EXT 0x3312
#define EGL_YUV_DEPTH_RANGE_EXT 0x3317
#define EGL_YUV_CSC_STANDARD_EXT 0x330A
#define EGL_YUV_PLANE_BPP_EXT 0x331A
#define EGL_YUV_BUFFER_EXT 0x3300
#define EGL_YUV_ORDER_YUV_EXT 0x3302
#define EGL_YUV_ORDER_YVU_EXT 0x3303
#define EGL_YUV_ORDER_YUYV_EXT 0x3304
#define EGL_YUV_ORDER_UYVY_EXT 0x3305
#define EGL_YUV_ORDER_YVYU_EXT 0x3306
#define EGL_YUV_ORDER_VYUY_EXT 0x3307
#define EGL_YUV_ORDER_AYUV_EXT 0x3308
#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313
#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314
#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315
#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318
#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319
#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B
#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C
#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D
#define EGL_YUV_PLANE_BPP_0_EXT 0x331B
#define EGL_YUV_PLANE_BPP_8_EXT 0x331C
#define EGL_YUV_PLANE_BPP_10_EXT 0x331D
#endif /* EGL_EXT_yuv_surface */
#ifndef EGL_HI_clientpixmap
#define EGL_HI_clientpixmap 1
struct EGLClientPixmapHI {
@ -639,6 +756,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR
#endif
#endif /* EGL_MESA_drm_image */
#ifndef EGL_MESA_image_dma_buf_export
#define EGL_MESA_image_dma_buf_export 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers);
EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
#endif
#endif /* EGL_MESA_image_dma_buf_export */
#ifndef EGL_MESA_platform_gbm
#define EGL_MESA_platform_gbm 1
#define EGL_PLATFORM_GBM_MESA 0x31D7
@ -683,6 +810,13 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurfa
#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
#endif /* EGL_NV_coverage_sample_resolve */
#ifndef EGL_NV_cuda_event
#define EGL_NV_cuda_event 1
#define EGL_CUDA_EVENT_HANDLE_NV 0x323B
#define EGL_SYNC_CUDA_EVENT_NV 0x323C
#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D
#endif /* EGL_NV_cuda_event */
#ifndef EGL_NV_depth_nonlinear
#define EGL_NV_depth_nonlinear 1
#define EGL_DEPTH_ENCODING_NV 0x30E2
@ -690,6 +824,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurfa
#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
#endif /* EGL_NV_depth_nonlinear */
#ifndef EGL_NV_device_cuda
#define EGL_NV_device_cuda 1
#define EGL_CUDA_DEVICE_NV 0x323A
#endif /* EGL_NV_device_cuda */
#ifndef EGL_NV_native_query
#define EGL_NV_native_query 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id);
@ -772,6 +911,16 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_NV_system_time */
#ifndef EGL_TIZEN_image_native_buffer
#define EGL_TIZEN_image_native_buffer 1
#define EGL_NATIVE_BUFFER_TIZEN 0x32A0
#endif /* EGL_TIZEN_image_native_buffer */
#ifndef EGL_TIZEN_image_native_surface
#define EGL_TIZEN_image_native_surface 1
#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
#endif /* EGL_TIZEN_image_native_surface */
#ifdef __cplusplus
}
#endif

View File

@ -25,7 +25,7 @@
*/
/* Platform-specific types and definitions for egl.h
* $Revision: 23432 $ on $Date: 2013-10-09 00:57:24 -0700 (Wed, 09 Oct 2013) $
* $Revision: 30994 $ on $Date: 2015-04-30 13:36:48 -0700 (Thu, 30 Apr 2015) $
*
* 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
@ -117,11 +117,15 @@ typedef Window EGLNativeWindowType;
#elif defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) )
// TODO(jmadill): native implementation for OSX
#if defined(__OBJC__)
@class CALayer;
#else
class CALayer;
#endif
typedef void *EGLNativeDisplayType;
typedef void *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
typedef CALayer *EGLNativeWindowType;
#else
#error "Platform not recognized"

View File

@ -1,56 +1,87 @@
#ifndef __gl2_h_
#define __gl2_h_
/* $Revision: 20555 $ on $Date:: 2013-02-12 14:32:47 -0800 #$ */
#include <GLES2/gl2platform.h>
#define __gl2_h_ 1
#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/ .
** Copyright (c) 2013-2015 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.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 31811 $ on $Date: 2015-08-10 00:01:11 -0700 (Mon, 10 Aug 2015) $
*/
#include <GLES2/gl2platform.h>
#ifndef GL_APIENTRYP
#define GL_APIENTRYP GL_APIENTRY*
#endif
/* Generated on date 20150809 */
/* Generated C header for:
* API: gles2
* Profile: common
* Versions considered: 2\.[0-9]
* Versions emitted: .*
* Default extensions included: None
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
/*-------------------------------------------------------------------------
* 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 */
#ifndef GL_ES_VERSION_2_0
#define GL_ES_VERSION_2_0 1
#include <KHR/khrplatform.h>
typedef khronos_int8_t GLbyte;
typedef khronos_float_t GLclampf;
typedef khronos_int32_t GLfixed;
typedef short GLshort;
typedef unsigned short GLushort;
typedef void GLvoid;
typedef struct __GLsync *GLsync;
typedef khronos_int64_t GLint64;
typedef khronos_uint64_t GLuint64;
typedef unsigned int GLenum;
typedef unsigned int GLuint;
typedef char GLchar;
typedef khronos_float_t GLfloat;
typedef khronos_ssize_t GLsizeiptr;
typedef khronos_intptr_t GLintptr;
typedef khronos_ssize_t GLsizeiptr;
/* OpenGL ES core versions */
#define GL_ES_VERSION_2_0 1
/* ClearBufferMask */
typedef unsigned int GLbitfield;
typedef int GLint;
typedef unsigned char GLboolean;
typedef int GLsizei;
typedef khronos_uint8_t GLubyte;
#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
@ -58,18 +89,6 @@ typedef khronos_ssize_t GLsizeiptr;
#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
@ -78,29 +97,15 @@ typedef khronos_ssize_t GLsizeiptr;
#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_RGB 0x8009
#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
@ -110,38 +115,19 @@ typedef khronos_ssize_t GLsizeiptr;
#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
@ -152,19 +138,13 @@ typedef khronos_ssize_t GLsizeiptr;
#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
@ -191,7 +171,6 @@ typedef khronos_ssize_t GLsizeiptr;
#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
@ -206,32 +185,18 @@ typedef khronos_ssize_t GLsizeiptr;
#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_GENERATE_MIPMAP_HINT 0x8192
#define GL_BYTE 0x1400
#define GL_UNSIGNED_BYTE 0x1401
#define GL_SHORT 0x1402
@ -240,44 +205,35 @@ typedef khronos_ssize_t GLsizeiptr;
#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_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_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
#define GL_NEVER 0x0200
#define GL_LESS 0x0201
#define GL_EQUAL 0x0202
@ -286,9 +242,6 @@ typedef khronos_ssize_t GLsizeiptr;
#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
@ -296,35 +249,21 @@ typedef khronos_ssize_t GLsizeiptr;
#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
@ -334,8 +273,6 @@ typedef khronos_ssize_t GLsizeiptr;
#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
@ -369,13 +306,9 @@ typedef khronos_ssize_t GLsizeiptr;
#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
@ -391,48 +324,34 @@ typedef khronos_ssize_t GLsizeiptr;
#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_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_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_INDEX8 0x8D48
#define GL_RENDERBUFFER_WIDTH 0x8D42
#define GL_RENDERBUFFER_HEIGHT 0x8D43
#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
@ -442,179 +361,313 @@ typedef khronos_ssize_t GLsizeiptr;
#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_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_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_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 GLint 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 GLint 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* const* 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);
typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);
typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);
typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);
typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);
typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap);
typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void);
typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void);
typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode);
typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data);
typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void);
typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);
typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode);
typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture);
typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width);
typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);
typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);
typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);
typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
#ifdef GL_GLEXT_PROTOTYPES
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 (GLfloat red, GLfloat green, GLfloat blue, GLfloat 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 sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d);
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 void *data);
GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *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 (GLfloat n, GLfloat f);
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 void *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 GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);
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 *data);
GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data);
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 GLint 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, void **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, void *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 (GLfloat value, GLboolean invert);
GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*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 sfail, GLenum dpfail, GLenum dppass);
GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *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 void *pixels);
GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0);
GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0);
GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
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 index, GLfloat x);
GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
#endif
#endif /* GL_ES_VERSION_2_0 */
#ifdef __cplusplus
}
#endif
#endif /* __gl2_h_ */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#ifndef __gl2platform_h_
#define __gl2platform_h_
/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */
/* $Revision: 23328 $ on $Date:: 2013-10-02 02:28:28 -0700 #$ */
/*
* This document is licensed under the SGI Free Software B License Version

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
#ifndef __gl3ext_h_
#define __gl3ext_h_
/* $Revision: 17809 $ on $Date:: 2012-05-14 08:03:36 -0700 #$ */
/*
* This document is licensed under the SGI Free Software B License Version
* 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
*/
/* OpenGL ES 3 Extensions
*
* After an OES extension's interactions with OpenGl ES 3.0 have been documented,
* its tokens and function definitions should be added to this file in a manner
* that does not conflict with gl2ext.h or gl3.h.
*
* Tokens and function definitions for extensions that have become standard
* features in OpenGL ES 3.0 will not be added to this file.
*
* Applications using OpenGL-ES-2-only extensions should include gl2ext.h
*/
#endif /* __gl3ext_h_ */

View File

@ -1,7 +1,7 @@
#ifndef __gl3platform_h_
#define __gl3platform_h_
/* $Revision: 18437 $ on $Date:: 2012-07-08 23:31:39 -0700 #$ */
/* $Revision: 23328 $ on $Date:: 2013-10-02 02:28:28 -0700 #$ */
/*
* This document is licensed under the SGI Free Software B License Version

View File

@ -48,7 +48,7 @@ typedef unsigned int GLenum;
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 138
#define ANGLE_SH_VERSION 140
typedef enum {
SH_GLES2_SPEC = 0x8B40,
@ -247,6 +247,7 @@ typedef struct
int OES_standard_derivatives;
int OES_EGL_image_external;
int ARB_texture_rectangle;
int EXT_blend_func_extended;
int EXT_draw_buffers;
int EXT_frag_depth;
int EXT_shader_texture_lod;
@ -271,6 +272,13 @@ typedef struct
int MinProgramTexelOffset;
int MaxProgramTexelOffset;
// Extension constants.
// Value of GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT for OpenGL ES output context.
// Value of GL_MAX_DUAL_SOURCE_DRAW_BUFFERS for OpenGL output context.
// GLES SL version 100 gl_MaxDualSourceDrawBuffersEXT value for EXT_blend_func_extended.
int MaxDualSourceDrawBuffers;
// Name Hashing.
// Set a 64 bit hash function to enable user-defined name hashing.
// Default is NULL.
@ -398,7 +406,7 @@ COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
COMPILER_EXPORT const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle);
COMPILER_EXPORT const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle);
COMPILER_EXPORT const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle);
COMPILER_EXPORT const std::vector<sh::Attribute> *ShGetOutputVariables(const ShHandle handle);
COMPILER_EXPORT const std::vector<sh::OutputVariable> *ShGetOutputVariables(const ShHandle handle);
COMPILER_EXPORT const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle);
typedef struct

View File

@ -110,19 +110,39 @@ struct COMPILER_EXPORT Uniform : public ShaderVariable
bool isSameUniformAtLinkTime(const Uniform &other) const;
};
struct COMPILER_EXPORT Attribute : public ShaderVariable
// An interface variable is a variable which passes data between the GL data structures and the
// shader execution: either vertex shader inputs or fragment shader outputs. These variables can
// have integer locations to pass back to the GL API.
struct COMPILER_EXPORT InterfaceVariable : public ShaderVariable
{
InterfaceVariable();
~InterfaceVariable();
InterfaceVariable(const InterfaceVariable &other);
InterfaceVariable &operator=(const InterfaceVariable &other);
bool operator==(const InterfaceVariable &other) const;
bool operator!=(const InterfaceVariable &other) const { return !operator==(other); }
int location;
};
struct COMPILER_EXPORT Attribute : public InterfaceVariable
{
Attribute();
~Attribute();
Attribute(const Attribute &other);
Attribute &operator=(const Attribute &other);
bool operator==(const Attribute &other) const;
bool operator!=(const Attribute &other) const
{
return !operator==(other);
}
bool operator!=(const Attribute &other) const { return !operator==(other); }
};
int location;
struct COMPILER_EXPORT OutputVariable : public InterfaceVariable
{
OutputVariable();
~OutputVariable();
OutputVariable(const OutputVariable &other);
OutputVariable &operator=(const OutputVariable &other);
bool operator==(const OutputVariable &other) const;
bool operator!=(const OutputVariable &other) const { return !operator==(other); }
};
struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable

View File

@ -13,7 +13,8 @@
#include "GLES2/gl2.h"
#include "GLES2/gl2ext.h"
#include "GLES3/gl3.h"
#include "GLES3/gl3ext.h"
#include "GLES3/gl31.h"
#include "GLES3/gl32.h"
// The following enum is used in ANGLE, but is from desktop GL
#ifndef GL_SAMPLER_2D_RECT_ARB

View File

@ -31,6 +31,17 @@ class Platform
// it is recommended that the fixed point be no further in the past than the epoch.
virtual double monotonicallyIncreasingTime() { return 0; }
// Logging ------------------------------------------------------------
// Log an error message within the platform implementation.
virtual void logError(const char *errorMessage) {}
// Log a warning message within the platform implementation.
virtual void logWarning(const char *warningMessage) {}
// Log an info message within the platform implementation.
virtual void logInfo(const char *infoMessage) {}
// Tracing --------
// Get a pointer to the enabled state of the given trace category. The

View File

@ -69,6 +69,7 @@ UNIFIED_SOURCES += [
'src/compiler/translator/PruneEmptyDeclarations.cpp',
'src/compiler/translator/RecordConstantPrecision.cpp',
'src/compiler/translator/RegenerateStructNames.cpp',
'src/compiler/translator/RemoveDynamicIndexing.cpp',
'src/compiler/translator/RemovePow.cpp',
'src/compiler/translator/RemoveSwitchFallThrough.cpp',
'src/compiler/translator/RewriteElseBlocks.cpp',

View File

@ -86,15 +86,6 @@
},
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'msvs_application_type_revision' : '<(angle_build_winrt_app_type_revision)',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
['OS=="win"',
{
'configurations':
@ -127,14 +118,8 @@
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'msvs_application_type_revision' : '<(angle_build_winrt_app_type_revision)',
'type' : 'shared_library',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
},
],
@ -176,14 +161,8 @@
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'msvs_application_type_revision' : '<(angle_build_winrt_app_type_revision)',
'type' : 'shared_library',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
}
]
@ -214,14 +193,8 @@
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'msvs_application_type_revision' : '<(angle_build_winrt_app_type_revision)',
'type' : 'shared_library',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
}
]
@ -259,14 +232,8 @@
}],
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'msvs_application_type_revision' : '<(angle_build_winrt_app_type_revision)',
'type' : 'shared_library',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
]
},
], # targets

View File

@ -1,14 +1,3 @@
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// commit.h:
// This is a default commit hash header, when git is not available.
//
#define ANGLE_COMMIT_HASH "unknown hash"
#define ANGLE_COMMIT_HASH_SIZE 12
#define ANGLE_COMMIT_DATE "unknown date"
#define ANGLE_DISABLE_PROGRAM_BINARY_LOAD
#define ANGLE_COMMIT_HASH "4a2a4c31a988"
#define ANGLE_COMMIT_HASH_SIZE 12
#define ANGLE_COMMIT_DATE "2015-09-29 14:41:08 -0400"

View File

@ -0,0 +1,156 @@
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// BitSetIterator:
// A helper class to quickly bitscan bitsets for set bits.
//
#ifndef COMMON_BITSETITERATOR_H_
#define COMMON_BITSETITERATOR_H_
#include <stdint.h>
#include <bitset>
#include "common/angleutils.h"
#include "common/debug.h"
#include "common/mathutil.h"
#include "common/platform.h"
namespace angle
{
template <size_t N>
class BitSetIterator final
{
public:
BitSetIterator(const std::bitset<N> &bitset);
BitSetIterator(const BitSetIterator &other);
BitSetIterator &operator=(const BitSetIterator &other);
class Iterator final
{
public:
Iterator(const std::bitset<N> &bits);
Iterator &operator++();
bool operator==(const Iterator &other) const;
bool operator!=(const Iterator &other) const;
unsigned long operator*() const { return mCurrentBit; }
private:
unsigned long getNextBit();
static const size_t BitsPerWord = sizeof(unsigned long) * 8;
std::bitset<N> mBits;
unsigned long mCurrentBit;
unsigned long mOffset;
};
Iterator begin() const { return Iterator(mBits); }
Iterator end() const { return Iterator(std::bitset<N>(0)); }
private:
const std::bitset<N> mBits;
};
template <size_t N>
BitSetIterator<N>::BitSetIterator(const std::bitset<N> &bitset)
: mBits(bitset)
{
}
template <size_t N>
BitSetIterator<N>::BitSetIterator(const BitSetIterator &other)
: mBits(other.mBits)
{
}
template <size_t N>
BitSetIterator<N> &BitSetIterator<N>::operator=(const BitSetIterator &other)
{
mBits = other.mBits;
return *this;
}
template <size_t N>
BitSetIterator<N>::Iterator::Iterator(const std::bitset<N> &bits)
: mBits(bits), mCurrentBit(0), mOffset(0)
{
if (bits.any())
{
mCurrentBit = getNextBit();
}
else
{
mOffset = static_cast<unsigned long>(rx::roundUp(N, BitsPerWord));
}
}
template <size_t N>
typename BitSetIterator<N>::Iterator &BitSetIterator<N>::Iterator::operator++()
{
ASSERT(mBits.any());
mBits.set(mCurrentBit - mOffset, 0);
mCurrentBit = getNextBit();
return *this;
}
inline unsigned long ScanForward(unsigned long bits)
{
ASSERT(bits != 0);
#if defined(ANGLE_PLATFORM_WINDOWS)
unsigned long firstBitIndex = 0ul;
unsigned char ret = _BitScanForward(&firstBitIndex, bits);
ASSERT(ret != 0);
UNUSED_ASSERTION_VARIABLE(ret);
return firstBitIndex;
#elif defined(ANGLE_PLATFORM_POSIX)
return static_cast<unsigned long>(__builtin_ctzl(bits));
#else
#error Please implement bit-scan-forward for your platform!
#endif
}
template <size_t N>
bool BitSetIterator<N>::Iterator::operator==(const Iterator &other) const
{
return mOffset == other.mOffset && mBits == other.mBits;
}
template <size_t N>
bool BitSetIterator<N>::Iterator::operator!=(const Iterator &other) const
{
return !(*this == other);
}
template <size_t N>
unsigned long BitSetIterator<N>::Iterator::getNextBit()
{
static std::bitset<N> wordMask(std::numeric_limits<unsigned long>::max());
while (mOffset < N)
{
unsigned long wordBits = (mBits & wordMask).to_ulong();
if (wordBits != 0ul)
{
return ScanForward(wordBits) + mOffset;
}
mBits >>= BitsPerWord;
mOffset += BitsPerWord;
}
return 0;
}
// Helper to avoid needing to specify the template parameter size
template <size_t N>
BitSetIterator<N> IterateBitSet(const std::bitset<N> &bitset)
{
return BitSetIterator<N>(bitset);
}
} // angle
#endif // COMMON_BITSETITERATOR_H_

View File

@ -0,0 +1,91 @@
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// BitSetIteratorTest:
// Test the IterableBitSet class.
//
#include <gtest/gtest.h>
#include "common/BitSetIterator.h"
using namespace angle;
namespace
{
class BitSetIteratorTest : public testing::Test
{
protected:
std::bitset<40> mStateBits;
};
// Simple iterator test.
TEST_F(BitSetIteratorTest, Iterator)
{
std::set<unsigned long> originalValues;
originalValues.insert(2);
originalValues.insert(6);
originalValues.insert(8);
originalValues.insert(35);
for (unsigned long value : originalValues)
{
mStateBits.set(value);
}
std::set<unsigned long> readValues;
for (unsigned long bit : IterateBitSet(mStateBits))
{
EXPECT_EQ(1u, originalValues.count(bit));
EXPECT_EQ(0u, readValues.count(bit));
readValues.insert(bit);
}
EXPECT_EQ(originalValues.size(), readValues.size());
}
// Test an empty iterator.
TEST_F(BitSetIteratorTest, EmptySet)
{
// We don't use the FAIL gtest macro here since it returns immediately,
// causing an unreachable code warning in MSVS
bool sawBit = false;
for (unsigned long bit : IterateBitSet(mStateBits))
{
sawBit = true;
UNUSED_TRACE_VARIABLE(bit);
}
EXPECT_FALSE(sawBit);
}
// Test iterating a result of combining two bitsets.
TEST_F(BitSetIteratorTest, NonLValueBitset)
{
std::bitset<40> otherBits;
mStateBits.set(1);
mStateBits.set(2);
mStateBits.set(3);
mStateBits.set(4);
otherBits.set(0);
otherBits.set(1);
otherBits.set(3);
otherBits.set(5);
std::set<unsigned long> seenBits;
for (unsigned long bit : IterateBitSet(mStateBits & otherBits))
{
EXPECT_EQ(0u, seenBits.count(bit));
seenBits.insert(bit);
EXPECT_TRUE(mStateBits[bit]);
EXPECT_TRUE(otherBits[bit]);
}
EXPECT_EQ((mStateBits & otherBits).count(), seenBits.size());
}
} // anonymous namespace

View File

@ -47,10 +47,7 @@ struct Optional
mValid = false;
}
static Optional None()
{
return Optional();
}
static Optional Invalid() { return Optional(); }
bool valid() const { return mValid; }
const T &value() const { return mValue; }

View File

@ -18,7 +18,7 @@ TEST(OptionalTest, BasicInvalid)
{
Optional<int> testInvalid;
ASSERT_FALSE(testInvalid.valid());
ASSERT_EQ(Optional<int>::None(), testInvalid);
ASSERT_EQ(Optional<int>::Invalid(), testInvalid);
}
TEST(OptionalTest, BasicValid)
@ -26,7 +26,7 @@ TEST(OptionalTest, BasicValid)
Optional<int> testValid(3);
ASSERT_TRUE(testValid.valid());
ASSERT_EQ(3, testValid.value());
ASSERT_NE(Optional<int>::None(), testValid);
ASSERT_NE(Optional<int>::Invalid(), testValid);
}
TEST(OptionalTest, Copies)

View File

@ -69,13 +69,13 @@ inline int clampToInt(unsigned int x)
template <typename DestT, typename SrcT>
inline DestT clampCast(SrcT value)
{
// This assumes SrcT can properly represent DestT::min/max
// Unfortunately we can't use META_ASSERT without C++11 constexpr support
ASSERT(static_cast<DestT>(static_cast<SrcT>(std::numeric_limits<DestT>::min())) == std::numeric_limits<DestT>::min());
ASSERT(static_cast<DestT>(static_cast<SrcT>(std::numeric_limits<DestT>::max())) == std::numeric_limits<DestT>::max());
SrcT lo = static_cast<SrcT>(std::numeric_limits<DestT>::min());
SrcT hi = static_cast<SrcT>(std::numeric_limits<DestT>::max());
// This assumes SrcT can properly represent DestT::min/max. Checking this is a bit tricky,
// especially given floating point representations.
ASSERT(lo < hi);
return static_cast<DestT>(value > lo ? (value > hi ? hi : value) : lo);
}
@ -503,7 +503,6 @@ inline unsigned int averageFloat10(unsigned int a, unsigned int b)
return float32ToFloat10((float10ToFloat32(static_cast<unsigned short>(a)) + float10ToFloat32(static_cast<unsigned short>(b))) * 0.5f);
}
// Represents intervals of the type [a, b)
template <typename T>
struct Range
{
@ -542,6 +541,26 @@ struct Range
typedef Range<int> RangeI;
typedef Range<unsigned int> RangeUI;
struct IndexRange
{
IndexRange() : IndexRange(0, 0, 0) {}
IndexRange(size_t start_, size_t end_, size_t vertexIndexCount_)
: start(start_), end(end_), vertexIndexCount(vertexIndexCount_)
{
ASSERT(start <= end);
}
// Number of vertices in the range.
size_t vertexCount() const { return (end - start) + 1; }
// Inclusive range of indices that are not primitive restart
size_t start;
size_t end;
// Number of non-primitive restart indices
size_t vertexIndexCount;
};
// First, both normalized floating-point values are converted into 16-bit integer values.
// Then, the results are packed into the returned 32-bit unsigned integer.
// The first float value will be written to the least significant bits of the output;

View File

@ -71,15 +71,15 @@ class Matrix
{
ASSERT(columns() == m.rows());
size_t resultRows = rows();
size_t resultCols = m.columns();
unsigned int resultRows = rows();
unsigned int resultCols = m.columns();
Matrix<T> result(std::vector<T>(resultRows * resultCols), resultRows, resultCols);
for (size_t i = 0; i < resultRows; i++)
for (unsigned int i = 0; i < resultRows; i++)
{
for (size_t j = 0; j < resultCols; j++)
for (unsigned int j = 0; j < resultCols; j++)
{
T tmp = 0.0f;
for (size_t k = 0; k < columns(); k++)
for (unsigned int k = 0; k < columns(); k++)
tmp += at(i, k) * m(k, j);
result(i, j) = tmp;
}
@ -103,8 +103,8 @@ class Matrix
Matrix<T> compMult(const Matrix<T> &mat1) const
{
Matrix result(std::vector<T>(mElements.size()), size());
for (size_t i = 0; i < columns(); i++)
for (size_t j = 0; j < rows(); j++)
for (unsigned int i = 0; i < columns(); i++)
for (unsigned int j = 0; j < rows(); j++)
result(i, j) = at(i, j) * mat1(i, j);
return result;
@ -114,8 +114,8 @@ class Matrix
{
unsigned int cols = mat1.columns();
Matrix result(std::vector<T>(rows() * cols), rows(), cols);
for (size_t i = 0; i < rows(); i++)
for (size_t j = 0; j < cols; j++)
for (unsigned int i = 0; i < rows(); i++)
for (unsigned int j = 0; j < cols; j++)
result(i, j) = at(i, 0) * mat1(0, j);
return result;
@ -124,8 +124,8 @@ class Matrix
Matrix<T> transpose() const
{
Matrix result(std::vector<T>(mElements.size()), columns(), rows());
for (size_t i = 0; i < columns(); i++)
for (size_t j = 0; j < rows(); j++)
for (unsigned int i = 0; i < columns(); i++)
for (unsigned int j = 0; j < rows(); j++)
result(i, j) = at(j, i);
return result;
@ -330,8 +330,8 @@ class Matrix
Matrix<T> adjugateMatrix(cof.transpose());
T det = determinant();
Matrix<T> result(std::vector<T>(mElements.size()), rows(), columns());
for (size_t i = 0; i < rows(); i++)
for (size_t j = 0; j < columns(); j++)
for (unsigned int i = 0; i < rows(); i++)
for (unsigned int j = 0; j < columns(); j++)
result(i, j) = det ? adjugateMatrix(i, j) / det : T();
return result;

View File

@ -21,9 +21,9 @@ const unsigned int maxDimensions = 4;
TEST(MatrixUtilsTest, MatrixConstructorTest)
{
for (size_t i = minDimensions; i <= maxDimensions; i++)
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
{
for (size_t j = minDimensions; j <= maxDimensions; j++)
for (unsigned int j = minDimensions; j <= maxDimensions; j++)
{
unsigned int numElements = i * j;
Matrix<float> m(std::vector<float>(numElements, 1.0f), i, j);
@ -33,7 +33,7 @@ TEST(MatrixUtilsTest, MatrixConstructorTest)
}
}
for (size_t i = minDimensions; i <= maxDimensions; i++)
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
{
unsigned int numElements = i * i;
Matrix<float> m(std::vector<float>(numElements, 1.0f), i);
@ -45,7 +45,7 @@ TEST(MatrixUtilsTest, MatrixConstructorTest)
TEST(MatrixUtilsTest, MatrixCompMultTest)
{
for (size_t i = minDimensions; i <= maxDimensions; i++)
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
{
unsigned int numElements = i * i;
Matrix<float> m1(std::vector<float>(numElements, 2.0f), i);
@ -58,9 +58,9 @@ TEST(MatrixUtilsTest, MatrixCompMultTest)
TEST(MatrixUtilsTest, MatrixOuterProductTest)
{
for (size_t i = minDimensions; i <= maxDimensions; i++)
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
{
for (size_t j = minDimensions; j <= maxDimensions; j++)
for (unsigned int j = minDimensions; j <= maxDimensions; j++)
{
unsigned int numElements = i * j;
Matrix<float> m1(std::vector<float>(numElements, 2.0f), i, 1);
@ -77,9 +77,9 @@ TEST(MatrixUtilsTest, MatrixOuterProductTest)
TEST(MatrixUtilsTest, MatrixTransposeTest)
{
for (size_t i = minDimensions; i <= maxDimensions; i++)
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
{
for (size_t j = minDimensions; j <= maxDimensions; j++)
for (unsigned int j = minDimensions; j <= maxDimensions; j++)
{
unsigned int numElements = i * j;
Matrix<float> m1(std::vector<float>(numElements, 2.0f), i, j);
@ -97,7 +97,7 @@ TEST(MatrixUtilsTest, MatrixTransposeTest)
TEST(MatrixUtilsTest, MatrixDeterminantTest)
{
for (size_t i = minDimensions; i <= maxDimensions; i++)
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
{
unsigned int numElements = i * i;
Matrix<float> m(std::vector<float>(numElements, 2.0f), i);
@ -176,7 +176,7 @@ TEST(MatrixUtilsTest, 4x4MatrixInverseTest)
Matrix<float> result = inputMatrix * inputMatrix.inverse();
std::vector<float> resultElements = result.elements();
const float floatFaultTolarance = 0.00001f;
for (size_t i = 0; i < numElements; i++)
for (unsigned int i = 0; i < numElements; i++)
EXPECT_NEAR(resultElements[i], identityMatrix[i], floatFaultTolarance);
}

View File

@ -19,6 +19,78 @@
# include <windows.graphics.display.h>
#endif
namespace
{
template <class IndexType>
gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
size_t count,
bool primitiveRestartEnabled,
GLuint primitiveRestartIndex)
{
ASSERT(count > 0);
IndexType minIndex = 0;
IndexType maxIndex = 0;
size_t nonPrimitiveRestartIndices = 0;
if (primitiveRestartEnabled)
{
// Find the first non-primitive restart index to initialize the min and max values
size_t i = 0;
for (; i < count; i++)
{
if (indices[i] != primitiveRestartIndex)
{
minIndex = indices[i];
maxIndex = indices[i];
nonPrimitiveRestartIndices++;
break;
}
}
// Loop over the rest of the indices
for (; i < count; i++)
{
if (indices[i] != primitiveRestartIndex)
{
if (minIndex > indices[i])
{
minIndex = indices[i];
}
if (maxIndex < indices[i])
{
maxIndex = indices[i];
}
nonPrimitiveRestartIndices++;
}
}
}
else
{
minIndex = indices[0];
maxIndex = indices[0];
nonPrimitiveRestartIndices = count;
for (size_t i = 1; i < count; i++)
{
if (minIndex > indices[i])
{
minIndex = indices[i];
}
if (maxIndex < indices[i])
{
maxIndex = indices[i];
}
}
}
return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
nonPrimitiveRestartIndices);
}
} // anonymous namespace
namespace gl
{
@ -399,30 +471,44 @@ GLenum LayerIndexToCubeMapTextureTarget(size_t index)
return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
}
template <class IndexType>
static RangeUI ComputeTypedIndexRange(const IndexType *indices, GLsizei count)
{
ASSERT(count > 0);
IndexType minIndex = indices[0];
IndexType maxIndex = indices[0];
for (GLsizei i = 1; i < count; i++)
{
if (minIndex > indices[i]) minIndex = indices[i];
if (maxIndex < indices[i]) maxIndex = indices[i];
}
return RangeUI(static_cast<GLuint>(minIndex), static_cast<GLuint>(maxIndex));
}
RangeUI ComputeIndexRange(GLenum indexType, const GLvoid *indices, GLsizei count)
IndexRange ComputeIndexRange(GLenum indexType,
const GLvoid *indices,
size_t count,
bool primitiveRestartEnabled)
{
switch (indexType)
{
case GL_UNSIGNED_BYTE: return ComputeTypedIndexRange(static_cast<const GLubyte*>(indices), count);
case GL_UNSIGNED_SHORT: return ComputeTypedIndexRange(static_cast<const GLushort*>(indices), count);
case GL_UNSIGNED_INT: return ComputeTypedIndexRange(static_cast<const GLuint*>(indices), count);
default: UNREACHABLE(); return RangeUI(0, 0);
case GL_UNSIGNED_BYTE:
return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
primitiveRestartEnabled,
GetPrimitiveRestartIndex(indexType));
case GL_UNSIGNED_SHORT:
return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
primitiveRestartEnabled,
GetPrimitiveRestartIndex(indexType));
case GL_UNSIGNED_INT:
return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
primitiveRestartEnabled,
GetPrimitiveRestartIndex(indexType));
default:
UNREACHABLE();
return IndexRange();
}
}
GLuint GetPrimitiveRestartIndex(GLenum indexType)
{
switch (indexType)
{
case GL_UNSIGNED_BYTE:
return 0xFF;
case GL_UNSIGNED_SHORT:
return 0xFFFF;
case GL_UNSIGNED_INT:
return 0xFFFFFFFF;
default:
UNREACHABLE();
return 0;
}
}
@ -555,6 +641,99 @@ std::string ParseUniformName(const std::string &name, size_t *outSubscript)
}
namespace egl
{
static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
"Unexpected EGL cube map enum value.");
static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
"Unexpected EGL cube map enum value.");
static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
"Unexpected EGL cube map enum value.");
static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
"Unexpected EGL cube map enum value.");
static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
"Unexpected EGL cube map enum value.");
bool IsCubeMapTextureTarget(EGLenum target)
{
return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
}
size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
{
ASSERT(IsCubeMapTextureTarget(target));
return target - static_cast<size_t>(FirstCubeMapTextureTarget);
}
EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
{
ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
}
bool IsTextureTarget(EGLenum target)
{
switch (target)
{
case EGL_GL_TEXTURE_2D_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
case EGL_GL_TEXTURE_3D_KHR:
return true;
default:
return false;
}
}
bool IsRenderbufferTarget(EGLenum target)
{
return target == EGL_GL_RENDERBUFFER_KHR;
}
}
namespace egl_gl
{
GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
{
ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
}
GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget)
{
switch (eglTarget)
{
case EGL_GL_TEXTURE_2D_KHR:
return GL_TEXTURE_2D;
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
return EGLCubeMapTargetToGLCubeMapTarget(eglTarget);
case EGL_GL_TEXTURE_3D_KHR:
return GL_TEXTURE_3D;
default:
UNREACHABLE();
return GL_NONE;
}
}
GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
{
return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
}
}
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
std::string getTempPath()
{

View File

@ -9,6 +9,9 @@
#ifndef COMMON_UTILITIES_H_
#define COMMON_UTILITIES_H_
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include "angle_gl.h"
#include <string>
#include <math.h>
@ -47,7 +50,15 @@ GLenum LayerIndexToCubeMapTextureTarget(size_t index);
// set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid.
std::string ParseUniformName(const std::string &name, size_t *outSubscript);
RangeUI ComputeIndexRange(GLenum indexType, const GLvoid *indices, GLsizei count);
// Find the range of index values in the provided indices pointer. Primitive restart indices are
// only counted in the range if primitive restart is disabled.
IndexRange ComputeIndexRange(GLenum indexType,
const GLvoid *indices,
size_t count,
bool primitiveRestartEnabled);
// Get the primitive restart index value for the given index type.
GLuint GetPrimitiveRestartIndex(GLenum indexType);
bool IsTriangleMode(GLenum drawMode);
@ -59,6 +70,24 @@ template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(
}
namespace egl
{
static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR;
bool IsCubeMapTextureTarget(EGLenum target);
size_t CubeMapTextureTargetToLayerIndex(EGLenum target);
EGLenum LayerIndexToCubeMapTextureTarget(size_t index);
bool IsTextureTarget(EGLenum target);
bool IsRenderbufferTarget(EGLenum target);
}
namespace egl_gl
{
GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget);
GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget);
GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer);
}
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
std::string getTempPath();
void writeFile(const char* path, const void* data, size_t size);

View File

@ -15,8 +15,9 @@
'../include/GLES2/gl2ext.h',
'../include/GLES2/gl2platform.h',
'../include/GLES3/gl3.h',
'../include/GLES3/gl3ext.h',
'../include/GLES3/gl3platform.h',
'../include/GLES3/gl31.h',
'../include/GLES3/gl32.h',
'../include/GLSLANG/ShaderLang.h',
'../include/GLSLANG/ShaderVars.h',
'../include/KHR/khrplatform.h',
@ -156,6 +157,8 @@
'compiler/translator/BuiltInFunctionEmulatorHLSL.h',
'compiler/translator/OutputHLSL.cpp',
'compiler/translator/OutputHLSL.h',
'compiler/translator/RemoveDynamicIndexing.cpp',
'compiler/translator/RemoveDynamicIndexing.h',
'compiler/translator/RemoveSwitchFallThrough.cpp',
'compiler/translator/RemoveSwitchFallThrough.h',
'compiler/translator/RewriteElseBlocks.cpp',
@ -217,18 +220,6 @@
'type': 'static_library',
'includes': [ '../build/common_defines.gypi', ],
'sources': [ '<@(angle_preprocessor_sources)', ],
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'msvs_application_type_revision' : '<(angle_build_winrt_app_type_revision)',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
},
{
'target_name': 'translator_lib',
@ -259,15 +250,6 @@
},
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'msvs_application_type_revision' : '<(angle_build_winrt_app_type_revision)',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
['angle_enable_hlsl==1',
{
'defines':
@ -308,18 +290,6 @@
'compiler/translator/ShaderLang.cpp',
'compiler/translator/ShaderVars.cpp'
],
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'msvs_application_type_revision' : '<(angle_build_winrt_app_type_revision)',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
},
{
@ -348,18 +318,6 @@
'compiler/translator/ShaderLang.cpp',
'compiler/translator/ShaderVars.cpp'
],
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'msvs_application_type_revision' : '<(angle_build_winrt_app_type_revision)',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
},
],
}

View File

@ -113,10 +113,6 @@ std::string Diagnostics::message(ID id)
return "invalid file number";
case PP_INVALID_LINE_DIRECTIVE:
return "invalid line directive";
case PP_INVALID_PRAGMA:
return "invalid pragma";
case PP_INVALID_PRAGMA_VALUE:
return "invalid pragma value, must be 'on' or 'off'";
case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3:
return "extension directive must occur before any non-preprocessor tokens in ESSL3";
// Errors end.

View File

@ -64,8 +64,6 @@ class Diagnostics
PP_INVALID_LINE_NUMBER,
PP_INVALID_FILE_NUMBER,
PP_INVALID_LINE_DIRECTIVE,
PP_INVALID_PRAGMA,
PP_INVALID_PRAGMA_VALUE,
PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3,
PP_ERROR_END,

View File

@ -141,71 +141,6 @@ bool isMacroPredefined(const std::string &name,
namespace pp
{
class DefinedParser : public Lexer
{
public:
DefinedParser(Lexer *lexer,
const MacroSet *macroSet,
Diagnostics *diagnostics)
: mLexer(lexer),
mMacroSet(macroSet),
mDiagnostics(diagnostics)
{
}
protected:
virtual void lex(Token *token)
{
const char kDefined[] = "defined";
mLexer->lex(token);
if (token->type != Token::IDENTIFIER)
return;
if (token->text != kDefined)
return;
bool paren = false;
mLexer->lex(token);
if (token->type == '(')
{
paren = true;
mLexer->lex(token);
}
if (token->type != Token::IDENTIFIER)
{
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
token->location, token->text);
skipUntilEOD(mLexer, token);
return;
}
MacroSet::const_iterator iter = mMacroSet->find(token->text);
std::string expression = iter != mMacroSet->end() ? "1" : "0";
if (paren)
{
mLexer->lex(token);
if (token->type != ')')
{
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
token->location, token->text);
skipUntilEOD(mLexer, token);
return;
}
}
// We have a valid defined operator.
// Convert the current token into a CONST_INT token.
token->type = Token::CONST_INT;
token->text = expression;
}
private:
Lexer *mLexer;
const MacroSet *mMacroSet;
Diagnostics *mDiagnostics;
};
DirectiveParser::DirectiveParser(Tokenizer *tokenizer,
MacroSet *macroSet,
Diagnostics *diagnostics,
@ -631,8 +566,7 @@ void DirectiveParser::parsePragma(Token *token)
break;
case PRAGMA_VALUE:
value = token->text;
// Pragma value validation is handled in DirectiveHandler::handlePragma
// because the proper pragma value is dependent on the pragma name.
valid = valid && (token->type == Token::IDENTIFIER);
break;
case RIGHT_PAREN:
valid = valid && (token->type == ')');
@ -649,7 +583,7 @@ void DirectiveParser::parsePragma(Token *token)
(state == RIGHT_PAREN + 1)); // With value.
if (!valid)
{
mDiagnostics->report(Diagnostics::PP_INVALID_PRAGMA,
mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA,
token->location, name);
}
else if (state > PRAGMA_NAME) // Do not notify for empty pragma.
@ -822,6 +756,7 @@ void DirectiveParser::parseVersion(Token *token)
{
mDirectiveHandler->handleVersion(token->location, version);
mShaderVersion = version;
PredefineMacro(mMacroSet, "__VERSION__", version);
}
}
@ -839,7 +774,7 @@ void DirectiveParser::parseLine(Token *token)
int line = 0, file = 0;
int state = LINE_NUMBER;
MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics);
MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false);
macroExpander.lex(token);
while ((token->type != '\n') && (token->type != Token::LAST))
{
@ -954,12 +889,10 @@ int DirectiveParser::parseExpressionIf(Token *token)
assert((getDirective(token) == DIRECTIVE_IF) ||
(getDirective(token) == DIRECTIVE_ELIF));
DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics);
MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics);
MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true);
ExpressionParser expressionParser(&macroExpander, mDiagnostics);
int expression = 0;
macroExpander.lex(token);
expressionParser.parse(token, &expression);
// Check if there are tokens after #if expression.

View File

@ -27,7 +27,7 @@ class DirectiveParser : public Lexer
Diagnostics *diagnostics,
DirectiveHandler *directiveHandler);
virtual void lex(Token *token);
void lex(Token *token) override;
private:
PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser);

View File

@ -110,6 +110,7 @@ typedef __int64 YYSTYPE;
#include <stdint.h>
typedef intmax_t YYSTYPE;
#endif // _MSC_VER
#define YYENABLE_NLS 0
#define YYLTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_TRIVIAL 1
@ -122,6 +123,13 @@ struct Context
pp::Lexer* lexer;
pp::Token* token;
int* result;
void startIgnoreErrors() { ++ignoreErrors; }
void endIgnoreErrors() { --ignoreErrors; }
bool isIgnoringErrors() { return ignoreErrors > 0; }
int ignoreErrors;
};
} // namespace
@ -162,15 +170,16 @@ extern int ppdebug;
enum yytokentype
{
TOK_CONST_INT = 258,
TOK_OP_OR = 259,
TOK_OP_AND = 260,
TOK_OP_EQ = 261,
TOK_OP_NE = 262,
TOK_OP_LE = 263,
TOK_OP_GE = 264,
TOK_OP_LEFT = 265,
TOK_OP_RIGHT = 266,
TOK_UNARY = 267
TOK_IDENTIFIER = 259,
TOK_OP_OR = 260,
TOK_OP_AND = 261,
TOK_OP_EQ = 262,
TOK_OP_NE = 263,
TOK_OP_LE = 264,
TOK_OP_GE = 265,
TOK_OP_LEFT = 266,
TOK_OP_RIGHT = 267,
TOK_UNARY = 268
};
#endif
@ -429,23 +438,23 @@ union yyalloc
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 14
#define YYFINAL 15
/* YYLAST -- Last index in YYTABLE. */
#define YYLAST 175
#define YYLAST 176
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 27
#define YYNTOKENS 28
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 3
#define YYNNTS 5
/* YYNRULES -- Number of rules. */
#define YYNRULES 26
#define YYNRULES 29
/* YYNSTATES -- Number of states. */
#define YYNSTATES 52
#define YYNSTATES 55
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 267
#define YYMAXUTOK 268
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@ -457,16 +466,16 @@ static const yytype_uint8 yytranslate[] =
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 23, 2, 2, 2, 21, 8, 2,
25, 26, 19, 17, 2, 18, 2, 20, 2, 2,
2, 2, 2, 24, 2, 2, 2, 22, 9, 2,
26, 27, 20, 18, 2, 19, 2, 21, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
11, 2, 12, 2, 2, 2, 2, 2, 2, 2,
12, 2, 13, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 7, 2, 2, 2, 2, 2,
2, 2, 2, 2, 8, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 6, 2, 24, 2, 2, 2,
2, 2, 2, 2, 7, 2, 25, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@ -480,16 +489,16 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 9, 10, 13, 14, 15, 16, 22
5, 6, 10, 11, 14, 15, 16, 17, 23
};
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
static const yytype_uint16 yyrline[] =
{
0, 97, 97, 104, 105, 108, 111, 114, 117, 120,
123, 126, 129, 132, 135, 138, 141, 144, 147, 150,
163, 176, 179, 182, 185, 188, 191
0, 106, 106, 113, 114, 124, 124, 145, 145, 166,
169, 172, 175, 178, 181, 184, 187, 190, 193, 196,
199, 202, 205, 224, 243, 246, 249, 252, 255, 258
};
#endif
@ -498,11 +507,11 @@ static const yytype_uint8 yyrline[] =
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
"$end", "error", "$undefined", "TOK_CONST_INT", "TOK_OP_OR",
"TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_EQ", "TOK_OP_NE", "'<'",
"'>'", "TOK_OP_LE", "TOK_OP_GE", "TOK_OP_LEFT", "TOK_OP_RIGHT", "'+'",
"'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('", "')'",
"$accept", "input", "expression", YY_NULLPTR
"$end", "error", "$undefined", "TOK_CONST_INT", "TOK_IDENTIFIER",
"TOK_OP_OR", "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_EQ", "TOK_OP_NE",
"'<'", "'>'", "TOK_OP_LE", "TOK_OP_GE", "TOK_OP_LEFT", "TOK_OP_RIGHT",
"'+'", "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('",
"')'", "$accept", "input", "expression", "$@1", "$@2", YY_NULLPTR
};
#endif
@ -511,16 +520,16 @@ static const char *const yytname[] =
(internal) symbol number NUM (which must be that of a token). */
static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 124, 94, 38, 261,
262, 60, 62, 263, 264, 265, 266, 43, 45, 42,
47, 37, 267, 33, 126, 40, 41
0, 256, 257, 258, 259, 260, 261, 124, 94, 38,
262, 263, 60, 62, 264, 265, 266, 267, 43, 45,
42, 47, 37, 268, 33, 126, 40, 41
};
# endif
#define YYPACT_NINF -11
#define YYPACT_NINF -12
#define yypact_value_is_default(Yystate) \
(!!((Yystate) == (-11)))
(!!((Yystate) == (-12)))
#define YYTABLE_NINF -1
@ -531,12 +540,12 @@ static const yytype_uint16 yytoknum[] =
STATE-NUM. */
static const yytype_int16 yypact[] =
{
46, -11, 46, 46, 46, 46, 46, 12, 68, -11,
-11, -11, -11, 27, -11, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, -11, 85, 101, 116, 130, 143, 154,
154, -10, -10, -10, -10, 37, 37, 31, 31, -11,
-11, -11
31, -12, -12, 31, 31, 31, 31, 31, 51, 76,
-12, -12, -12, -12, 53, -12, -12, -12, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, -12, 31, 31, 124, 138, 26,
149, 149, -11, -11, -11, -11, 154, 154, -8, -8,
-12, -12, -12, 93, 109
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@ -544,24 +553,24 @@ static const yytype_int16 yypact[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
0, 3, 0, 0, 0, 0, 0, 0, 2, 25,
24, 22, 23, 0, 1, 0, 0, 0, 0, 0,
0, 3, 4, 0, 0, 0, 0, 0, 0, 2,
28, 27, 25, 26, 0, 1, 5, 7, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 26, 4, 5, 6, 7, 8, 10,
9, 14, 13, 12, 11, 16, 15, 18, 17, 21,
20, 19
0, 0, 0, 0, 29, 0, 0, 9, 10, 11,
13, 12, 17, 16, 15, 14, 19, 18, 21, 20,
24, 23, 22, 6, 8
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
-11, -11, -2
-12, -12, -3, -12, -12
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
-1, 7, 8
-1, 8, 9, 35, 36
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@ -569,74 +578,74 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] =
{
9, 10, 11, 12, 13, 26, 27, 28, 29, 30,
31, 32, 14, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 1,
30, 31, 32, 33, 28, 29, 30, 31, 32, 0,
0, 0, 0, 2, 3, 0, 0, 0, 0, 4,
5, 6, 15, 16, 17, 18, 19, 20, 21, 22,
10, 11, 12, 13, 14, 27, 28, 29, 30, 31,
32, 33, 31, 32, 33, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 0, 53, 54, 1, 2, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 3,
4, 15, 0, 0, 0, 5, 6, 7, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 0, 0, 0, 0,
34, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32
33, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 29, 30, 31, 32, 33
};
static const yytype_int8 yycheck[] =
{
2, 3, 4, 5, 6, 15, 16, 17, 18, 19,
20, 21, 0, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 3,
19, 20, 21, 26, 17, 18, 19, 20, 21, -1,
-1, -1, -1, 17, 18, -1, -1, -1, -1, 23,
24, 25, 4, 5, 6, 7, 8, 9, 10, 11,
3, 4, 5, 6, 7, 16, 17, 18, 19, 20,
21, 22, 20, 21, 22, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, -1, 35, 36, 3, 4, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 18,
19, 0, -1, -1, -1, 24, 25, 26, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, -1, -1, -1, -1,
27, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21
22, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 18, 19, 20, 21, 22
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
0, 3, 17, 18, 23, 24, 25, 28, 29, 29,
29, 29, 29, 29, 0, 4, 5, 6, 7, 8,
0, 3, 4, 18, 19, 24, 25, 26, 29, 30,
30, 30, 30, 30, 30, 0, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 26, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29
19, 20, 21, 22, 27, 31, 32, 30, 30, 30,
30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
30, 30, 30, 30, 30
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
0, 27, 28, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29
0, 28, 29, 30, 30, 31, 30, 32, 30, 30,
30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
30, 30, 30, 30, 30, 30, 30, 30, 30, 30
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
0, 2, 1, 1, 3, 3, 3, 3, 3, 3,
0, 2, 1, 1, 1, 0, 4, 0, 4, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 2, 2, 2, 2, 3
3, 3, 3, 3, 3, 2, 2, 2, 2, 3
};
@ -1330,7 +1339,14 @@ yyreduce:
case 4:
{
(yyval) = (yyvsp[-2]) || (yyvsp[0]);
if (!context->isIgnoringErrors())
{
// This rule should be applied right after the token is lexed, so we can
// refer to context->token in the error message.
context->diagnostics->report(pp::Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
context->token->location, context->token->text);
}
(yyval) = (yyvsp[0]);
}
break;
@ -1338,7 +1354,15 @@ yyreduce:
case 5:
{
(yyval) = (yyvsp[-2]) && (yyvsp[0]);
if ((yyvsp[-1]) != 0)
{
// Ignore errors in the short-circuited part of the expression.
// ESSL3.00 section 3.4:
// If an operand is not evaluated, the presence of undefined identifiers
// in the operand will not cause an error.
// Unevaluated division by zero should not cause an error either.
context->startIgnoreErrors();
}
}
break;
@ -1346,7 +1370,15 @@ yyreduce:
case 6:
{
(yyval) = (yyvsp[-2]) | (yyvsp[0]);
if ((yyvsp[-3]) != 0)
{
context->endIgnoreErrors();
(yyval) = static_cast<YYSTYPE>(1);
}
else
{
(yyval) = (yyvsp[-3]) || (yyvsp[0]);
}
}
break;
@ -1354,7 +1386,15 @@ yyreduce:
case 7:
{
(yyval) = (yyvsp[-2]) ^ (yyvsp[0]);
if ((yyvsp[-1]) == 0)
{
// Ignore errors in the short-circuited part of the expression.
// ESSL3.00 section 3.4:
// If an operand is not evaluated, the presence of undefined identifiers
// in the operand will not cause an error.
// Unevaluated division by zero should not cause an error either.
context->startIgnoreErrors();
}
}
break;
@ -1362,7 +1402,15 @@ yyreduce:
case 8:
{
(yyval) = (yyvsp[-2]) & (yyvsp[0]);
if ((yyvsp[-3]) == 0)
{
context->endIgnoreErrors();
(yyval) = static_cast<YYSTYPE>(0);
}
else
{
(yyval) = (yyvsp[-3]) && (yyvsp[0]);
}
}
break;
@ -1370,7 +1418,7 @@ yyreduce:
case 9:
{
(yyval) = (yyvsp[-2]) != (yyvsp[0]);
(yyval) = (yyvsp[-2]) | (yyvsp[0]);
}
break;
@ -1378,7 +1426,7 @@ yyreduce:
case 10:
{
(yyval) = (yyvsp[-2]) == (yyvsp[0]);
(yyval) = (yyvsp[-2]) ^ (yyvsp[0]);
}
break;
@ -1386,7 +1434,7 @@ yyreduce:
case 11:
{
(yyval) = (yyvsp[-2]) >= (yyvsp[0]);
(yyval) = (yyvsp[-2]) & (yyvsp[0]);
}
break;
@ -1394,7 +1442,7 @@ yyreduce:
case 12:
{
(yyval) = (yyvsp[-2]) <= (yyvsp[0]);
(yyval) = (yyvsp[-2]) != (yyvsp[0]);
}
break;
@ -1402,7 +1450,7 @@ yyreduce:
case 13:
{
(yyval) = (yyvsp[-2]) > (yyvsp[0]);
(yyval) = (yyvsp[-2]) == (yyvsp[0]);
}
break;
@ -1410,7 +1458,7 @@ yyreduce:
case 14:
{
(yyval) = (yyvsp[-2]) < (yyvsp[0]);
(yyval) = (yyvsp[-2]) >= (yyvsp[0]);
}
break;
@ -1418,7 +1466,7 @@ yyreduce:
case 15:
{
(yyval) = (yyvsp[-2]) >> (yyvsp[0]);
(yyval) = (yyvsp[-2]) <= (yyvsp[0]);
}
break;
@ -1426,7 +1474,7 @@ yyreduce:
case 16:
{
(yyval) = (yyvsp[-2]) << (yyvsp[0]);
(yyval) = (yyvsp[-2]) > (yyvsp[0]);
}
break;
@ -1434,7 +1482,7 @@ yyreduce:
case 17:
{
(yyval) = (yyvsp[-2]) - (yyvsp[0]);
(yyval) = (yyvsp[-2]) < (yyvsp[0]);
}
break;
@ -1442,7 +1490,7 @@ yyreduce:
case 18:
{
(yyval) = (yyvsp[-2]) + (yyvsp[0]);
(yyval) = (yyvsp[-2]) >> (yyvsp[0]);
}
break;
@ -1450,17 +1498,7 @@ yyreduce:
case 19:
{
if ((yyvsp[0]) == 0) {
std::ostringstream stream;
stream << (yyvsp[-2]) << " % " << (yyvsp[0]);
std::string text = stream.str();
context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
context->token->location,
text.c_str());
YYABORT;
} else {
(yyval) = (yyvsp[-2]) % (yyvsp[0]);
}
(yyval) = (yyvsp[-2]) << (yyvsp[0]);
}
break;
@ -1468,17 +1506,7 @@ yyreduce:
case 20:
{
if ((yyvsp[0]) == 0) {
std::ostringstream stream;
stream << (yyvsp[-2]) << " / " << (yyvsp[0]);
std::string text = stream.str();
context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
context->token->location,
text.c_str());
YYABORT;
} else {
(yyval) = (yyvsp[-2]) / (yyvsp[0]);
}
(yyval) = (yyvsp[-2]) - (yyvsp[0]);
}
break;
@ -1486,7 +1514,7 @@ yyreduce:
case 21:
{
(yyval) = (yyvsp[-2]) * (yyvsp[0]);
(yyval) = (yyvsp[-2]) + (yyvsp[0]);
}
break;
@ -1494,7 +1522,23 @@ yyreduce:
case 22:
{
(yyval) = ! (yyvsp[0]);
if ((yyvsp[0]) == 0)
{
if (!context->isIgnoringErrors())
{
std::ostringstream stream;
stream << (yyvsp[-2]) << " % " << (yyvsp[0]);
std::string text = stream.str();
context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
context->token->location,
text.c_str());
}
(yyval) = static_cast<YYSTYPE>(0);
}
else
{
(yyval) = (yyvsp[-2]) % (yyvsp[0]);
}
}
break;
@ -1502,7 +1546,23 @@ yyreduce:
case 23:
{
(yyval) = ~ (yyvsp[0]);
if ((yyvsp[0]) == 0)
{
if (!context->isIgnoringErrors())
{
std::ostringstream stream;
stream << (yyvsp[-2]) << " / " << (yyvsp[0]);
std::string text = stream.str();
context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
context->token->location,
text.c_str());
}
(yyval) = static_cast<YYSTYPE>(0);
}
else
{
(yyval) = (yyvsp[-2]) / (yyvsp[0]);
}
}
break;
@ -1510,7 +1570,7 @@ yyreduce:
case 24:
{
(yyval) = - (yyvsp[0]);
(yyval) = (yyvsp[-2]) * (yyvsp[0]);
}
break;
@ -1518,13 +1578,37 @@ yyreduce:
case 25:
{
(yyval) = + (yyvsp[0]);
(yyval) = ! (yyvsp[0]);
}
break;
case 26:
{
(yyval) = ~ (yyvsp[0]);
}
break;
case 27:
{
(yyval) = - (yyvsp[0]);
}
break;
case 28:
{
(yyval) = + (yyvsp[0]);
}
break;
case 29:
{
(yyval) = (yyvsp[-1]);
}
@ -1765,9 +1849,11 @@ yyreturn:
int yylex(YYSTYPE *lvalp, Context *context)
{
pp::Token *token = context->token;
context->lexer->lex(token);
int type = 0;
pp::Token *token = context->token;
switch (token->type)
{
case pp::Token::CONST_INT: {
@ -1781,6 +1867,10 @@ int yylex(YYSTYPE *lvalp, Context *context)
type = TOK_CONST_INT;
break;
}
case pp::Token::IDENTIFIER:
*lvalp = static_cast<YYSTYPE>(-1);
type = TOK_IDENTIFIER;
break;
case pp::Token::OP_OR:
type = TOK_OP_OR;
break;
@ -1826,10 +1916,6 @@ int yylex(YYSTYPE *lvalp, Context *context)
break;
}
// Advance to the next token if the current one is valid.
if (type != 0)
context->lexer->lex(token);
return type;
}
@ -1855,6 +1941,7 @@ bool ExpressionParser::parse(Token *token, int *result)
context.lexer = mLexer;
context.token = token;
context.result = result;
context.ignoreErrors = 0;
int ret = yyparse(&context);
switch (ret)
{

View File

@ -52,6 +52,7 @@ typedef __int64 YYSTYPE;
#include <stdint.h>
typedef intmax_t YYSTYPE;
#endif // _MSC_VER
#define YYENABLE_NLS 0
#define YYLTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_TRIVIAL 1
@ -64,6 +65,13 @@ struct Context
pp::Lexer* lexer;
pp::Token* token;
int* result;
void startIgnoreErrors() { ++ignoreErrors; }
void endIgnoreErrors() { --ignoreErrors; }
bool isIgnoringErrors() { return ignoreErrors > 0; }
int ignoreErrors;
};
} // namespace
%}
@ -79,6 +87,7 @@ static void yyerror(Context* context, const char* reason);
%}
%token TOK_CONST_INT
%token TOK_IDENTIFIER
%left TOK_OP_OR
%left TOK_OP_AND
%left '|'
@ -102,11 +111,57 @@ input
expression
: TOK_CONST_INT
| expression TOK_OP_OR expression {
$$ = $1 || $3;
| TOK_IDENTIFIER {
if (!context->isIgnoringErrors())
{
// This rule should be applied right after the token is lexed, so we can
// refer to context->token in the error message.
context->diagnostics->report(pp::Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
context->token->location, context->token->text);
}
$$ = $1;
}
| expression TOK_OP_AND expression {
$$ = $1 && $3;
| expression TOK_OP_OR {
if ($1 != 0)
{
// Ignore errors in the short-circuited part of the expression.
// ESSL3.00 section 3.4:
// If an operand is not evaluated, the presence of undefined identifiers
// in the operand will not cause an error.
// Unevaluated division by zero should not cause an error either.
context->startIgnoreErrors();
}
} expression {
if ($1 != 0)
{
context->endIgnoreErrors();
$$ = static_cast<YYSTYPE>(1);
}
else
{
$$ = $1 || $4;
}
}
| expression TOK_OP_AND {
if ($1 == 0)
{
// Ignore errors in the short-circuited part of the expression.
// ESSL3.00 section 3.4:
// If an operand is not evaluated, the presence of undefined identifiers
// in the operand will not cause an error.
// Unevaluated division by zero should not cause an error either.
context->startIgnoreErrors();
}
} expression {
if ($1 == 0)
{
context->endIgnoreErrors();
$$ = static_cast<YYSTYPE>(0);
}
else
{
$$ = $1 && $4;
}
}
| expression '|' expression {
$$ = $1 | $3;
@ -148,28 +203,40 @@ expression
$$ = $1 + $3;
}
| expression '%' expression {
if ($3 == 0) {
std::ostringstream stream;
stream << $1 << " % " << $3;
std::string text = stream.str();
context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
context->token->location,
text.c_str());
YYABORT;
} else {
if ($3 == 0)
{
if (!context->isIgnoringErrors())
{
std::ostringstream stream;
stream << $1 << " % " << $3;
std::string text = stream.str();
context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
context->token->location,
text.c_str());
}
$$ = static_cast<YYSTYPE>(0);
}
else
{
$$ = $1 % $3;
}
}
| expression '/' expression {
if ($3 == 0) {
std::ostringstream stream;
stream << $1 << " / " << $3;
std::string text = stream.str();
context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
context->token->location,
text.c_str());
YYABORT;
} else {
if ($3 == 0)
{
if (!context->isIgnoringErrors())
{
std::ostringstream stream;
stream << $1 << " / " << $3;
std::string text = stream.str();
context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
context->token->location,
text.c_str());
}
$$ = static_cast<YYSTYPE>(0);
}
else
{
$$ = $1 / $3;
}
}
@ -197,9 +264,11 @@ expression
int yylex(YYSTYPE *lvalp, Context *context)
{
pp::Token *token = context->token;
context->lexer->lex(token);
int type = 0;
pp::Token *token = context->token;
switch (token->type)
{
case pp::Token::CONST_INT: {
@ -213,6 +282,10 @@ int yylex(YYSTYPE *lvalp, Context *context)
type = TOK_CONST_INT;
break;
}
case pp::Token::IDENTIFIER:
*lvalp = static_cast<YYSTYPE>(-1);
type = TOK_IDENTIFIER;
break;
case pp::Token::OP_OR:
type = TOK_OP_OR;
break;
@ -258,10 +331,6 @@ int yylex(YYSTYPE *lvalp, Context *context)
break;
}
// Advance to the next token if the current one is valid.
if (type != 0)
context->lexer->lex(token);
return type;
}
@ -287,6 +356,7 @@ bool ExpressionParser::parse(Token *token, int *result)
context.lexer = mLexer;
context.token = token;
context.result = result;
context.ignoreErrors = 0;
int ret = yyparse(&context);
switch (ret)
{

View File

@ -29,13 +29,75 @@ Input::Input(size_t count, const char *const string[], const int length[]) :
}
}
size_t Input::read(char *buf, size_t maxSize)
const char *Input::skipChar()
{
// This function should only be called when there is a character to skip.
assert(mReadLoc.cIndex < mLength[mReadLoc.sIndex]);
++mReadLoc.cIndex;
if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
{
++mReadLoc.sIndex;
mReadLoc.cIndex = 0;
}
if (mReadLoc.sIndex >= mCount)
{
return nullptr;
}
return mString[mReadLoc.sIndex] + mReadLoc.cIndex;
}
size_t Input::read(char *buf, size_t maxSize, int *lineNo)
{
size_t nRead = 0;
while ((nRead < maxSize) && (mReadLoc.sIndex < mCount))
// The previous call to read might have stopped copying the string when encountering a line
// continuation. Check for this possibility first.
if (mReadLoc.sIndex < mCount && maxSize > 0)
{
const char *c = mString[mReadLoc.sIndex] + mReadLoc.cIndex;
if ((*c) == '\\')
{
c = skipChar();
if (c != nullptr && (*c) == '\n')
{
// Line continuation of backslash + newline.
skipChar();
++(*lineNo);
}
else if (c != nullptr && (*c) == '\r')
{
// Line continuation. Could be backslash + '\r\n' or just backslash + '\r'.
c = skipChar();
if (c != nullptr && (*c) == '\n')
{
skipChar();
}
++(*lineNo);
}
else
{
// Not line continuation, so write the skipped backslash to buf.
*buf = '\\';
++nRead;
}
}
}
size_t maxRead = maxSize;
while ((nRead < maxRead) && (mReadLoc.sIndex < mCount))
{
size_t size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;
size = std::min(size, maxSize);
for (size_t i = 0; i < size; ++i)
{
// Stop if a possible line continuation is encountered.
// It will be processed on the next call on input, which skips it
// and increments line number if necessary.
if (*(mString[mReadLoc.sIndex] + mReadLoc.cIndex + i) == '\\')
{
size = i;
maxRead = nRead + size; // Stop reading right before the backslash.
}
}
std::memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);
nRead += size;
mReadLoc.cIndex += size;

View File

@ -33,7 +33,7 @@ class Input
return mLength[index];
}
size_t read(char *buf, size_t maxSize);
size_t read(char *buf, size_t maxSize, int *lineNo);
struct Location
{
@ -49,6 +49,10 @@ class Input
const Location &readLoc() const { return mReadLoc; }
private:
// Skip a character and return the next character after the one that was skipped.
// Return nullptr if data runs out.
const char *skipChar();
// Input.
size_t mCount;
const char * const *mString;

View File

@ -6,6 +6,8 @@
#include "Macro.h"
#include <sstream>
#include "Token.h"
namespace pp
@ -19,5 +21,23 @@ bool Macro::equals(const Macro &other) const
(replacements == other.replacements);
}
void PredefineMacro(MacroSet *macroSet, const char *name, int value)
{
std::ostringstream stream;
stream << value;
Token token;
token.type = Token::CONST_INT;
token.text = stream.str();
Macro macro;
macro.predefined = true;
macro.type = Macro::kTypeObj;
macro.name = name;
macro.replacements.push_back(token);
(*macroSet)[name] = macro;
}
} // namespace pp

View File

@ -45,6 +45,8 @@ struct Macro
typedef std::map<std::string, Macro> MacroSet;
void PredefineMacro(MacroSet *macroSet, const char *name, int value);
} // namespace pp
#endif // COMPILER_PREPROCESSOR_MACRO_H_

View File

@ -26,7 +26,7 @@ class TokenLexer : public Lexer
mIter = mTokens.begin();
}
virtual void lex(Token *token)
void lex(Token *token) override
{
if (mIter == mTokens.end())
{
@ -48,10 +48,9 @@ class TokenLexer : public Lexer
MacroExpander::MacroExpander(Lexer *lexer,
MacroSet *macroSet,
Diagnostics *diagnostics)
: mLexer(lexer),
mMacroSet(macroSet),
mDiagnostics(diagnostics)
Diagnostics *diagnostics,
bool parseDefined)
: mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics), mParseDefined(parseDefined)
{
}
@ -67,11 +66,54 @@ void MacroExpander::lex(Token *token)
{
while (true)
{
const char kDefined[] = "defined";
getToken(token);
if (token->type != Token::IDENTIFIER)
break;
// Defined operator is parsed here since it may be generated by macro expansion.
// Defined operator produced by macro expansion has undefined behavior according to C++
// spec, which the GLSL spec references (see C++14 draft spec section 16.1.4), but this
// behavior is needed for passing dEQP tests, which enforce stricter compatibility between
// implementations.
if (mParseDefined && token->text == kDefined)
{
bool paren = false;
getToken(token);
if (token->type == '(')
{
paren = true;
getToken(token);
}
if (token->type != Token::IDENTIFIER)
{
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
token->text);
break;
}
auto iter = mMacroSet->find(token->text);
std::string expression = iter != mMacroSet->end() ? "1" : "0";
if (paren)
{
getToken(token);
if (token->type != ')')
{
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
token->text);
break;
}
}
// We have a valid defined operator.
// Convert the current token into a CONST_INT token.
token->type = Token::CONST_INT;
token->text = expression;
break;
}
if (token->expansionDisabled())
break;
@ -187,6 +229,12 @@ bool MacroExpander::expandMacro(const Macro &macro,
std::vector<Token> *replacements)
{
replacements->clear();
// In the case of an object-like macro, the replacement list gets its location
// from the identifier, but in the case of a function-like macro, the replacement
// list gets its location from the closing parenthesis of the macro invocation.
// This is tested by dEQP-GLES3.functional.shaders.preprocessor.predefined_macros.*
SourceLocation replacementLocation = identifier.location;
if (macro.type == Macro::kTypeObj)
{
replacements->assign(macro.replacements.begin(),
@ -218,7 +266,7 @@ bool MacroExpander::expandMacro(const Macro &macro,
assert(macro.type == Macro::kTypeFunc);
std::vector<MacroArg> args;
args.reserve(macro.parameters.size());
if (!collectMacroArgs(macro, identifier, &args))
if (!collectMacroArgs(macro, identifier, &args, &replacementLocation))
return false;
replaceMacroParams(macro, args, replacements);
@ -234,14 +282,15 @@ bool MacroExpander::expandMacro(const Macro &macro,
repl.setAtStartOfLine(identifier.atStartOfLine());
repl.setHasLeadingSpace(identifier.hasLeadingSpace());
}
repl.location = identifier.location;
repl.location = replacementLocation;
}
return true;
}
bool MacroExpander::collectMacroArgs(const Macro &macro,
const Token &identifier,
std::vector<MacroArg> *args)
std::vector<MacroArg> *args,
SourceLocation *closingParenthesisLocation)
{
Token token;
getToken(&token);
@ -271,6 +320,7 @@ bool MacroExpander::collectMacroArgs(const Macro &macro,
case ')':
--openParens;
isArg = openParens != 0;
*closingParenthesisLocation = token.location;
break;
case ',':
// The individual arguments are separated by comma tokens, but
@ -317,7 +367,7 @@ bool MacroExpander::collectMacroArgs(const Macro &macro,
{
MacroArg &arg = args->at(i);
TokenLexer lexer(&arg);
MacroExpander expander(&lexer, mMacroSet, mDiagnostics);
MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mParseDefined);
arg.clear();
expander.lex(&token);

View File

@ -19,14 +19,15 @@ namespace pp
{
class Diagnostics;
struct SourceLocation;
class MacroExpander : public Lexer
{
public:
MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics);
virtual ~MacroExpander();
MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics, bool parseDefined);
~MacroExpander() override;
virtual void lex(Token *token);
void lex(Token *token) override;
private:
PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander);
@ -45,7 +46,8 @@ class MacroExpander : public Lexer
typedef std::vector<Token> MacroArg;
bool collectMacroArgs(const Macro &macro,
const Token &identifier,
std::vector<MacroArg> *args);
std::vector<MacroArg> *args,
SourceLocation *closingParenthesisLocation);
void replaceMacroParams(const Macro &macro,
const std::vector<MacroArg> &args,
std::vector<Token> *replacements);
@ -79,6 +81,7 @@ class MacroExpander : public Lexer
Lexer *mLexer;
MacroSet *mMacroSet;
Diagnostics *mDiagnostics;
bool mParseDefined;
std::auto_ptr<Token> mReserveToken;
std::vector<MacroContext *> mContextStack;

View File

@ -7,7 +7,6 @@
#include "Preprocessor.h"
#include <cassert>
#include <sstream>
#include "DiagnosticsBase.h"
#include "DirectiveParser.h"
@ -27,12 +26,11 @@ struct PreprocessorImpl
DirectiveParser directiveParser;
MacroExpander macroExpander;
PreprocessorImpl(Diagnostics *diag,
DirectiveHandler *directiveHandler)
PreprocessorImpl(Diagnostics *diag, DirectiveHandler *directiveHandler)
: diagnostics(diag),
tokenizer(diag),
directiveParser(&tokenizer, &macroSet, diag, directiveHandler),
macroExpander(&directiveParser, &macroSet, diag)
macroExpander(&directiveParser, &macroSet, diag, false)
{
}
};
@ -52,12 +50,12 @@ bool Preprocessor::init(size_t count,
const char * const string[],
const int length[])
{
static const int kGLSLVersion = 100;
static const int kDefaultGLSLVersion = 100;
// Add standard pre-defined macros.
predefineMacro("__LINE__", 0);
predefineMacro("__FILE__", 0);
predefineMacro("__VERSION__", kGLSLVersion);
predefineMacro("__VERSION__", kDefaultGLSLVersion);
predefineMacro("GL_ES", 1);
return mImpl->tokenizer.init(count, string, length);
@ -65,20 +63,7 @@ bool Preprocessor::init(size_t count,
void Preprocessor::predefineMacro(const char *name, int value)
{
std::ostringstream stream;
stream << value;
Token token;
token.type = Token::CONST_INT;
token.text = stream.str();
Macro macro;
macro.predefined = true;
macro.type = Macro::kTypeObj;
macro.name = name;
macro.replacements.push_back(token);
mImpl->macroSet[name] = macro;
PredefineMacro(&mImpl->macroSet, name, value);
}
void Preprocessor::lex(Token *token)

View File

@ -594,7 +594,7 @@ typedef pp::SourceLocation YYLTYPE;
} while(0);
#define YY_INPUT(buf, result, maxSize) \
result = yyextra->input.read(buf, maxSize);
result = yyextra->input.read(buf, maxSize, &yylineno);
#define INITIAL 0
#define COMMENT 1

View File

@ -42,7 +42,7 @@ class Tokenizer : public Lexer
void setLineNumber(int line);
void setMaxTokenSize(size_t maxTokenSize);
virtual void lex(Token *token);
void lex(Token *token) override;
private:
PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer);

View File

@ -77,7 +77,7 @@ typedef pp::SourceLocation YYLTYPE;
} while(0);
#define YY_INPUT(buf, result, maxSize) \
result = yyextra->input.read(buf, maxSize);
result = yyextra->input.read(buf, maxSize, &yylineno);
%}

View File

@ -48,6 +48,15 @@ bool numeric_lex_int(const std::string &str, IntType *value)
template<typename FloatType>
bool numeric_lex_float(const std::string &str, FloatType *value)
{
// On 64-bit Intel Android, istringstream is broken. Until this is fixed in
// a newer NDK, don't use it. Android doesn't have locale support, so this
// doesn't have to force the C locale.
// TODO(thakis): Remove this once this bug has been fixed in the NDK and
// that NDK has been rolled into chromium.
#if defined(ANGLE_PLATFORM_ANDROID) && __x86_64__
*value = strtod(str.c_str(), nullptr);
return errno != ERANGE;
#else
std::istringstream stream(str);
// Force "C" locale so that decimal character is always '.', and
// not dependent on the current locale.
@ -55,6 +64,7 @@ bool numeric_lex_float(const std::string &str, FloatType *value)
stream >> (*value);
return !stream.fail();
#endif
}
} // namespace pp.

View File

@ -139,13 +139,16 @@ class PullGradient : public TIntermTraverser
std::vector<TIntermNode*> mParents;
};
// Traverses the AST of a function definition, assuming it has already been used to
// traverse the callees of that function; computes the discontinuous loops and the if
// statements that contain a discontinuous loop in their call graph.
class PullComputeDiscontinuousLoops : public TIntermTraverser
// Traverses the AST of a function definition to compute the the discontinuous loops
// and the if statements containing gradient loops. It assumes that the gradient loops
// (loops that contain a gradient) have already been computed and that it has already
// traversed the current function's callees.
class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
{
public:
PullComputeDiscontinuousLoops(MetadataList *metadataList, size_t index, const CallDAG &dag)
PullComputeDiscontinuousAndGradientLoops(MetadataList *metadataList,
size_t index,
const CallDAG &dag)
: TIntermTraverser(true, false, true),
mMetadataList(metadataList),
mMetadata(&(*metadataList)[index]),
@ -161,15 +164,15 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser
ASSERT(mIfs.empty());
}
// Called when a discontinuous loop or a call to a function with a discontinuous loop
// in its call graph is found.
void onDiscontinuousLoop()
// Called when traversing a gradient loop or a call to a function with a
// gradient loop in its call graph.
void onGradientLoop()
{
mMetadata->mHasDiscontinuousLoopInCallGraph = true;
mMetadata->mHasGradientLoopInCallGraph = true;
// Mark the latest if as using a discontinuous loop.
if (!mIfs.empty())
{
mMetadata->mIfsContainingDiscontinuousLoop.insert(mIfs.back());
mMetadata->mIfsContainingGradientLoop.insert(mIfs.back());
}
}
@ -178,6 +181,11 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser
if (visit == PreVisit)
{
mLoopsAndSwitches.push_back(loop);
if (mMetadata->hasGradientInCallGraph(loop))
{
onGradientLoop();
}
}
else if (visit == PostVisit)
{
@ -199,9 +207,9 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser
ASSERT(mIfs.back() == node);
mIfs.pop_back();
// An if using a discontinuous loop means its parents ifs are also discontinuous.
if (mMetadata->mIfsContainingDiscontinuousLoop.count(node) > 0 && !mIfs.empty())
if (mMetadata->mIfsContainingGradientLoop.count(node) > 0 && !mIfs.empty())
{
mMetadata->mIfsContainingDiscontinuousLoop.insert(mIfs.back());
mMetadata->mIfsContainingGradientLoop.insert(mIfs.back());
}
}
@ -221,7 +229,6 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser
if (loop != nullptr)
{
mMetadata->mDiscontinuousLoops.insert(loop);
onDiscontinuousLoop();
}
}
break;
@ -237,7 +244,6 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser
}
ASSERT(loop != nullptr);
mMetadata->mDiscontinuousLoops.insert(loop);
onDiscontinuousLoop();
}
break;
case EOpKill:
@ -245,15 +251,14 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser
// A return or discard jumps out of all the enclosing loops
if (!mLoopsAndSwitches.empty())
{
for (TIntermNode* node : mLoopsAndSwitches)
for (TIntermNode *intermNode : mLoopsAndSwitches)
{
TIntermLoop *loop = node->getAsLoopNode();
TIntermLoop *loop = intermNode->getAsLoopNode();
if (loop)
{
mMetadata->mDiscontinuousLoops.insert(loop);
}
}
onDiscontinuousLoop();
}
break;
default:
@ -274,9 +279,9 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
UNUSED_ASSERTION_VARIABLE(mIndex);
if ((*mMetadataList)[calleeIndex].mHasDiscontinuousLoopInCallGraph)
if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
{
onDiscontinuousLoop();
onGradientLoop();
}
}
}
@ -375,19 +380,14 @@ class PushDiscontinuousLoops : public TIntermTraverser
}
bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermSelection *node)
{
return mControlFlowsContainingGradient.count(node) > 0;
}
bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node)
{
return mControlFlowsContainingGradient.count(node) > 0;
}
bool ASTMetadataHLSL::hasDiscontinuousLoop(TIntermSelection *node)
bool ASTMetadataHLSL::hasGradientLoop(TIntermSelection *node)
{
return mIfsContainingDiscontinuousLoop.count(node) > 0;
return mIfsContainingGradientLoop.count(node) > 0;
}
MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag)
@ -424,10 +424,10 @@ MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag)
// of callgraph analysis as for the gradient.
// First compute which loops are discontinuous (no specific order) and pull
// the ifs and functions using a discontinuous loop.
// the ifs and functions using a gradient loop.
for (size_t i = 0; i < callDag.size(); i++)
{
PullComputeDiscontinuousLoops pull(&metadataList, i, callDag);
PullComputeDiscontinuousAndGradientLoops pull(&metadataList, i, callDag);
pull.traverse(callDag.getRecordFromIndex(i).node);
}

View File

@ -22,16 +22,15 @@ struct ASTMetadataHLSL
ASTMetadataHLSL()
: mUsesGradient(false),
mCalledInDiscontinuousLoop(false),
mHasDiscontinuousLoopInCallGraph(false),
mHasGradientLoopInCallGraph(false),
mNeedsLod0(false)
{
}
// Here "something uses a gradient" means here that it either contains a
// gradient operation, or a call to a function that uses a gradient.
bool hasGradientInCallGraph(TIntermSelection *node);
bool hasGradientInCallGraph(TIntermLoop *node);
bool hasDiscontinuousLoop(TIntermSelection *node);
bool hasGradientLoop(TIntermSelection *node);
// Does the function use a gradient.
bool mUsesGradient;
@ -43,9 +42,9 @@ struct ASTMetadataHLSL
// Remember information about the discontinuous loops and which functions
// are called in such loops.
bool mCalledInDiscontinuousLoop;
bool mHasDiscontinuousLoopInCallGraph;
bool mHasGradientLoopInCallGraph;
std::set<TIntermLoop*> mDiscontinuousLoops;
std::set<TIntermSelection*> mIfsContainingDiscontinuousLoop;
std::set<TIntermSelection *> mIfsContainingGradientLoop;
// Will we need to generate a Lod0 version of the function.
bool mNeedsLod0;

View File

@ -324,8 +324,9 @@ enum TQualifier
// built-ins written by fragment shader
EvqFragColor,
EvqFragData,
EvqFragDepthEXT, // gl_FragDepthEXT for ESSL100, EXT_frag_depth.
EvqFragDepth, // gl_FragDepth for ESSL300.
EvqFragDepth,
EvqSecondaryFragColorEXT, // EXT_blend_func_extended
EvqSecondaryFragDataEXT, // EXT_blend_func_extended
// built-ins written by the shader_framebuffer_fetch extension(s)
EvqLastFragColor,
@ -389,7 +390,7 @@ struct TLayoutQualifier
inline const char* getQualifierString(TQualifier q)
{
switch(q)
{ // clang-format off
{
case EvqTemporary: return "Temporary"; break;
case EvqGlobal: return "Global"; break;
case EvqConst: return "const"; break;
@ -413,8 +414,13 @@ inline const char* getQualifierString(TQualifier q)
case EvqPointCoord: return "PointCoord"; break;
case EvqFragColor: return "FragColor"; break;
case EvqFragData: return "FragData"; break;
case EvqFragDepthEXT: return "FragDepth"; break;
case EvqFragDepth: return "FragDepth"; break;
case EvqSecondaryFragColorEXT:
return "SecondaryFragColorEXT";
break;
case EvqSecondaryFragDataEXT:
return "SecondaryFragDataEXT";
break;
case EvqLastFragColor: return "LastFragColor"; break;
case EvqLastFragData: return "LastFragData"; break;
case EvqSmoothOut: return "smooth out"; break;
@ -424,7 +430,7 @@ inline const char* getQualifierString(TQualifier q)
case EvqFlatIn: return "flat in"; break;
case EvqCentroidIn: return "centroid in"; break;
default: UNREACHABLE(); return "unknown qualifier";
} // clang-format on
}
}
inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq)

View File

@ -17,7 +17,7 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr
{
}
virtual bool visitUnary(Visit visit, TIntermUnary *node)
bool visitUnary(Visit visit, TIntermUnary *node) override
{
if (visit == PreVisit)
{
@ -28,7 +28,7 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr
return true;
}
virtual bool visitAggregate(Visit visit, TIntermAggregate *node)
bool visitAggregate(Visit visit, TIntermAggregate *node) override
{
if (visit == PreVisit)
{

View File

@ -71,10 +71,10 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
record.callees.reserve(data.callees.size());
for (auto &callee : data.callees)
{
record.callees.push_back(callee->index);
record.callees.push_back(static_cast<int>(callee->index));
}
(*idToIndex)[data.node->getFunctionId()] = data.index;
(*idToIndex)[data.node->getFunctionId()] = static_cast<int>(data.index);
}
}

View File

@ -151,6 +151,15 @@ TCompiler::~TCompiler()
{
}
bool TCompiler::shouldRunLoopAndIndexingValidation(int compileOptions) const
{
// If compiling an ESSL 1.00 shader for WebGL, or if its been requested through the API,
// validate loop and indexing as well (to verify that the shader only uses minimal functionality
// of ESSL 1.00 as in Appendix A of the spec).
return (IsWebGLBasedSpec(shaderSpec) && shaderVersion == 100) ||
(compileOptions & SH_VALIDATE_LOOP_INDEXING);
}
bool TCompiler::Init(const ShBuiltInResources& resources)
{
shaderVersion = 100;
@ -182,8 +191,9 @@ TIntermNode *TCompiler::compileTreeForTesting(const char* const shaderStrings[],
return compileTreeImpl(shaderStrings, numStrings, compileOptions);
}
TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
size_t numStrings, int compileOptions)
TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
size_t numStrings,
const int compileOptions)
{
clearResults();
@ -193,10 +203,6 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
// Reset the extension behavior for each compilation unit.
ResetExtensionBehavior(extensionBehavior);
// If compiling for WebGL, validate loop and indexing as well.
if (IsWebGLBasedSpec(shaderSpec))
compileOptions |= SH_VALIDATE_LOOP_INDEXING;
// First string is path of source file if flag is set. The actual source follows.
size_t firstSource = 0;
if (compileOptions & SH_SOURCE_PATH)
@ -242,7 +248,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
}
root = parseContext.getTreeRoot();
success = intermediate.postProcess(root);
root = intermediate.postProcess(root);
// Disallow expressions deemed too complex.
if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
@ -273,7 +279,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
if (success && shaderVersion == 300 && shaderType == GL_FRAGMENT_SHADER)
success = validateOutputs(root);
if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
if (success && shouldRunLoopAndIndexingValidation(compileOptions))
success = validateLimitations(root);
if (success && (compileOptions & SH_TIMING_RESTRICTIONS))
@ -326,7 +332,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
RemovePow(root);
}
if (success && (compileOptions & SH_VARIABLES))
if (success && shouldCollectVariables(compileOptions))
{
collectVariables(root);
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
@ -461,6 +467,7 @@ void TCompiler::setResourceString()
<< ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
<< ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity
<< ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
<< ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended
<< ":EXT_frag_depth:" << compileResources.EXT_frag_depth
<< ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
<< ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
@ -470,6 +477,7 @@ void TCompiler::setResourceString()
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
<< ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers
<< ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision;
@ -542,7 +550,7 @@ bool TCompiler::checkCallDepth()
infoSink.info << "Call stack too deep (larger than " << maxCallStackDepth
<< ") with the following call chain: " << record.name;
int currentFunction = i;
int currentFunction = static_cast<int>(i);
int currentDepth = depth;
while (currentFunction != -1)
@ -572,7 +580,7 @@ bool TCompiler::checkCallDepth()
bool TCompiler::tagUsedFunctions()
{
// Search from main, starting from the end of the DAG as it usually is the root.
for (int i = mCallDag.size(); i-- > 0;)
for (size_t i = mCallDag.size(); i-- > 0;)
{
if (mCallDag.getRecordFromIndex(i).name == "main(")
{
@ -660,9 +668,9 @@ bool TCompiler::pruneUnusedFunctions(TIntermNode *root)
bool TCompiler::validateOutputs(TIntermNode* root)
{
ValidateOutputs validateOutputs(infoSink.info, compileResources.MaxDrawBuffers);
ValidateOutputs validateOutputs(getExtensionBehavior(), compileResources.MaxDrawBuffers);
root->traverse(&validateOutputs);
return (validateOutputs.numErrors() == 0);
return (validateOutputs.validateAndCountErrors(infoSink.info) == 0);
}
void TCompiler::rewriteCSSShader(TIntermNode* root)

View File

@ -67,8 +67,8 @@ class TCompiler : public TShHandleBase
{
public:
TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
virtual ~TCompiler();
virtual TCompiler* getAsCompiler() { return this; }
~TCompiler() override;
TCompiler *getAsCompiler() override { return this; }
bool Init(const ShBuiltInResources& resources);
@ -89,7 +89,7 @@ class TCompiler : public TShHandleBase
void clearResults();
const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
const std::vector<sh::OutputVariable> &getOutputVariables() const { return outputVariables; }
const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
const std::vector<sh::Varying> &getVaryings() const { return varyings; }
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
@ -101,6 +101,8 @@ class TCompiler : public TShHandleBase
ShShaderOutput getOutputType() const { return outputType; }
const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
bool shouldRunLoopAndIndexingValidation(int compileOptions) const;
// Get the resources set by InitBuiltInSymbolTable
const ShBuiltInResources& getResources() const;
@ -158,12 +160,17 @@ class TCompiler : public TShHandleBase
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
std::vector<sh::Attribute> attributes;
std::vector<sh::Attribute> outputVariables;
std::vector<sh::OutputVariable> outputVariables;
std::vector<sh::Uniform> uniforms;
std::vector<sh::ShaderVariable> expandedUniforms;
std::vector<sh::Varying> varyings;
std::vector<sh::InterfaceBlock> interfaceBlocks;
virtual bool shouldCollectVariables(int compileOptions)
{
return (compileOptions & SH_VARIABLES) != 0;
}
private:
// Creates the function call DAG for further analysis, returning false if there is a recursion
bool initCallDag(TIntermNode *root);
@ -175,8 +182,9 @@ class TCompiler : public TShHandleBase
class UnusedPredicate;
bool pruneUnusedFunctions(TIntermNode *root);
TIntermNode *compileTreeImpl(const char* const shaderStrings[],
size_t numStrings, int compileOptions);
TIntermNode *compileTreeImpl(const char *const shaderStrings[],
size_t numStrings,
const int compileOptions);
sh::GLenum shaderType;
ShShaderSpec shaderSpec;

View File

@ -16,7 +16,7 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable
{
public:
TDiagnostics(TInfoSink& infoSink);
virtual ~TDiagnostics();
~TDiagnostics() override;
TInfoSink& infoSink() { return mInfoSink; }
@ -30,9 +30,7 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable
const std::string& extra);
protected:
virtual void print(ID id,
const pp::SourceLocation& loc,
const std::string& text);
void print(ID id, const pp::SourceLocation &loc, const std::string &text) override;
private:
TInfoSink& mInfoSink;

View File

@ -98,8 +98,9 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
if (invalidValue)
{
mDiagnostics.report(pp::Diagnostics::PP_INVALID_PRAGMA_VALUE, loc, value);
return;
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
"invalid pragma value", value,
"'on' or 'off' expected");
}
}
}

View File

@ -21,25 +21,23 @@ class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
TDiagnostics& diagnostics,
int& shaderVersion,
bool debugShaderPrecisionSupported);
virtual ~TDirectiveHandler();
~TDirectiveHandler() override;
const TPragma& pragma() const { return mPragma; }
const TExtensionBehavior& extensionBehavior() const { return mExtensionBehavior; }
virtual void handleError(const pp::SourceLocation& loc,
const std::string& msg);
void handleError(const pp::SourceLocation &loc, const std::string &msg) override;
virtual void handlePragma(const pp::SourceLocation& loc,
const std::string& name,
const std::string& value,
bool stdgl);
void handlePragma(const pp::SourceLocation &loc,
const std::string &name,
const std::string &value,
bool stdgl) override;
virtual void handleExtension(const pp::SourceLocation& loc,
const std::string& name,
const std::string& behavior);
void handleExtension(const pp::SourceLocation &loc,
const std::string &name,
const std::string &behavior) override;
virtual void handleVersion(const pp::SourceLocation& loc,
int version);
void handleVersion(const pp::SourceLocation &loc, int version) override;
private:
TPragma mPragma;

View File

@ -238,8 +238,10 @@ bool canRoundFloat(const TType &type)
TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *child)
{
TIntermAggregate *callNode = new TIntermAggregate();
callNode->setOp(EOpInternalFunctionCall);
callNode->setName(name);
callNode->setOp(EOpFunctionCall);
TName nameObj(TFunction::mangleName(name));
nameObj.setInternal(true);
callNode->setNameObj(nameObj);
callNode->getSequence()->push_back(child);
return callNode;
}
@ -291,17 +293,14 @@ bool parentUsesResult(TIntermNode* parent, TIntermNode* node)
} // namespace anonymous
EmulatePrecision::EmulatePrecision()
: TIntermTraverser(true, true, true),
mDeclaringVariables(false),
mInLValue(false),
mInFunctionCallOutParameter(false)
EmulatePrecision::EmulatePrecision(const TSymbolTable &symbolTable, int shaderVersion)
: TLValueTrackingTraverser(true, true, true, symbolTable, shaderVersion),
mDeclaringVariables(false)
{}
void EmulatePrecision::visitSymbol(TIntermSymbol *node)
{
if (canRoundFloat(node->getType()) &&
!mDeclaringVariables && !mInLValue && !mInFunctionCallOutParameter)
if (canRoundFloat(node->getType()) && !mDeclaringVariables && !isLValueRequiredHere())
{
TIntermNode *parent = getParentNode();
TIntermNode *replacement = createRoundingFunctionCallNode(node);
@ -314,14 +313,6 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
{
bool visitChildren = true;
if (node->isAssignment())
{
if (visit == PreVisit)
mInLValue = true;
else if (visit == InVisit)
mInLValue = false;
}
TOperator op = node->getOp();
// RHS of initialize is not being declared.
@ -415,22 +406,9 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
{
case EOpSequence:
case EOpConstructStruct:
// No special handling
break;
case EOpFunction:
if (visit == PreVisit)
{
const TIntermSequence &sequence = *(node->getSequence());
TIntermSequence::const_iterator seqIter = sequence.begin();
TIntermAggregate *params = (*seqIter)->getAsAggregate();
ASSERT(params != NULL);
ASSERT(params->getOp() == EOpParameters);
mFunctionMap[node->getName()] = params->getSequence();
}
break;
case EOpPrototype:
if (visit == PreVisit)
mFunctionMap[node->getName()] = node->getSequence();
visitChildren = false;
break;
case EOpParameters:
@ -457,50 +435,17 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpFunctionCall:
{
// Function call.
bool inFunctionMap = (mFunctionMap.find(node->getName()) != mFunctionMap.end());
if (visit == PreVisit)
{
// User-defined function return values are not rounded, this relies on that
// calculations producing the value were rounded.
TIntermNode *parent = getParentNode();
if (canRoundFloat(node->getType()) && !inFunctionMap && parentUsesResult(parent, node))
if (canRoundFloat(node->getType()) && !isInFunctionMap(node) &&
parentUsesResult(parent, node))
{
TIntermNode *replacement = createRoundingFunctionCallNode(node);
mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
}
if (inFunctionMap)
{
mSeqIterStack.push_back(mFunctionMap[node->getName()]->begin());
if (mSeqIterStack.back() != mFunctionMap[node->getName()]->end())
{
TQualifier qualifier = (*mSeqIterStack.back())->getAsTyped()->getQualifier();
mInFunctionCallOutParameter = (qualifier == EvqOut || qualifier == EvqInOut);
}
}
else
{
// The function is not user-defined - it is likely built-in texture function.
// Assume that those do not have out parameters.
mInFunctionCallOutParameter = false;
}
}
else if (visit == InVisit)
{
if (inFunctionMap)
{
++mSeqIterStack.back();
TQualifier qualifier = (*mSeqIterStack.back())->getAsTyped()->getQualifier();
mInFunctionCallOutParameter = (qualifier == EvqOut || qualifier == EvqInOut);
}
}
else
{
if (inFunctionMap)
{
mSeqIterStack.pop_back();
mInFunctionCallOutParameter = false;
}
}
break;
}
@ -523,15 +468,10 @@ bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node)
case EOpNegative:
case EOpVectorLogicalNot:
case EOpLogicalNot:
break;
case EOpPostIncrement:
case EOpPostDecrement:
case EOpPreIncrement:
case EOpPreDecrement:
if (visit == PreVisit)
mInLValue = true;
else if (visit == PostVisit)
mInLValue = false;
break;
default:
if (canRoundFloat(node->getType()) && visit == PreVisit)

View File

@ -18,15 +18,15 @@
// need to write a huge number of variations of the emulated compound assignment
// to every translated shader with emulation enabled.
class EmulatePrecision : public TIntermTraverser
class EmulatePrecision : public TLValueTrackingTraverser
{
public:
EmulatePrecision();
EmulatePrecision(const TSymbolTable &symbolTable, int shaderVersion);
virtual void visitSymbol(TIntermSymbol *node);
virtual bool visitBinary(Visit visit, TIntermBinary *node);
virtual bool visitUnary(Visit visit, TIntermUnary *node);
virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
void visitSymbol(TIntermSymbol *node) override;
bool visitBinary(Visit visit, TIntermBinary *node) override;
bool visitUnary(Visit visit, TIntermUnary *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
void writeEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage);
@ -56,20 +56,7 @@ class EmulatePrecision : public TIntermTraverser
EmulationSet mEmulateCompoundMul;
EmulationSet mEmulateCompoundDiv;
// Stack of function call parameter iterators
std::vector<TIntermSequence::const_iterator> mSeqIterStack;
bool mDeclaringVariables;
bool mInLValue;
bool mInFunctionCallOutParameter;
struct TStringComparator
{
bool operator() (const TString& a, const TString& b) const { return a.compare(b) < 0; }
};
// Map from function names to their parameter sequences
std::map<TString, TIntermSequence*, TStringComparator> mFunctionMap;
};
#endif // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_

View File

@ -34,4 +34,10 @@ inline const char* getBehaviorString(TBehavior b)
// Mapping between extension name and behavior.
typedef std::map<std::string, TBehavior> TExtensionBehavior;
inline bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, const char *extension)
{
auto iter = extBehavior.find(extension);
return iter != extBehavior.end() && (iter->second == EBhEnable || iter->second == EBhRequire);
}
#endif // COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_

View File

@ -27,8 +27,8 @@ class FlagStd140Structs : public TIntermTraverser
const std::vector<TIntermTyped *> getFlaggedNodes() const { return mFlaggedNodes; }
protected:
virtual bool visitBinary(Visit visit, TIntermBinary *binaryNode);
virtual void visitSymbol(TIntermSymbol *symbol);
bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
void visitSymbol(TIntermSymbol *symbol) override;
private:
bool isInStd140InterfaceBlock(TIntermTyped *node) const;

View File

@ -32,9 +32,9 @@ class ForLoopUnrollMarker : public TIntermTraverser
{
}
virtual bool visitBinary(Visit, TIntermBinary *node);
virtual bool visitLoop(Visit, TIntermLoop *node);
virtual void visitSymbol(TIntermSymbol *node);
bool visitBinary(Visit, TIntermBinary *node) override;
bool visitLoop(Visit, TIntermLoop *node) override;
void visitSymbol(TIntermSymbol *node) override;
bool samplerArrayIndexIsFloatLoopIndex() const
{

View File

@ -464,6 +464,12 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
if (spec != SH_CSS_SHADERS_SPEC)
{
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers);
if (resources.EXT_blend_func_extended)
{
symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended",
"gl_MaxDualSourceDrawBuffersEXT",
resources.MaxDualSourceDrawBuffers);
}
}
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", resources.MaxVertexOutputVectors);
@ -502,19 +508,24 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
fragData.setArraySize(resources.MaxDrawBuffers);
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
if (resources.EXT_frag_depth)
if (resources.EXT_blend_func_extended)
{
symbolTable.insert(
ESSL1_BUILTINS, "GL_EXT_frag_depth",
new TVariable(
NewPoolTString("gl_FragDepthEXT"),
TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
EvqFragDepthEXT, 1)));
ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"),
TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4)));
TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true);
secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers);
symbolTable.insert(
ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData));
}
symbolTable.insert(ESSL3_BUILTINS,
new TVariable(NewPoolTString("gl_FragDepth"),
TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
if (resources.EXT_frag_depth)
{
symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_frag_depth", new TVariable(NewPoolTString("gl_FragDepthEXT"),
TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
}
if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
{
@ -575,6 +586,8 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
extBehavior["GL_OES_EGL_image_external"] = EBhUndefined;
if (resources.ARB_texture_rectangle)
extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined;
if (resources.EXT_blend_func_extended)
extBehavior["GL_EXT_blend_func_extended"] = EBhUndefined;
if (resources.EXT_draw_buffers)
extBehavior["GL_EXT_draw_buffers"] = EBhUndefined;
if (resources.EXT_frag_depth)

View File

@ -33,13 +33,13 @@ class InitializeVariables : public TIntermTraverser
}
protected:
virtual bool visitBinary(Visit, TIntermBinary *node) { return false; }
virtual bool visitUnary(Visit, TIntermUnary *node) { return false; }
virtual bool visitSelection(Visit, TIntermSelection *node) { return false; }
virtual bool visitLoop(Visit, TIntermLoop *node) { return false; }
virtual bool visitBranch(Visit, TIntermBranch *node) { return false; }
bool visitBinary(Visit, TIntermBinary *node) override { return false; }
bool visitUnary(Visit, TIntermUnary *node) override { return false; }
bool visitSelection(Visit, TIntermSelection *node) override { return false; }
bool visitLoop(Visit, TIntermLoop *node) override { return false; }
bool visitBranch(Visit, TIntermBranch *node) override { return false; }
virtual bool visitAggregate(Visit visit, TIntermAggregate* node);
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
private:
void insertInitCode(TIntermSequence *sequence);

View File

@ -311,17 +311,13 @@ bool TIntermAggregate::replaceChildNodeWithMultiple(TIntermNode *original, TInte
bool TIntermAggregate::insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions)
{
TIntermSequence::size_type itPosition = 0;
for (auto it = mSequence.begin(); it < mSequence.end(); ++it)
if (position > mSequence.size())
{
if (itPosition == position)
{
mSequence.insert(it, insertions.begin(), insertions.end());
return true;
}
++itPosition;
return false;
}
return false;
auto it = mSequence.begin() + position;
mSequence.insert(it, insertions.begin(), insertions.end());
return true;
}
void TIntermAggregate::setPrecisionFromChildren()
@ -365,7 +361,7 @@ void TIntermAggregate::setBuiltInFunctionPrecision()
}
// ESSL 3.0 spec section 8: textureSize always gets highp precision.
// All other functions that take a sampler are assumed to be texture functions.
if (mName.find("textureSize") == 0)
if (mName.getString().find("textureSize") == 0)
mType.setPrecision(EbpHigh);
else
mType.setPrecision(precision);
@ -395,6 +391,75 @@ bool TIntermCase::replaceChildNode(
return false;
}
TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermNode(), mType(node.mType)
{
// Copy constructor is disallowed for TIntermNode in order to disallow it for subclasses that
// don't explicitly allow it, so normal TIntermNode constructor is used to construct the copy.
// We need to manually copy any fields of TIntermNode besides handling fields in TIntermTyped.
mLine = node.mLine;
}
TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node)
{
size_t arraySize = mType.getObjectSize();
mUnionArrayPointer = new TConstantUnion[arraySize];
for (size_t i = 0u; i < arraySize; ++i)
{
mUnionArrayPointer[i] = node.mUnionArrayPointer[i];
}
}
TIntermAggregate::TIntermAggregate(const TIntermAggregate &node)
: TIntermOperator(node),
mName(node.mName),
mUserDefined(node.mUserDefined),
mFunctionId(node.mFunctionId),
mUseEmulatedFunction(node.mUseEmulatedFunction),
mGotPrecisionFromChildren(node.mGotPrecisionFromChildren)
{
for (TIntermNode *child : node.mSequence)
{
TIntermTyped *typedChild = child->getAsTyped();
ASSERT(typedChild != nullptr);
TIntermTyped *childCopy = typedChild->deepCopy();
mSequence.push_back(childCopy);
}
}
TIntermBinary::TIntermBinary(const TIntermBinary &node)
: TIntermOperator(node), mAddIndexClamp(node.mAddIndexClamp)
{
TIntermTyped *leftCopy = node.mLeft->deepCopy();
TIntermTyped *rightCopy = node.mRight->deepCopy();
ASSERT(leftCopy != nullptr && rightCopy != nullptr);
mLeft = leftCopy;
mRight = rightCopy;
}
TIntermUnary::TIntermUnary(const TIntermUnary &node)
: TIntermOperator(node), mUseEmulatedFunction(node.mUseEmulatedFunction)
{
TIntermTyped *operandCopy = node.mOperand->deepCopy();
ASSERT(operandCopy != nullptr);
mOperand = operandCopy;
}
TIntermSelection::TIntermSelection(const TIntermSelection &node) : TIntermTyped(node)
{
// Only supported for ternary nodes, not if statements.
TIntermTyped *trueTyped = node.mTrueBlock->getAsTyped();
TIntermTyped *falseTyped = node.mFalseBlock->getAsTyped();
ASSERT(trueTyped != nullptr);
ASSERT(falseTyped != nullptr);
TIntermTyped *conditionCopy = node.mCondition->deepCopy();
TIntermTyped *trueCopy = trueTyped->deepCopy();
TIntermTyped *falseCopy = falseTyped->deepCopy();
ASSERT(conditionCopy != nullptr && trueCopy != nullptr && falseCopy != nullptr);
mCondition = conditionCopy;
mTrueBlock = trueCopy;
mFalseBlock = falseCopy;
}
//
// Say whether or not an operation node changes the value of a variable.
//
@ -1875,7 +1940,7 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
{
TOperator op = aggregate->getOp();
TIntermSequence *sequence = aggregate->getSequence();
unsigned int paramsCount = sequence->size();
unsigned int paramsCount = static_cast<unsigned int>(sequence->size());
std::vector<TConstantUnion *> unionArrays(paramsCount);
std::vector<size_t> objectSizes(paramsCount);
size_t maxObjectSize = 0;
@ -2256,7 +2321,7 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
{
// Perform component-wise matrix multiplication.
resultArray = new TConstantUnion[maxObjectSize];
size_t size = (*sequence)[0]->getAsTyped()->getNominalSize();
int size = (*sequence)[0]->getAsTyped()->getNominalSize();
angle::Matrix<float> result =
GetMatrix(unionArrays[0], size).compMult(GetMatrix(unionArrays[1], size));
SetUnionArrayFromMatrix(result, resultArray);
@ -2272,7 +2337,8 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
size_t numCols = (*sequence)[1]->getAsTyped()->getType().getObjectSize();
resultArray = new TConstantUnion[numRows * numCols];
angle::Matrix<float> result =
GetMatrix(unionArrays[0], 1, numCols).outerProduct(GetMatrix(unionArrays[1], numRows, 1));
GetMatrix(unionArrays[0], 1, static_cast<int>(numCols))
.outerProduct(GetMatrix(unionArrays[1], static_cast<int>(numRows), 1));
SetUnionArrayFromMatrix(result, resultArray);
}
else
@ -2478,9 +2544,20 @@ void TIntermTraverser::updateTree()
{
const NodeInsertMultipleEntry &insertion = mInsertions[ii];
ASSERT(insertion.parent);
bool inserted = insertion.parent->insertChildNodes(insertion.position, insertion.insertions);
ASSERT(inserted);
UNUSED_ASSERTION_VARIABLE(inserted);
if (!insertion.insertionsAfter.empty())
{
bool inserted = insertion.parent->insertChildNodes(insertion.position + 1,
insertion.insertionsAfter);
ASSERT(inserted);
UNUSED_ASSERTION_VARIABLE(inserted);
}
if (!insertion.insertionsBefore.empty())
{
bool inserted =
insertion.parent->insertChildNodes(insertion.position, insertion.insertionsBefore);
ASSERT(inserted);
UNUSED_ASSERTION_VARIABLE(inserted);
}
}
for (size_t ii = 0; ii < mReplacements.size(); ++ii)
{

View File

@ -42,10 +42,33 @@ class TInfoSink;
class TInfoSinkBase;
class TIntermRaw;
class TSymbolTable;
// Encapsulate an identifier string and track whether it is coming from the original shader code
// (not internal) or from ANGLE (internal). Usually internal names shouldn't be decorated or hashed.
class TName
{
public:
POOL_ALLOCATOR_NEW_DELETE();
explicit TName(const TString &name) : mName(name), mIsInternal(false) {}
TName() : mName(), mIsInternal(false) {}
TName(const TName &) = default;
TName &operator=(const TName &) = default;
const TString &getString() const { return mName; }
void setString(const TString &string) { mName = string; }
bool isInternal() const { return mIsInternal; }
void setInternal(bool isInternal) { mIsInternal = isInternal; }
private:
TString mName;
bool mIsInternal;
};
//
// Base class for the tree nodes
//
class TIntermNode
class TIntermNode : angle::NonCopyable
{
public:
POOL_ALLOCATOR_NEW_DELETE();
@ -99,7 +122,10 @@ class TIntermTyped : public TIntermNode
{
public:
TIntermTyped(const TType &t) : mType(t) { }
virtual TIntermTyped *getAsTyped() { return this; }
virtual TIntermTyped *deepCopy() const = 0;
TIntermTyped *getAsTyped() override { return this; }
virtual bool hasSideEffects() const = 0;
@ -129,6 +155,8 @@ class TIntermTyped : public TIntermNode
protected:
TType mType;
TIntermTyped(const TIntermTyped &node);
};
//
@ -154,10 +182,9 @@ class TIntermLoop : public TIntermNode
mBody(body),
mUnrollFlag(false) { }
virtual TIntermLoop *getAsLoopNode() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
TIntermLoop *getAsLoopNode() override { return this; }
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
TLoopType getType() const { return mType; }
TIntermNode *getInit() { return mInit; }
@ -188,9 +215,8 @@ class TIntermBranch : public TIntermNode
: mFlowOp(op),
mExpression(e) { }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
TOperator getFlowOp() { return mFlowOp; }
TIntermTyped* getExpression() { return mExpression; }
@ -210,31 +236,32 @@ class TIntermSymbol : public TIntermTyped
// If sym comes from per process globalpoolallocator, then it causes increased memory usage
// per compile it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(int id, const TString &symbol, const TType &type)
: TIntermTyped(type),
mId(id),
mInternal(false)
: TIntermTyped(type), mId(id), mSymbol(symbol)
{
mSymbol = symbol;
}
virtual bool hasSideEffects() const { return false; }
TIntermTyped *deepCopy() const override { return new TIntermSymbol(*this); }
bool hasSideEffects() const override { return false; }
int getId() const { return mId; }
const TString &getSymbol() const { return mSymbol; }
const TString &getSymbol() const { return mSymbol.getString(); }
const TName &getName() const { return mSymbol; }
void setId(int newId) { mId = newId; }
bool isInternal() const { return mInternal; }
void setInternal(bool isInternal) { mInternal = isInternal; }
void setInternal(bool internal) { mSymbol.setInternal(internal); }
virtual void traverse(TIntermTraverser *);
virtual TIntermSymbol *getAsSymbolNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
void traverse(TIntermTraverser *it) override;
TIntermSymbol *getAsSymbolNode() override { return this; }
bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
protected:
int mId;
bool mInternal;
TString mSymbol;
TName mSymbol;
private:
TIntermSymbol(const TIntermSymbol &) = default; // Note: not deleted, just private!
};
// A Raw node stores raw code, that the translator will insert verbatim
@ -246,15 +273,22 @@ class TIntermRaw : public TIntermTyped
TIntermRaw(const TType &type, const TString &rawText)
: TIntermTyped(type),
mRawText(rawText) { }
TIntermRaw(const TIntermRaw &) = delete;
virtual bool hasSideEffects() const { return false; }
TIntermTyped *deepCopy() const override
{
UNREACHABLE();
return nullptr;
}
bool hasSideEffects() const override { return false; }
TString getRawText() const { return mRawText; }
virtual void traverse(TIntermTraverser *);
void traverse(TIntermTraverser *it) override;
virtual TIntermRaw *getAsRawNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
TIntermRaw *getAsRawNode() override { return this; }
bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
protected:
TString mRawText;
@ -267,7 +301,9 @@ class TIntermConstantUnion : public TIntermTyped
: TIntermTyped(type),
mUnionArrayPointer(unionPointer) { }
virtual bool hasSideEffects() const { return false; }
TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); }
bool hasSideEffects() const override { return false; }
const TConstantUnion *getUnionArrayPointer() const { return mUnionArrayPointer; }
TConstantUnion *getUnionArrayPointer() { return mUnionArrayPointer; }
@ -295,9 +331,9 @@ class TIntermConstantUnion : public TIntermTyped
mUnionArrayPointer = safeConstantUnion;
}
virtual TIntermConstantUnion *getAsConstantUnion() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
TIntermConstantUnion *getAsConstantUnion() override { return this; }
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
TConstantUnion *foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink);
TConstantUnion *foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink);
@ -311,6 +347,8 @@ class TIntermConstantUnion : public TIntermTyped
private:
typedef float(*FloatTypeUnaryFunc) (float);
bool foldFloatTypeUnary(const TConstantUnion &parameter, FloatTypeUnaryFunc builtinFunc, TInfoSink &infoSink, TConstantUnion *result) const;
TIntermConstantUnion(const TIntermConstantUnion &node); // Note: not deleted, just private!
};
//
@ -326,7 +364,7 @@ class TIntermOperator : public TIntermTyped
bool isMultiplication() const;
bool isConstructor() const;
virtual bool hasSideEffects() const { return isAssignment(); }
bool hasSideEffects() const override { return isAssignment(); }
protected:
TIntermOperator(TOperator op)
@ -336,6 +374,8 @@ class TIntermOperator : public TIntermTyped
: TIntermTyped(type),
mOp(op) {}
TIntermOperator(const TIntermOperator &) = default;
TOperator mOp;
};
@ -349,12 +389,13 @@ class TIntermBinary : public TIntermOperator
: TIntermOperator(op),
mAddIndexClamp(false) {}
virtual TIntermBinary *getAsBinaryNode() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); }
virtual bool hasSideEffects() const
TIntermBinary *getAsBinaryNode() override { return this; };
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
bool hasSideEffects() const override
{
return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
}
@ -375,6 +416,9 @@ class TIntermBinary : public TIntermOperator
// If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
bool mAddIndexClamp;
private:
TIntermBinary(const TIntermBinary &node); // Note: not deleted, just private!
};
//
@ -392,15 +436,13 @@ class TIntermUnary : public TIntermOperator
mOperand(NULL),
mUseEmulatedFunction(false) {}
virtual void traverse(TIntermTraverser *);
virtual TIntermUnary *getAsUnaryNode() { return this; }
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); }
virtual bool hasSideEffects() const
{
return isAssignment() || mOperand->hasSideEffects();
}
void traverse(TIntermTraverser *it) override;
TIntermUnary *getAsUnaryNode() override { return this; }
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); }
void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; }
@ -416,6 +458,9 @@ class TIntermUnary : public TIntermOperator
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
bool mUseEmulatedFunction;
private:
TIntermUnary(const TIntermUnary &node); // note: not deleted, just private!
};
typedef TVector<TIntermNode *> TIntermSequence;
@ -442,29 +487,29 @@ class TIntermAggregate : public TIntermOperator
}
~TIntermAggregate() { }
virtual TIntermAggregate *getAsAggregate() { return this; }
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
// Note: only supported for nodes that can be a part of an expression.
TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); }
TIntermAggregate *getAsAggregate() override { return this; }
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
bool replaceChildNodeWithMultiple(TIntermNode *original, TIntermSequence replacements);
bool insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions);
// Conservatively assume function calls and other aggregate operators have side-effects
virtual bool hasSideEffects() const { return true; }
bool hasSideEffects() const override { return true; }
TIntermTyped *fold(TInfoSink &infoSink);
TIntermSequence *getSequence() { return &mSequence; }
void setName(const TString &name) { mName = name; }
const TString &getName() const { return mName; }
void setNameObj(const TName &name) { mName = name; }
const TName &getNameObj() const { return mName; }
void setName(const TString &name) { mName.setString(name); }
const TString &getName() const { return mName.getString(); }
void setUserDefined() { mUserDefined = true; }
bool isUserDefined() const { return mUserDefined; }
void setOptimize(bool optimize) { mOptimize = optimize; }
bool getOptimize() const { return mOptimize; }
void setDebug(bool debug) { mDebug = debug; }
bool getDebug() const { return mDebug; }
void setFunctionId(int functionId) { mFunctionId = functionId; }
int getFunctionId() const { return mFunctionId; }
@ -478,21 +523,19 @@ class TIntermAggregate : public TIntermOperator
bool gotPrecisionFromChildren() const { return mGotPrecisionFromChildren; }
protected:
TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator
TIntermSequence mSequence;
TString mName;
TName mName;
bool mUserDefined; // used for user defined function names
int mFunctionId;
bool mOptimize;
bool mDebug;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
bool mUseEmulatedFunction;
bool mGotPrecisionFromChildren;
private:
TIntermAggregate(const TIntermAggregate &node); // note: not deleted, just private!
};
//
@ -513,23 +556,28 @@ class TIntermSelection : public TIntermTyped
mTrueBlock(trueB),
mFalseBlock(falseB) {}
virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
// Note: only supported for ternary operator nodes.
TIntermTyped *deepCopy() const override { return new TIntermSelection(*this); }
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
// Conservatively assume selections have side-effects
virtual bool hasSideEffects() const { return true; }
bool hasSideEffects() const override { return true; }
bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
TIntermNode *getCondition() const { return mCondition; }
TIntermNode *getTrueBlock() const { return mTrueBlock; }
TIntermNode *getFalseBlock() const { return mFalseBlock; }
TIntermSelection *getAsSelectionNode() { return this; }
TIntermSelection *getAsSelectionNode() override { return this; }
protected:
protected:
TIntermTyped *mCondition;
TIntermNode *mTrueBlock;
TIntermNode *mFalseBlock;
private:
TIntermSelection(const TIntermSelection &node); // Note: not deleted, just private!
};
//
@ -551,6 +599,7 @@ class TIntermSwitch : public TIntermNode
TIntermSwitch *getAsSwitchNode() override { return this; }
TIntermTyped *getInit() { return mInit; }
TIntermAggregate *getStatementList() { return mStatementList; }
void setStatementList(TIntermAggregate *statementList) { mStatementList = statementList; }
@ -592,9 +641,12 @@ enum Visit
};
//
// For traversing the tree. User should derive from this,
// put their traversal specific data in it, and then pass
// it to a Traverse method.
// For traversing the tree. User should derive from this class overriding the visit functions,
// and then pass an object of the subclass to a traverse method of a node.
//
// The traverse*() functions may also be overridden do other bookkeeping on the tree to provide
// contextual information to the visit functions, such as whether the node is the target of an
// assignment.
//
// When using this, just fill in the methods for nodes you want visited.
// Return false from a pre-visit to skip visiting that node's subtree.
@ -614,20 +666,48 @@ class TIntermTraverser : angle::NonCopyable
}
virtual ~TIntermTraverser() {}
virtual void visitSymbol(TIntermSymbol *) {}
virtual void visitRaw(TIntermRaw *) {}
virtual void visitConstantUnion(TIntermConstantUnion *) {}
virtual bool visitBinary(Visit, TIntermBinary *) { return true; }
virtual bool visitUnary(Visit, TIntermUnary *) { return true; }
virtual bool visitSelection(Visit, TIntermSelection *) { return true; }
virtual bool visitSwitch(Visit, TIntermSwitch *) { return true; }
virtual bool visitCase(Visit, TIntermCase *) { return true; }
virtual bool visitAggregate(Visit, TIntermAggregate *) { return true; }
virtual bool visitLoop(Visit, TIntermLoop *) { return true; }
virtual bool visitBranch(Visit, TIntermBranch *) { return true; }
virtual void visitSymbol(TIntermSymbol *node) {}
virtual void visitRaw(TIntermRaw *node) {}
virtual void visitConstantUnion(TIntermConstantUnion *node) {}
virtual bool visitBinary(Visit visit, TIntermBinary *node) { return true; }
virtual bool visitUnary(Visit visit, TIntermUnary *node) { return true; }
virtual bool visitSelection(Visit visit, TIntermSelection *node) { return true; }
virtual bool visitSwitch(Visit visit, TIntermSwitch *node) { return true; }
virtual bool visitCase(Visit visit, TIntermCase *node) { return true; }
virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; }
virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; }
virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; }
// The traverse functions contain logic for iterating over the children of the node
// and calling the visit functions in the appropriate places. They also track some
// context that may be used by the visit functions.
virtual void traverseSymbol(TIntermSymbol *node);
virtual void traverseRaw(TIntermRaw *node);
virtual void traverseConstantUnion(TIntermConstantUnion *node);
virtual void traverseBinary(TIntermBinary *node);
virtual void traverseUnary(TIntermUnary *node);
virtual void traverseSelection(TIntermSelection *node);
virtual void traverseSwitch(TIntermSwitch *node);
virtual void traverseCase(TIntermCase *node);
virtual void traverseAggregate(TIntermAggregate *node);
virtual void traverseLoop(TIntermLoop *node);
virtual void traverseBranch(TIntermBranch *node);
int getMaxDepth() const { return mMaxDepth; }
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
static TString hash(const TString &name, ShHashFunction64 hashFunction);
// If traversers need to replace nodes, they can add the replacements in
// mReplacements/mMultiReplacements during traversal and the user of the traverser should call
// this function after traversal to perform them.
void updateTree();
// Start creating temporary symbols from the given temporary symbol index + 1.
void useTemporaryIndex(unsigned int *temporaryIndex);
protected:
void incrementDepth(TIntermNode *current)
{
mDepth++;
@ -655,23 +735,10 @@ class TIntermTraverser : angle::NonCopyable
return !mParentBlockStack.empty() && getParentNode() == mParentBlockStack.back().node;
}
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
static TString hash(const TString& name, ShHashFunction64 hashFunction);
const bool preVisit;
const bool inVisit;
const bool postVisit;
// If traversers need to replace nodes, they can add the replacements in
// mReplacements/mMultiReplacements during traversal and the user of the traverser should call
// this function after traversal to perform them.
void updateTree();
// Start creating temporary symbols from the given temporary symbol index + 1.
void useTemporaryIndex(unsigned int *temporaryIndex);
protected:
int mDepth;
int mMaxDepth;
@ -714,16 +781,21 @@ class TIntermTraverser : angle::NonCopyable
// To insert multiple nodes on the parent aggregate node
struct NodeInsertMultipleEntry
{
NodeInsertMultipleEntry(TIntermAggregate *_parent, TIntermSequence::size_type _position, TIntermSequence _insertions)
NodeInsertMultipleEntry(TIntermAggregate *_parent,
TIntermSequence::size_type _position,
TIntermSequence _insertionsBefore,
TIntermSequence _insertionsAfter)
: parent(_parent),
position(_position),
insertions(_insertions)
position(_position),
insertionsBefore(_insertionsBefore),
insertionsAfter(_insertionsAfter)
{
}
TIntermAggregate *parent;
TIntermSequence::size_type position;
TIntermSequence insertions;
TIntermSequence insertionsBefore;
TIntermSequence insertionsAfter;
};
// During traversing, save all the changes that need to happen into
@ -740,6 +812,11 @@ class TIntermTraverser : angle::NonCopyable
// supported.
void insertStatementsInParentBlock(const TIntermSequence &insertions);
// Same as above, but supports simultaneous insertion of statements before and after the node
// currently being traversed.
void insertStatementsInParentBlock(const TIntermSequence &insertionsBefore,
const TIntermSequence &insertionsAfter);
// Helper to create a temporary symbol node with the given qualifier.
TIntermSymbol *createTempSymbol(const TType &type, TQualifier qualifier);
// Helper to create a temporary symbol node.
@ -773,6 +850,74 @@ class TIntermTraverser : angle::NonCopyable
unsigned int *mTemporaryIndex;
};
// Traverser parent class that tracks where a node is a destination of a write operation and so is
// required to be an l-value.
class TLValueTrackingTraverser : public TIntermTraverser
{
public:
TLValueTrackingTraverser(bool preVisit,
bool inVisit,
bool postVisit,
const TSymbolTable &symbolTable,
int shaderVersion)
: TIntermTraverser(preVisit, inVisit, postVisit),
mOperatorRequiresLValue(false),
mInFunctionCallOutParameter(false),
mSymbolTable(symbolTable),
mShaderVersion(shaderVersion)
{
}
virtual ~TLValueTrackingTraverser() {}
void traverseBinary(TIntermBinary *node) override;
void traverseUnary(TIntermUnary *node) override;
void traverseAggregate(TIntermAggregate *node) override;
protected:
bool isLValueRequiredHere() const
{
return mOperatorRequiresLValue || mInFunctionCallOutParameter;
}
// Return true if the prototype or definition of the function being called has been encountered
// during traversal.
bool isInFunctionMap(const TIntermAggregate *callNode) const;
private:
// Track whether an l-value is required in the node that is currently being traversed by the
// surrounding operator.
// Use isLValueRequiredHere to check all conditions which require an l-value.
void setOperatorRequiresLValue(bool lValueRequired)
{
mOperatorRequiresLValue = lValueRequired;
}
bool operatorRequiresLValue() const { return mOperatorRequiresLValue; }
// Add a function encountered during traversal to the function map.
void addToFunctionMap(const TString &name, TIntermSequence *paramSequence);
// Return the parameters sequence from the function definition or prototype.
TIntermSequence *getFunctionParameters(const TIntermAggregate *callNode);
// Track whether an l-value is required inside a function call.
void setInFunctionCallOutParameter(bool inOutParameter);
bool isInFunctionCallOutParameter() const;
bool mOperatorRequiresLValue;
bool mInFunctionCallOutParameter;
struct TStringComparator
{
bool operator()(const TString &a, const TString &b) const { return a.compare(b) < 0; }
};
// Map from mangled function names to their parameter sequences
TMap<TString, TIntermSequence *, TStringComparator> mFunctionMap;
const TSymbolTable &mSymbolTable;
const int mShaderVersion;
};
//
// For traversing the tree, and computing max depth.
// Takes a maximum depth limit to prevent stack overflow.
@ -785,12 +930,12 @@ class TMaxDepthTraverser : public TIntermTraverser
: TIntermTraverser(true, true, false),
mDepthLimit(depthLimit) { }
virtual bool visitBinary(Visit, TIntermBinary *) { return depthCheck(); }
virtual bool visitUnary(Visit, TIntermUnary *) { return depthCheck(); }
virtual bool visitSelection(Visit, TIntermSelection *) { return depthCheck(); }
virtual bool visitAggregate(Visit, TIntermAggregate *) { return depthCheck(); }
virtual bool visitLoop(Visit, TIntermLoop *) { return depthCheck(); }
virtual bool visitBranch(Visit, TIntermBranch *) { return depthCheck(); }
bool visitBinary(Visit, TIntermBinary *) override { return depthCheck(); }
bool visitUnary(Visit, TIntermUnary *) override { return depthCheck(); }
bool visitSelection(Visit, TIntermSelection *) override { return depthCheck(); }
bool visitAggregate(Visit, TIntermAggregate *) override { return depthCheck(); }
bool visitLoop(Visit, TIntermLoop *) override { return depthCheck(); }
bool visitBranch(Visit, TIntermBranch *) override { return depthCheck(); }
protected:
bool depthCheck() const { return mMaxDepth < mDepthLimit; }

View File

@ -6,6 +6,62 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/SymbolTable.h"
void TIntermSymbol::traverse(TIntermTraverser *it)
{
it->traverseSymbol(this);
}
void TIntermRaw::traverse(TIntermTraverser *it)
{
it->traverseRaw(this);
}
void TIntermConstantUnion::traverse(TIntermTraverser *it)
{
it->traverseConstantUnion(this);
}
void TIntermBinary::traverse(TIntermTraverser *it)
{
it->traverseBinary(this);
}
void TIntermUnary::traverse(TIntermTraverser *it)
{
it->traverseUnary(this);
}
void TIntermSelection::traverse(TIntermTraverser *it)
{
it->traverseSelection(this);
}
void TIntermSwitch::traverse(TIntermTraverser *it)
{
it->traverseSwitch(this);
}
void TIntermCase::traverse(TIntermTraverser *it)
{
it->traverseCase(this);
}
void TIntermAggregate::traverse(TIntermTraverser *it)
{
it->traverseAggregate(this);
}
void TIntermLoop::traverse(TIntermTraverser *it)
{
it->traverseLoop(this);
}
void TIntermBranch::traverse(TIntermTraverser *it)
{
it->traverseBranch(this);
}
void TIntermTraverser::pushParentBlock(TIntermAggregate *node)
{
@ -24,9 +80,17 @@ void TIntermTraverser::popParentBlock()
}
void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &insertions)
{
TIntermSequence emptyInsertionsAfter;
insertStatementsInParentBlock(insertions, emptyInsertionsAfter);
}
void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &insertionsBefore,
const TIntermSequence &insertionsAfter)
{
ASSERT(!mParentBlockStack.empty());
NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos, insertions);
NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos,
insertionsBefore, insertionsAfter);
mInsertions.push_back(insert);
}
@ -96,6 +160,33 @@ void TIntermTraverser::nextTemporaryIndex()
++(*mTemporaryIndex);
}
void TLValueTrackingTraverser::addToFunctionMap(const TString &name, TIntermSequence *paramSequence)
{
mFunctionMap[name] = paramSequence;
}
bool TLValueTrackingTraverser::isInFunctionMap(const TIntermAggregate *callNode) const
{
ASSERT(callNode->getOp() == EOpFunctionCall);
return (mFunctionMap.find(callNode->getName()) != mFunctionMap.end());
}
TIntermSequence *TLValueTrackingTraverser::getFunctionParameters(const TIntermAggregate *callNode)
{
ASSERT(isInFunctionMap(callNode));
return mFunctionMap[callNode->getName()];
}
void TLValueTrackingTraverser::setInFunctionCallOutParameter(bool inOutParameter)
{
mInFunctionCallOutParameter = inOutParameter;
}
bool TLValueTrackingTraverser::isInFunctionCallOutParameter() const
{
return mInFunctionCallOutParameter;
}
//
// Traverse the intermediate representation tree, and
// call a node type specific function for each node.
@ -110,240 +201,469 @@ void TIntermTraverser::nextTemporaryIndex()
//
// Traversal functions for terminals are straighforward....
//
void TIntermSymbol::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseSymbol(TIntermSymbol *node)
{
it->visitSymbol(this);
visitSymbol(node);
}
void TIntermConstantUnion::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseConstantUnion(TIntermConstantUnion *node)
{
it->visitConstantUnion(this);
visitConstantUnion(node);
}
//
// Traverse a binary node.
//
void TIntermBinary::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseBinary(TIntermBinary *node)
{
bool visit = true;
//
// visit the node before children if pre-visiting.
//
if (it->preVisit)
visit = it->visitBinary(PreVisit, this);
if (preVisit)
visit = visitBinary(PreVisit, node);
//
// Visit the children, in the right order.
//
if (visit)
{
it->incrementDepth(this);
incrementDepth(node);
if (mLeft)
mLeft->traverse(it);
if (node->getLeft())
node->getLeft()->traverse(this);
if (it->inVisit)
visit = it->visitBinary(InVisit, this);
if (inVisit)
visit = visitBinary(InVisit, node);
if (visit && mRight)
mRight->traverse(it);
if (visit && node->getRight())
node->getRight()->traverse(this);
it->decrementDepth();
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);
if (visit && postVisit)
visitBinary(PostVisit, node);
}
void TLValueTrackingTraverser::traverseBinary(TIntermBinary *node)
{
bool visit = true;
//
// visit the node before children if pre-visiting.
//
if (preVisit)
visit = visitBinary(PreVisit, node);
//
// Visit the children, in the right order.
//
if (visit)
{
incrementDepth(node);
// Some binary operations like indexing can be inside an expression which must be an
// l-value.
bool parentOperatorRequiresLValue = operatorRequiresLValue();
bool parentInFunctionCallOutParameter = isInFunctionCallOutParameter();
if (node->isAssignment())
{
ASSERT(!isLValueRequiredHere());
setOperatorRequiresLValue(true);
}
if (node->getLeft())
node->getLeft()->traverse(this);
if (inVisit)
visit = visitBinary(InVisit, node);
if (node->isAssignment())
setOperatorRequiresLValue(false);
// Index is not required to be an l-value even when the surrounding expression is required
// to be an l-value.
TOperator op = node->getOp();
if (op == EOpIndexDirect || op == EOpIndexDirectInterfaceBlock ||
op == EOpIndexDirectStruct || op == EOpIndexIndirect)
{
setOperatorRequiresLValue(false);
setInFunctionCallOutParameter(false);
}
if (visit && node->getRight())
node->getRight()->traverse(this);
setOperatorRequiresLValue(parentOperatorRequiresLValue);
setInFunctionCallOutParameter(parentInFunctionCallOutParameter);
decrementDepth();
}
//
// Visit the node after the children, if requested and the traversal
// hasn't been cancelled yet.
//
if (visit && postVisit)
visitBinary(PostVisit, node);
}
//
// Traverse a unary node. Same comments in binary node apply here.
//
void TIntermUnary::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseUnary(TIntermUnary *node)
{
bool visit = true;
if (it->preVisit)
visit = it->visitUnary(PreVisit, this);
if (preVisit)
visit = visitUnary(PreVisit, node);
if (visit) {
it->incrementDepth(this);
mOperand->traverse(it);
it->decrementDepth();
if (visit)
{
incrementDepth(node);
node->getOperand()->traverse(this);
decrementDepth();
}
if (visit && it->postVisit)
it->visitUnary(PostVisit, this);
if (visit && postVisit)
visitUnary(PostVisit, node);
}
void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node)
{
bool visit = true;
if (preVisit)
visit = visitUnary(PreVisit, node);
if (visit)
{
incrementDepth(node);
ASSERT(!operatorRequiresLValue());
switch (node->getOp())
{
case EOpPostIncrement:
case EOpPostDecrement:
case EOpPreIncrement:
case EOpPreDecrement:
setOperatorRequiresLValue(true);
break;
default:
break;
}
node->getOperand()->traverse(this);
setOperatorRequiresLValue(false);
decrementDepth();
}
if (visit && postVisit)
visitUnary(PostVisit, node);
}
//
// Traverse an aggregate node. Same comments in binary node apply here.
//
void TIntermAggregate::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
{
bool visit = true;
if (it->preVisit)
visit = it->visitAggregate(PreVisit, this);
TIntermSequence *sequence = node->getSequence();
if (preVisit)
visit = visitAggregate(PreVisit, node);
if (visit)
{
if (mOp == EOpSequence)
it->pushParentBlock(this);
incrementDepth(node);
it->incrementDepth(this);
if (node->getOp() == EOpSequence)
pushParentBlock(node);
for (TIntermSequence::iterator sit = mSequence.begin();
sit != mSequence.end(); sit++)
for (auto *child : *sequence)
{
(*sit)->traverse(it);
if (visit && it->inVisit)
child->traverse(this);
if (visit && inVisit)
{
if (*sit != mSequence.back())
visit = it->visitAggregate(InVisit, this);
if (child != sequence->back())
visit = visitAggregate(InVisit, node);
}
if (mOp == EOpSequence)
if (node->getOp() == EOpSequence)
incrementParentBlockPos();
}
if (node->getOp() == EOpSequence)
popParentBlock();
decrementDepth();
}
if (visit && postVisit)
visitAggregate(PostVisit, node);
}
void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
{
bool visit = true;
TIntermSequence *sequence = node->getSequence();
switch (node->getOp())
{
case EOpFunction:
{
TIntermAggregate *params = sequence->front()->getAsAggregate();
ASSERT(params != nullptr);
ASSERT(params->getOp() == EOpParameters);
addToFunctionMap(node->getName(), params->getSequence());
break;
}
case EOpPrototype:
addToFunctionMap(node->getName(), sequence);
break;
default:
break;
}
if (preVisit)
visit = visitAggregate(PreVisit, node);
if (visit)
{
bool inFunctionMap = false;
if (node->getOp() == EOpFunctionCall)
{
inFunctionMap = isInFunctionMap(node);
if (!inFunctionMap)
{
it->incrementParentBlockPos();
// The function is not user-defined - it is likely built-in texture function.
// Assume that those do not have out parameters.
setInFunctionCallOutParameter(false);
}
}
it->decrementDepth();
incrementDepth(node);
if (mOp == EOpSequence)
it->popParentBlock();
if (inFunctionMap)
{
TIntermSequence *params = getFunctionParameters(node);
TIntermSequence::iterator paramIter = params->begin();
for (auto *child : *sequence)
{
ASSERT(paramIter != params->end());
TQualifier qualifier = (*paramIter)->getAsTyped()->getQualifier();
setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut);
child->traverse(this);
if (visit && inVisit)
{
if (child != sequence->back())
visit = visitAggregate(InVisit, node);
}
++paramIter;
}
setInFunctionCallOutParameter(false);
}
else
{
if (node->getOp() == EOpSequence)
pushParentBlock(node);
// Find the built-in function corresponding to this op so that we can determine the
// in/out qualifiers of its parameters.
TFunction *builtInFunc = nullptr;
TString opString = GetOperatorString(node->getOp());
if (!node->isConstructor() && !opString.empty())
{
// The return type doesn't affect the mangled name of the function, which is used
// to look it up from the symbol table.
TType dummyReturnType;
TFunction call(&opString, &dummyReturnType, node->getOp());
for (auto *child : *sequence)
{
TType *paramType = child->getAsTyped()->getTypePointer();
TConstParameter p(paramType);
call.addParameter(p);
}
TSymbol *sym = mSymbolTable.findBuiltIn(call.getMangledName(), mShaderVersion);
if (sym != nullptr && sym->isFunction())
{
builtInFunc = static_cast<TFunction *>(sym);
ASSERT(builtInFunc->getParamCount() == sequence->size());
}
}
size_t paramIndex = 0;
for (auto *child : *sequence)
{
TQualifier qualifier = EvqIn;
if (builtInFunc != nullptr)
qualifier = builtInFunc->getParam(paramIndex).type->getQualifier();
setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut);
child->traverse(this);
if (visit && inVisit)
{
if (child != sequence->back())
visit = visitAggregate(InVisit, node);
}
if (node->getOp() == EOpSequence)
incrementParentBlockPos();
++paramIndex;
}
setInFunctionCallOutParameter(false);
if (node->getOp() == EOpSequence)
popParentBlock();
}
decrementDepth();
}
if (visit && it->postVisit)
it->visitAggregate(PostVisit, this);
if (visit && postVisit)
visitAggregate(PostVisit, node);
}
//
// Traverse a selection node. Same comments in binary node apply here.
//
void TIntermSelection::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseSelection(TIntermSelection *node)
{
bool visit = true;
if (it->preVisit)
visit = it->visitSelection(PreVisit, this);
if (preVisit)
visit = visitSelection(PreVisit, node);
if (visit)
{
it->incrementDepth(this);
mCondition->traverse(it);
if (mTrueBlock)
mTrueBlock->traverse(it);
if (mFalseBlock)
mFalseBlock->traverse(it);
it->decrementDepth();
incrementDepth(node);
node->getCondition()->traverse(this);
if (node->getTrueBlock())
node->getTrueBlock()->traverse(this);
if (node->getFalseBlock())
node->getFalseBlock()->traverse(this);
decrementDepth();
}
if (visit && it->postVisit)
it->visitSelection(PostVisit, this);
if (visit && postVisit)
visitSelection(PostVisit, node);
}
//
// Traverse a switch node. Same comments in binary node apply here.
//
void TIntermSwitch::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseSwitch(TIntermSwitch *node)
{
bool visit = true;
if (it->preVisit)
visit = it->visitSwitch(PreVisit, this);
if (preVisit)
visit = visitSwitch(PreVisit, node);
if (visit)
{
it->incrementDepth(this);
mInit->traverse(it);
if (it->inVisit)
visit = it->visitSwitch(InVisit, this);
if (visit && mStatementList)
mStatementList->traverse(it);
it->decrementDepth();
incrementDepth(node);
node->getInit()->traverse(this);
if (inVisit)
visit = visitSwitch(InVisit, node);
if (visit && node->getStatementList())
node->getStatementList()->traverse(this);
decrementDepth();
}
if (visit && it->postVisit)
it->visitSwitch(PostVisit, this);
if (visit && postVisit)
visitSwitch(PostVisit, node);
}
//
// Traverse a switch node. Same comments in binary node apply here.
// Traverse a case node. Same comments in binary node apply here.
//
void TIntermCase::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseCase(TIntermCase *node)
{
bool visit = true;
if (it->preVisit)
visit = it->visitCase(PreVisit, this);
if (preVisit)
visit = visitCase(PreVisit, node);
if (visit && mCondition)
mCondition->traverse(it);
if (visit && node->getCondition())
node->getCondition()->traverse(this);
if (visit && it->postVisit)
it->visitCase(PostVisit, this);
if (visit && postVisit)
visitCase(PostVisit, node);
}
//
// Traverse a loop node. Same comments in binary node apply here.
//
void TIntermLoop::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseLoop(TIntermLoop *node)
{
bool visit = true;
if (it->preVisit)
visit = it->visitLoop(PreVisit, this);
if (preVisit)
visit = visitLoop(PreVisit, node);
if (visit)
{
it->incrementDepth(this);
incrementDepth(node);
if (mInit)
mInit->traverse(it);
if (node->getInit())
node->getInit()->traverse(this);
if (mCond)
mCond->traverse(it);
if (node->getCondition())
node->getCondition()->traverse(this);
if (mBody)
mBody->traverse(it);
if (node->getBody())
node->getBody()->traverse(this);
if (mExpr)
mExpr->traverse(it);
if (node->getExpression())
node->getExpression()->traverse(this);
it->decrementDepth();
decrementDepth();
}
if (visit && it->postVisit)
it->visitLoop(PostVisit, this);
if (visit && postVisit)
visitLoop(PostVisit, node);
}
//
// Traverse a branch node. Same comments in binary node apply here.
//
void TIntermBranch::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseBranch(TIntermBranch *node)
{
bool visit = true;
if (it->preVisit)
visit = it->visitBranch(PreVisit, this);
if (preVisit)
visit = visitBranch(PreVisit, node);
if (visit && mExpression) {
it->incrementDepth(this);
mExpression->traverse(it);
it->decrementDepth();
if (visit && node->getExpression())
{
incrementDepth(node);
node->getExpression()->traverse(this);
decrementDepth();
}
if (visit && it->postVisit)
it->visitBranch(PostVisit, this);
if (visit && postVisit)
visitBranch(PostVisit, node);
}
void TIntermRaw::traverse(TIntermTraverser *it)
void TIntermTraverser::traverseRaw(TIntermRaw *node)
{
it->visitRaw(this);
visitRaw(node);
}

View File

@ -426,19 +426,27 @@ TIntermBranch* TIntermediate::addBranch(
// This is to be executed once the final root is put on top by the parsing
// process.
//
bool TIntermediate::postProcess(TIntermNode *root)
TIntermAggregate *TIntermediate::postProcess(TIntermNode *root)
{
if (root == NULL)
return true;
if (root == nullptr)
return nullptr;
//
// First, finish off the top level sequence, if any
// Finish off the top level sequence, if any
//
TIntermAggregate *aggRoot = root->getAsAggregate();
if (aggRoot && aggRoot->getOp() == EOpNull)
if (aggRoot != nullptr && aggRoot->getOp() == EOpNull)
{
aggRoot->setOp(EOpSequence);
}
else if (aggRoot == nullptr || aggRoot->getOp() != EOpSequence)
{
aggRoot = new TIntermAggregate(EOpSequence);
aggRoot->setLine(root->getLine());
aggRoot->getSequence()->push_back(root);
}
return true;
return aggRoot;
}
TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate)

View File

@ -60,7 +60,7 @@ class TIntermediate
TIntermBranch *addBranch(TOperator, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &);
TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &);
bool postProcess(TIntermNode *);
TIntermAggregate *postProcess(TIntermNode *root);
static void outputTree(TIntermNode *, TInfoSinkBase &);

View File

@ -15,7 +15,6 @@ enum TOperator
EOpNull, // if in a node, should only mean a node is still being built
EOpSequence, // denotes a list of statements, or parameters, etc.
EOpFunctionCall,
EOpInternalFunctionCall, // Call to an internal helper function
EOpFunction, // For function definition
EOpParameters, // an aggregate listing the parameters to a function

View File

@ -21,7 +21,8 @@ public:
bool forceHighp);
protected:
virtual bool writeVariablePrecision(TPrecision precision);
bool writeVariablePrecision(TPrecision precision) override;
private:
bool mForceHighp;
};

View File

@ -45,6 +45,14 @@ void TOutputGLSL::visitSymbol(TIntermSymbol *node)
{
out << "webgl_FragData";
}
else if (symbol == "gl_SecondaryFragColorEXT")
{
out << "angle_SecondaryFragColor";
}
else if (symbol == "gl_SecondaryFragDataEXT")
{
out << "angle_SecondaryFragData";
}
else
{
TOutputGLSLBase::visitSymbol(node);

View File

@ -21,9 +21,9 @@ class TOutputGLSL : public TOutputGLSLBase
ShShaderOutput output);
protected:
virtual bool writeVariablePrecision(TPrecision);
virtual void visitSymbol(TIntermSymbol* node);
virtual TString translateTextureFunction(TString& name);
bool writeVariablePrecision(TPrecision) override;
void visitSymbol(TIntermSymbol *node) override;
TString translateTextureFunction(TString &name) override;
};
#endif // COMPILER_TRANSLATOR_OUTPUTGLSL_H_

View File

@ -96,6 +96,11 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
{
out << "invariant ";
}
if (type.getBasicType() == EbtInterfaceBlock)
{
TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
declareInterfaceBlockLayout(interfaceBlock);
}
TQualifier qualifier = type.getQualifier();
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
{
@ -134,6 +139,11 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
mDeclaredStructs.insert(structure->uniqueId());
}
}
else if (type.getBasicType() == EbtInterfaceBlock)
{
TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
declareInterfaceBlock(interfaceBlock);
}
else
{
if (writeVariablePrecision(type.getPrecision()))
@ -373,6 +383,22 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
visitChildren = false;
}
break;
case EOpIndexDirectInterfaceBlock:
if (visit == InVisit)
{
out << ".";
const TInterfaceBlock *interfaceBlock = node->getLeft()->getType().getInterfaceBlock();
const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
const TField *field = interfaceBlock->fields()[index->getIConst(0)];
TString fieldName = field->name();
ASSERT(!mSymbolTable.findBuiltIn(interfaceBlock->name(), mShaderVersion));
fieldName = hashName(fieldName);
out << fieldName;
visitChildren = false;
}
break;
case EOpVectorSwizzle:
if (visit == InVisit)
{
@ -783,7 +809,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
out << arrayBrackets(type);
}
out << " " << hashFunctionName(node->getName());
out << " " << hashFunctionNameIfNeeded(node->getNameObj());
out << "(";
writeFunctionParameters(*(node->getSequence()));
@ -801,7 +827,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
out << arrayBrackets(type);
}
out << " " << hashFunctionName(node->getName());
out << " " << hashFunctionNameIfNeeded(node->getNameObj());
incrementDepth(node);
// Function definition node contains one or two children nodes
@ -830,16 +856,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpFunctionCall:
// Function call.
if (visit == PreVisit)
out << hashFunctionName(node->getName()) << "(";
else if (visit == InVisit)
out << ", ";
else
out << ")";
break;
case EOpInternalFunctionCall:
// Function call to an internal helper function.
if (visit == PreVisit)
out << node->getName() << "(";
out << hashFunctionNameIfNeeded(node->getNameObj()) << "(";
else if (visit == InVisit)
out << ", ";
else
@ -1183,6 +1200,10 @@ TString TOutputGLSLBase::getTypeName(const TType &type)
{
out << "mat";
out << type.getNominalSize();
if (type.getSecondarySize() != type.getNominalSize())
{
out << "x" << type.getSecondarySize();
}
}
else if (type.isVector())
{
@ -1234,12 +1255,16 @@ TString TOutputGLSLBase::hashVariableName(const TString &name)
return hashName(name);
}
TString TOutputGLSLBase::hashFunctionName(const TString &mangled_name)
TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TName &mangledName)
{
TString name = TFunction::unmangleName(mangled_name);
if (mSymbolTable.findBuiltIn(mangled_name, mShaderVersion) != NULL || name == "main")
TString mangledStr = mangledName.getString();
TString name = TFunction::unmangleName(mangledStr);
if (mSymbolTable.findBuiltIn(mangledStr, mShaderVersion) != nullptr || name == "main")
return translateTextureFunction(name);
return hashName(name);
if (mangledName.isInternal())
return name;
else
return hashName(name);
}
bool TOutputGLSLBase::structDeclared(const TStructure *structure) const
@ -1272,3 +1297,70 @@ void TOutputGLSLBase::declareStruct(const TStructure *structure)
out << "}";
}
void TOutputGLSLBase::declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock)
{
TInfoSinkBase &out = objSink();
out << "layout(";
switch (interfaceBlock->blockStorage())
{
case EbsUnspecified:
case EbsShared:
// Default block storage is shared.
out << "shared";
break;
case EbsPacked:
out << "packed";
break;
case EbsStd140:
out << "std140";
break;
default:
UNREACHABLE();
break;
}
out << ", ";
switch (interfaceBlock->matrixPacking())
{
case EmpUnspecified:
case EmpColumnMajor:
// Default matrix packing is column major.
out << "column_major";
break;
case EmpRowMajor:
out << "row_major";
break;
default:
UNREACHABLE();
break;
}
out << ") ";
}
void TOutputGLSLBase::declareInterfaceBlock(const TInterfaceBlock *interfaceBlock)
{
TInfoSinkBase &out = objSink();
out << hashName(interfaceBlock->name()) << "{\n";
const TFieldList &fields = interfaceBlock->fields();
for (size_t i = 0; i < fields.size(); ++i)
{
const TField *field = fields[i];
if (writeVariablePrecision(field->type()->getPrecision()))
out << " ";
out << getTypeName(*field->type()) << " " << hashName(field->name());
if (field->type()->isArray())
out << arrayBrackets(*field->type());
out << ";\n";
}
out << "}";
}

View File

@ -39,16 +39,16 @@ class TOutputGLSLBase : public TIntermTraverser
void writeConstructorTriplet(Visit visit, const TType &type, const char *constructorBaseType);
TString getTypeName(const TType &type);
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 visitSwitch(Visit visit, TIntermSwitch *node);
virtual bool visitCase(Visit visit, TIntermCase *node);
virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
virtual bool visitLoop(Visit visit, TIntermLoop *node);
virtual bool visitBranch(Visit visit, TIntermBranch *node);
void visitSymbol(TIntermSymbol *node) override;
void visitConstantUnion(TIntermConstantUnion *node) override;
bool visitBinary(Visit visit, TIntermBinary *node) override;
bool visitUnary(Visit visit, TIntermUnary *node) override;
bool visitSelection(Visit visit, TIntermSelection *node) override;
bool visitSwitch(Visit visit, TIntermSwitch *node) override;
bool visitCase(Visit visit, TIntermCase *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
bool visitLoop(Visit visit, TIntermLoop *node) override;
bool visitBranch(Visit visit, TIntermBranch *node) override;
void visitCodeBlock(TIntermNode *node);
@ -57,8 +57,8 @@ class TOutputGLSLBase : public TIntermTraverser
TString hashName(const TString &name);
// Same as hashName(), but without hashing built-in variables.
TString hashVariableName(const TString &name);
// Same as hashName(), but without hashing built-in functions.
TString hashFunctionName(const TString &mangled_name);
// Same as hashName(), but without hashing built-in functions and with unmangling.
TString hashFunctionNameIfNeeded(const TName &mangledName);
// Used to translate function names for differences between ESSL and GLSL
virtual TString translateTextureFunction(TString &name) { return name; }
@ -66,6 +66,9 @@ class TOutputGLSLBase : public TIntermTraverser
bool structDeclared(const TStructure *structure) const;
void declareStruct(const TStructure *structure);
void declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock);
void declareInterfaceBlock(const TInterfaceBlock *interfaceBlock);
void writeBuiltInFunctionTriplet(Visit visit, const char *preStr, bool useEmulatedFunction);
TInfoSinkBase &mObjSink;

View File

@ -1386,18 +1386,14 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
mUsesInstanceID = true;
out << name;
}
else if (name == "gl_FragDepthEXT" || name == "gl_FragDepth")
else if (name == "gl_FragDepthEXT")
{
mUsesFragDepth = true;
out << "gl_Depth";
}
else if (node->isInternal())
{
out << name;
}
else
{
out << Decorate(name);
out << DecorateIfNeeded(node->getName());
}
}
}
@ -1943,7 +1939,9 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
return false;
}
out << TypeString(node->getType()) << " " << Decorate(TFunction::unmangleName(node->getName())) << (mOutputLod0Function ? "Lod0(" : "(");
TString name = DecorateFunctionIfNeeded(node->getNameObj());
out << TypeString(node->getType()) << " " << name
<< (mOutputLod0Function ? "Lod0(" : "(");
TIntermSequence *arguments = node->getSequence();
@ -1981,7 +1979,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpFunction:
{
ASSERT(mCurrentFunctionMetadata == nullptr);
TString name = TFunction::unmangleName(node->getName());
TString name = TFunction::unmangleName(node->getNameObj().getString());
size_t index = mCallDag.findIndex(node);
ASSERT(index != CallDAG::InvalidIndex);
@ -1995,7 +1993,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
}
else
{
out << Decorate(name) << (mOutputLod0Function ? "Lod0(" : "(");
out << DecorateFunctionIfNeeded(node->getNameObj())
<< (mOutputLod0Function ? "Lod0(" : "(");
}
TIntermSequence *sequence = node->getSequence();
@ -2051,7 +2050,6 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
break;
case EOpFunctionCall:
{
TString name = TFunction::unmangleName(node->getName());
TIntermSequence *arguments = node->getSequence();
bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function;
@ -2065,10 +2063,11 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
ASSERT(index != CallDAG::InvalidIndex);
lod0 &= mASTMetadataList[index].mNeedsLod0;
out << Decorate(name) << (lod0 ? "Lod0(" : "(");
out << DecorateFunctionIfNeeded(node->getNameObj()) << (lod0 ? "Lod0(" : "(");
}
else
{
TString name = TFunction::unmangleName(node->getNameObj().getString());
TBasicType samplerType = (*arguments)[0]->getAsTyped()->getType().getBasicType();
TextureFunction textureFunction;
@ -2375,9 +2374,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
}
// D3D errors when there is a gradient operation in a loop in an unflattened if.
if (mShaderType == GL_FRAGMENT_SHADER &&
mCurrentFunctionMetadata->hasDiscontinuousLoop(node) &&
mCurrentFunctionMetadata->hasGradientInCallGraph(node))
if (mShaderType == GL_FRAGMENT_SHADER && mCurrentFunctionMetadata->hasGradientLoop(node))
{
out << "FLATTEN ";
}
@ -2849,25 +2846,27 @@ void OutputHLSL::outputLineDirective(int line)
TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
{
TQualifier qualifier = symbol->getQualifier();
const TType &type = symbol->getType();
TString name = symbol->getSymbol();
const TType &type = symbol->getType();
const TName &name = symbol->getName();
TString nameStr;
if (name.empty()) // HLSL demands named arguments, also for prototypes
if (name.getString().empty()) // HLSL demands named arguments, also for prototypes
{
name = "x" + str(mUniqueIndex++);
nameStr = "x" + str(mUniqueIndex++);
}
else if (!symbol->isInternal())
else
{
name = Decorate(name);
nameStr = DecorateIfNeeded(name);
}
if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType()))
{
return QualifierString(qualifier) + " " + TextureString(type) + " texture_" + name + ArrayString(type) + ", " +
QualifierString(qualifier) + " " + SamplerString(type) + " sampler_" + name + ArrayString(type);
return QualifierString(qualifier) + " " + TextureString(type) + " texture_" + nameStr +
ArrayString(type) + ", " + QualifierString(qualifier) + " " + SamplerString(type) +
" sampler_" + nameStr + ArrayString(type);
}
return QualifierString(qualifier) + " " + TypeString(type) + " " + name + ArrayString(type);
return QualifierString(qualifier) + " " + TypeString(type) + " " + nameStr + ArrayString(type);
}
TString OutputHLSL::initializer(const TType &type)

File diff suppressed because it is too large Load Diff

View File

@ -58,7 +58,8 @@ class TParseContext : angle::NonCopyable
mPreprocessor(&mDiagnostics, &mDirectiveHandler),
mScanner(nullptr),
mUsesFragData(false),
mUsesFragColor(false)
mUsesFragColor(false),
mUsesSecondaryOutputs(false)
{
}
@ -113,7 +114,6 @@ class TParseContext : angle::NonCopyable
const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line);
bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc &line);
bool reservedErrorCheck(const TSourceLoc &line, const TString &identifier);
void assignError(const TSourceLoc &line, const char *op, TString left, TString right);
@ -140,6 +140,9 @@ class TParseContext : angle::NonCopyable
bool layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier);
bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation);
void es3InputOutputTypeCheck(const TQualifier qualifier,
const TPublicType &type,
const TSourceLoc &qualifierLocation);
const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
const TExtensionBehavior &extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); }
@ -349,6 +352,8 @@ class TParseContext : angle::NonCopyable
void *mScanner;
bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor
bool mUsesFragColor;
bool mUsesSecondaryOutputs; // Track if we are using either gl_SecondaryFragData or
// gl_Secondary FragColor or both.
};
int PaParseStrings(

View File

@ -23,8 +23,8 @@ class RegenerateStructNames : public TIntermTraverser
mScopeDepth(0) {}
protected:
virtual void visitSymbol(TIntermSymbol *);
virtual bool visitAggregate(Visit, TIntermAggregate *);
void visitSymbol(TIntermSymbol *) override;
bool visitAggregate(Visit, TIntermAggregate *) override;
private:
const TSymbolTable &mSymbolTable;

View File

@ -0,0 +1,508 @@
//
// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of vectors and matrices,
// replacing them with calls to functions that choose which component to return or write.
//
#include "compiler/translator/RemoveDynamicIndexing.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
namespace
{
TName GetIndexFunctionName(const TType &type, bool write)
{
TInfoSinkBase nameSink;
nameSink << "dyn_index_";
if (write)
{
nameSink << "write_";
}
if (type.isMatrix())
{
nameSink << "mat" << type.getCols() << "x" << type.getRows();
}
else
{
switch (type.getBasicType())
{
case EbtInt:
nameSink << "ivec";
break;
case EbtBool:
nameSink << "bvec";
break;
case EbtUInt:
nameSink << "uvec";
break;
case EbtFloat:
nameSink << "vec";
break;
default:
UNREACHABLE();
}
nameSink << type.getNominalSize();
}
TString nameString = TFunction::mangleName(nameSink.c_str());
TName name(nameString);
name.setInternal(true);
return name;
}
TIntermSymbol *CreateBaseSymbol(const TType &type)
{
TIntermSymbol *symbol = new TIntermSymbol(0, "base", type);
symbol->setInternal(true);
return symbol;
}
TIntermSymbol *CreateIndexSymbol()
{
TIntermSymbol *symbol = new TIntermSymbol(0, "index", TType(EbtInt, EbpHigh));
symbol->setInternal(true);
return symbol;
}
TIntermSymbol *CreateValueSymbol(const TType &type)
{
TIntermSymbol *symbol = new TIntermSymbol(0, "value", type);
symbol->setInternal(true);
return symbol;
}
TIntermConstantUnion *CreateIntConstantNode(int i)
{
TConstantUnion *constant = new TConstantUnion();
constant->setIConst(i);
return new TIntermConstantUnion(constant, TType(EbtInt, EbpHigh));
}
TIntermBinary *CreateIndexDirectBaseSymbolNode(const TType &indexedType,
const TType &fieldType,
const int index)
{
TIntermBinary *indexNode = new TIntermBinary(EOpIndexDirect);
indexNode->setType(fieldType);
indexNode->setLeft(CreateBaseSymbol(indexedType));
indexNode->setRight(CreateIntConstantNode(index));
return indexNode;
}
TIntermBinary *CreateAssignValueSymbolNode(TIntermTyped *targetNode, const TType &assignedValueType)
{
TIntermBinary *assignNode = new TIntermBinary(EOpAssign);
assignNode->setType(assignedValueType);
assignNode->setLeft(targetNode);
assignNode->setRight(CreateValueSymbol(assignedValueType));
return assignNode;
}
TIntermTyped *EnsureSignedInt(TIntermTyped *node)
{
if (node->getBasicType() == EbtInt)
return node;
TIntermAggregate *convertedNode = new TIntermAggregate(EOpConstructInt);
convertedNode->setType(TType(EbtInt));
convertedNode->getSequence()->push_back(node);
convertedNode->setPrecisionFromChildren();
return convertedNode;
}
TType GetFieldType(const TType &indexedType)
{
if (indexedType.isMatrix())
{
TType fieldType = TType(indexedType.getBasicType(), indexedType.getPrecision());
fieldType.setPrimarySize(static_cast<unsigned char>(indexedType.getRows()));
return fieldType;
}
else
{
return TType(indexedType.getBasicType(), indexedType.getPrecision());
}
}
// Generate a read or write function for one field in a vector/matrix.
// Out-of-range indices are clamped. This is consistent with how ANGLE handles out-of-range
// indices in other places.
// Note that indices can be either int or uint. We create only int versions of the functions,
// and convert uint indices to int at the call site.
// read function example:
// float dyn_index_vec2(in vec2 base, in int index)
// {
// switch(index)
// {
// case (0):
// return base[0];
// case (1):
// return base[1];
// default:
// break;
// }
// if (index < 0)
// return base[0];
// return base[1];
// }
// write function example:
// void dyn_index_write_vec2(inout vec2 base, in int index, in float value)
// {
// switch(index)
// {
// case (0):
// base[0] = value;
// return;
// case (1):
// base[1] = value;
// return;
// default:
// break;
// }
// if (index < 0)
// {
// base[0] = value;
// return;
// }
// base[1] = value;
// }
// Note that else is not used in above functions to avoid the RewriteElseBlocks transformation.
TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write)
{
ASSERT(!type.isArray());
// Conservatively use highp here, even if the indexed type is not highp. That way the code can't
// end up using mediump version of an indexing function for a highp value, if both mediump and
// highp values are being indexed in the shader. For HLSL precision doesn't matter, but in
// principle this code could be used with multiple backends.
type.setPrecision(EbpHigh);
TIntermAggregate *indexingFunction = new TIntermAggregate(EOpFunction);
indexingFunction->setNameObj(GetIndexFunctionName(type, write));
TType fieldType = GetFieldType(type);
int numCases = 0;
if (type.isMatrix())
{
numCases = type.getCols();
}
else
{
numCases = type.getNominalSize();
}
if (write)
{
indexingFunction->setType(TType(EbtVoid));
}
else
{
indexingFunction->setType(fieldType);
}
TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters);
TIntermSymbol *baseParam = CreateBaseSymbol(type);
if (write)
baseParam->getTypePointer()->setQualifier(EvqInOut);
else
baseParam->getTypePointer()->setQualifier(EvqIn);
paramsNode->getSequence()->push_back(baseParam);
TIntermSymbol *indexParam = CreateIndexSymbol();
indexParam->getTypePointer()->setQualifier(EvqIn);
paramsNode->getSequence()->push_back(indexParam);
if (write)
{
TIntermSymbol *valueParam = CreateValueSymbol(fieldType);
valueParam->getTypePointer()->setQualifier(EvqIn);
paramsNode->getSequence()->push_back(valueParam);
}
indexingFunction->getSequence()->push_back(paramsNode);
TIntermAggregate *statementList = new TIntermAggregate(EOpSequence);
for (int i = 0; i < numCases; ++i)
{
TIntermCase *caseNode = new TIntermCase(CreateIntConstantNode(i));
statementList->getSequence()->push_back(caseNode);
TIntermBinary *indexNode = CreateIndexDirectBaseSymbolNode(type, fieldType, i);
if (write)
{
TIntermBinary *assignNode = CreateAssignValueSymbolNode(indexNode, fieldType);
statementList->getSequence()->push_back(assignNode);
TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr);
statementList->getSequence()->push_back(returnNode);
}
else
{
TIntermBranch *returnNode = new TIntermBranch(EOpReturn, indexNode);
statementList->getSequence()->push_back(returnNode);
}
}
// Default case
TIntermCase *defaultNode = new TIntermCase(nullptr);
statementList->getSequence()->push_back(defaultNode);
TIntermBranch *breakNode = new TIntermBranch(EOpBreak, nullptr);
statementList->getSequence()->push_back(breakNode);
TIntermSwitch *switchNode = new TIntermSwitch(CreateIndexSymbol(), statementList);
TIntermAggregate *bodyNode = new TIntermAggregate(EOpSequence);
bodyNode->getSequence()->push_back(switchNode);
TIntermBinary *cond = new TIntermBinary(EOpLessThan);
cond->setType(TType(EbtBool, EbpUndefined));
cond->setLeft(CreateIndexSymbol());
cond->setRight(CreateIntConstantNode(0));
// Two blocks: one accesses (either reads or writes) the first element and returns,
// the other accesses the last element.
TIntermAggregate *useFirstBlock = new TIntermAggregate(EOpSequence);
TIntermAggregate *useLastBlock = new TIntermAggregate(EOpSequence);
TIntermBinary *indexFirstNode = CreateIndexDirectBaseSymbolNode(type, fieldType, 0);
TIntermBinary *indexLastNode = CreateIndexDirectBaseSymbolNode(type, fieldType, numCases - 1);
if (write)
{
TIntermBinary *assignFirstNode = CreateAssignValueSymbolNode(indexFirstNode, fieldType);
useFirstBlock->getSequence()->push_back(assignFirstNode);
TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr);
useFirstBlock->getSequence()->push_back(returnNode);
TIntermBinary *assignLastNode = CreateAssignValueSymbolNode(indexLastNode, fieldType);
useLastBlock->getSequence()->push_back(assignLastNode);
}
else
{
TIntermBranch *returnFirstNode = new TIntermBranch(EOpReturn, indexFirstNode);
useFirstBlock->getSequence()->push_back(returnFirstNode);
TIntermBranch *returnLastNode = new TIntermBranch(EOpReturn, indexLastNode);
useLastBlock->getSequence()->push_back(returnLastNode);
}
TIntermSelection *ifNode = new TIntermSelection(cond, useFirstBlock, nullptr);
bodyNode->getSequence()->push_back(ifNode);
bodyNode->getSequence()->push_back(useLastBlock);
indexingFunction->getSequence()->push_back(bodyNode);
return indexingFunction;
}
class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser
{
public:
RemoveDynamicIndexingTraverser(const TSymbolTable &symbolTable, int shaderVersion);
bool visitBinary(Visit visit, TIntermBinary *node) override;
void insertHelperDefinitions(TIntermNode *root);
void nextIteration();
bool usedTreeInsertion() const { return mUsedTreeInsertion; }
protected:
// Sets of types that are indexed. Note that these can not store multiple variants
// of the same type with different precisions - only one precision gets stored.
std::set<TType> mIndexedVecAndMatrixTypes;
std::set<TType> mWrittenVecAndMatrixTypes;
bool mUsedTreeInsertion;
// When true, the traverser will remove side effects from any indexing expression.
// This is done so that in code like
// V[j++][i]++.
// where V is an array of vectors, j++ will only be evaluated once.
bool mRemoveIndexSideEffectsInSubtree;
};
RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(const TSymbolTable &symbolTable,
int shaderVersion)
: TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion),
mUsedTreeInsertion(false),
mRemoveIndexSideEffectsInSubtree(false)
{
}
void RemoveDynamicIndexingTraverser::insertHelperDefinitions(TIntermNode *root)
{
TIntermAggregate *rootAgg = root->getAsAggregate();
ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence);
TIntermSequence insertions;
for (TType type : mIndexedVecAndMatrixTypes)
{
insertions.push_back(GetIndexFunctionDefinition(type, false));
}
for (TType type : mWrittenVecAndMatrixTypes)
{
insertions.push_back(GetIndexFunctionDefinition(type, true));
}
mInsertions.push_back(NodeInsertMultipleEntry(rootAgg, 0, insertions, TIntermSequence()));
}
// Create a call to dyn_index_*() based on an indirect indexing op node
TIntermAggregate *CreateIndexFunctionCall(TIntermBinary *node,
TIntermTyped *indexedNode,
TIntermTyped *index)
{
ASSERT(node->getOp() == EOpIndexIndirect);
TIntermAggregate *indexingCall = new TIntermAggregate(EOpFunctionCall);
indexingCall->setLine(node->getLine());
indexingCall->setUserDefined();
indexingCall->setNameObj(GetIndexFunctionName(indexedNode->getType(), false));
indexingCall->getSequence()->push_back(indexedNode);
indexingCall->getSequence()->push_back(index);
TType fieldType = GetFieldType(indexedNode->getType());
indexingCall->setType(fieldType);
return indexingCall;
}
TIntermAggregate *CreateIndexedWriteFunctionCall(TIntermBinary *node,
TIntermTyped *index,
TIntermTyped *writtenValue)
{
// Deep copy the left node so that two pointers to the same node don't end up in the tree.
TIntermNode *leftCopy = node->getLeft()->deepCopy();
ASSERT(leftCopy != nullptr && leftCopy->getAsTyped() != nullptr);
TIntermAggregate *indexedWriteCall =
CreateIndexFunctionCall(node, leftCopy->getAsTyped(), index);
indexedWriteCall->setNameObj(GetIndexFunctionName(node->getLeft()->getType(), true));
indexedWriteCall->setType(TType(EbtVoid));
indexedWriteCall->getSequence()->push_back(writtenValue);
return indexedWriteCall;
}
bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *node)
{
if (mUsedTreeInsertion)
return false;
if (node->getOp() == EOpIndexIndirect)
{
if (mRemoveIndexSideEffectsInSubtree)
{
ASSERT(node->getRight()->hasSideEffects());
// In case we're just removing index side effects, convert
// v_expr[index_expr]
// to this:
// int s0 = index_expr; v_expr[s0];
// Now v_expr[s0] can be safely executed several times without unintended side effects.
// Init the temp variable holding the index
TIntermAggregate *initIndex = createTempInitDeclaration(node->getRight());
TIntermSequence insertions;
insertions.push_back(initIndex);
insertStatementsInParentBlock(insertions);
mUsedTreeInsertion = true;
// Replace the index with the temp variable
TIntermSymbol *tempIndex = createTempSymbol(node->getRight()->getType());
NodeUpdateEntry replaceIndex(node, node->getRight(), tempIndex, false);
mReplacements.push_back(replaceIndex);
}
else if (!node->getLeft()->isArray() && node->getLeft()->getBasicType() != EbtStruct)
{
bool write = isLValueRequiredHere();
TType type = node->getLeft()->getType();
mIndexedVecAndMatrixTypes.insert(type);
if (write)
{
// Convert:
// v_expr[index_expr]++;
// to this:
// int s0 = index_expr; float s1 = dyn_index(v_expr, s0); s1++;
// dyn_index_write(v_expr, s0, s1);
// This works even if index_expr has some side effects.
if (node->getLeft()->hasSideEffects())
{
// If v_expr has side effects, those need to be removed before proceeding.
// Otherwise the side effects of v_expr would be evaluated twice.
// The only case where an l-value can have side effects is when it is
// indexing. For example, it can be V[j++] where V is an array of vectors.
mRemoveIndexSideEffectsInSubtree = true;
return true;
}
// TODO(oetuaho@nvidia.com): This is not optimal if the expression using the value
// only writes it and doesn't need the previous value. http://anglebug.com/1116
mWrittenVecAndMatrixTypes.insert(type);
TType fieldType = GetFieldType(type);
TIntermSequence insertionsBefore;
TIntermSequence insertionsAfter;
// Store the index in a temporary signed int variable.
TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight());
TIntermAggregate *initIndex = createTempInitDeclaration(indexInitializer);
initIndex->setLine(node->getLine());
insertionsBefore.push_back(initIndex);
TIntermAggregate *indexingCall = CreateIndexFunctionCall(
node, node->getLeft(), createTempSymbol(indexInitializer->getType()));
// Create a node for referring to the index after the nextTemporaryIndex() call
// below.
TIntermSymbol *tempIndex = createTempSymbol(indexInitializer->getType());
nextTemporaryIndex(); // From now on, creating temporary symbols that refer to the
// field value.
insertionsBefore.push_back(createTempInitDeclaration(indexingCall));
TIntermAggregate *indexedWriteCall =
CreateIndexedWriteFunctionCall(node, tempIndex, createTempSymbol(fieldType));
insertionsAfter.push_back(indexedWriteCall);
insertStatementsInParentBlock(insertionsBefore, insertionsAfter);
NodeUpdateEntry replaceIndex(getParentNode(), node, createTempSymbol(fieldType),
false);
mReplacements.push_back(replaceIndex);
mUsedTreeInsertion = true;
}
else
{
// The indexed value is not being written, so we can simply convert
// v_expr[index_expr]
// into
// dyn_index(v_expr, index_expr)
// If the index_expr is unsigned, we'll convert it to signed.
ASSERT(!mRemoveIndexSideEffectsInSubtree);
TIntermAggregate *indexingCall = CreateIndexFunctionCall(
node, node->getLeft(), EnsureSignedInt(node->getRight()));
NodeUpdateEntry replaceIndex(getParentNode(), node, indexingCall, false);
mReplacements.push_back(replaceIndex);
}
}
}
return !mUsedTreeInsertion;
}
void RemoveDynamicIndexingTraverser::nextIteration()
{
mUsedTreeInsertion = false;
mRemoveIndexSideEffectsInSubtree = false;
nextTemporaryIndex();
}
} // namespace
void RemoveDynamicIndexing(TIntermNode *root,
unsigned int *temporaryIndex,
const TSymbolTable &symbolTable,
int shaderVersion)
{
RemoveDynamicIndexingTraverser traverser(symbolTable, shaderVersion);
ASSERT(temporaryIndex != nullptr);
traverser.useTemporaryIndex(temporaryIndex);
do
{
traverser.nextIteration();
root->traverse(&traverser);
traverser.updateTree();
} while (traverser.usedTreeInsertion());
traverser.insertHelperDefinitions(root);
traverser.updateTree();
}

View File

@ -0,0 +1,21 @@
//
// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of vectors and matrices,
// replacing them with calls to functions that choose which component to return or write.
//
#ifndef COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
#define COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
class TIntermNode;
class TSymbolTable;
void RemoveDynamicIndexing(TIntermNode *root,
unsigned int *temporaryIndex,
const TSymbolTable &symbolTable,
int shaderVersion);
#endif // COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_

View File

@ -20,7 +20,7 @@ public:
, mOldFunctionName(oldFunctionName)
, mNewFunctionName(newFunctionName) {}
virtual bool visitAggregate(Visit visit, TIntermAggregate* node)
bool visitAggregate(Visit visit, TIntermAggregate *node) override
{
TOperator op = node->getOp();
if ((op == EOpFunction || op == EOpFunctionCall) && node->getName() == mOldFunctionName)

View File

@ -20,7 +20,7 @@ class ScalarizeVecAndMatConstructorArgs : public TIntermTraverser
mFragmentPrecisionHigh(fragmentPrecisionHigh) {}
protected:
virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
private:
void scalarizeArgs(TIntermAggregate *aggregate,

View File

@ -20,7 +20,7 @@ class SearchSymbol : public TIntermTraverser
SearchSymbol(const TString &symbol);
void traverse(TIntermNode *node);
void visitSymbol(TIntermSymbol *symbolNode);
void visitSymbol(TIntermSymbol *symbolNode) override;
bool foundMatch() const;

View File

@ -23,15 +23,6 @@
namespace
{
enum ShaderVariableType
{
SHADERVAR_UNIFORM,
SHADERVAR_VARYING,
SHADERVAR_ATTRIBUTE,
SHADERVAR_OUTPUTVARIABLE,
SHADERVAR_INTERFACEBLOCK
};
bool isInitialized = false;
//
@ -40,36 +31,40 @@ bool isInitialized = false;
//
template <typename VarT>
const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
const std::vector<VarT> *GetVariableList(const TCompiler *compiler);
template <>
const std::vector<sh::Uniform> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
const std::vector<sh::Uniform> *GetVariableList(const TCompiler *compiler)
{
return &compiler->getUniforms();
}
template <>
const std::vector<sh::Varying> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
const std::vector<sh::Varying> *GetVariableList(const TCompiler *compiler)
{
return &compiler->getVaryings();
}
template <>
const std::vector<sh::Attribute> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType)
const std::vector<sh::Attribute> *GetVariableList(const TCompiler *compiler)
{
return (variableType == SHADERVAR_ATTRIBUTE ?
&compiler->getAttributes() :
&compiler->getOutputVariables());
return &compiler->getAttributes();
}
template <>
const std::vector<sh::InterfaceBlock> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
const std::vector<sh::OutputVariable> *GetVariableList(const TCompiler *compiler)
{
return &compiler->getOutputVariables();
}
template <>
const std::vector<sh::InterfaceBlock> *GetVariableList(const TCompiler *compiler)
{
return &compiler->getInterfaceBlocks();
}
template <typename VarT>
const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariableType variableType)
const std::vector<VarT> *GetShaderVariables(const ShHandle handle)
{
if (!handle)
{
@ -83,7 +78,7 @@ const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariabl
return NULL;
}
return GetVariableList<VarT>(compiler, variableType);
return GetVariableList<VarT>(compiler);
}
TCompiler *GetCompilerFromHandle(ShHandle handle)
@ -104,7 +99,7 @@ TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
}
#endif // ANGLE_ENABLE_HLSL
} // namespace anonymous
} // anonymous namespace
//
// Driver must call this first, once, before doing any other compiler operations.
@ -154,6 +149,7 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->OES_standard_derivatives = 0;
resources->OES_EGL_image_external = 0;
resources->ARB_texture_rectangle = 0;
resources->EXT_blend_func_extended = 0;
resources->EXT_draw_buffers = 0;
resources->EXT_frag_depth = 0;
resources->EXT_shader_texture_lod = 0;
@ -173,6 +169,9 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->MinProgramTexelOffset = -8;
resources->MaxProgramTexelOffset = 7;
// Extensions constants.
resources->MaxDualSourceDrawBuffers = 0;
// Disable name hashing by default.
resources->HashFunction = NULL;
@ -295,27 +294,27 @@ const std::map<std::string, std::string> *ShGetNameHashingMap(
const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
{
return GetShaderVariables<sh::Uniform>(handle, SHADERVAR_UNIFORM);
return GetShaderVariables<sh::Uniform>(handle);
}
const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle)
{
return GetShaderVariables<sh::Varying>(handle, SHADERVAR_VARYING);
return GetShaderVariables<sh::Varying>(handle);
}
const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle)
{
return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_ATTRIBUTE);
return GetShaderVariables<sh::Attribute>(handle);
}
const std::vector<sh::Attribute> *ShGetOutputVariables(const ShHandle handle)
const std::vector<sh::OutputVariable> *ShGetOutputVariables(const ShHandle handle)
{
return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_OUTPUTVARIABLE);
return GetShaderVariables<sh::OutputVariable>(handle);
}
const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle)
{
return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
return GetShaderVariables<sh::InterfaceBlock>(handle);
}
bool ShCheckVariablesWithinPackingLimits(

View File

@ -217,31 +217,75 @@ bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
return ShaderVariable::isSameVariableAtLinkTime(other, true);
}
Attribute::Attribute()
: location(-1)
InterfaceVariable::InterfaceVariable() : location(-1)
{}
Attribute::~Attribute()
InterfaceVariable::~InterfaceVariable()
{}
Attribute::Attribute(const Attribute &other)
: ShaderVariable(other),
location(other.location)
InterfaceVariable::InterfaceVariable(const InterfaceVariable &other)
: ShaderVariable(other), location(other.location)
{}
Attribute &Attribute::operator=(const Attribute &other)
InterfaceVariable &InterfaceVariable::operator=(const InterfaceVariable &other)
{
ShaderVariable::operator=(other);
location = other.location;
return *this;
}
bool Attribute::operator==(const Attribute &other) const
bool InterfaceVariable::operator==(const InterfaceVariable &other) const
{
return (ShaderVariable::operator==(other) &&
location == other.location);
}
Attribute::Attribute()
{
}
Attribute::~Attribute()
{
}
Attribute::Attribute(const Attribute &other) : InterfaceVariable(other)
{
}
Attribute &Attribute::operator=(const Attribute &other)
{
InterfaceVariable::operator=(other);
return *this;
}
bool Attribute::operator==(const Attribute &other) const
{
return InterfaceVariable::operator==(other);
}
OutputVariable::OutputVariable()
{
}
OutputVariable::~OutputVariable()
{
}
OutputVariable::OutputVariable(const OutputVariable &other) : InterfaceVariable(other)
{
}
OutputVariable &OutputVariable::operator=(const OutputVariable &other)
{
InterfaceVariable::operator=(other);
return *this;
}
bool OutputVariable::operator==(const OutputVariable &other) const
{
return InterfaceVariable::operator==(other);
}
InterfaceBlockField::InterfaceBlockField()
: isRowMajorLayout(false)
{}

View File

@ -32,14 +32,14 @@ TFunction::~TFunction()
const TString *TFunction::buildMangledName() const
{
std::string mangledName = mangleName(getName()).c_str();
std::string newName = mangleName(getName()).c_str();
for (const auto &p : parameters)
{
mangledName += p.type->getMangledName().c_str();
newName += p.type->getMangledName().c_str();
}
return NewPoolTString(mangledName.c_str());
return NewPoolTString(newName.c_str());
}
//

View File

@ -109,13 +109,8 @@ class TVariable : public TSymbol
unionArray(0)
{
}
virtual ~TVariable()
{
}
virtual bool isVariable() const
{
return true;
}
~TVariable() override {}
bool isVariable() const override { return true; }
TType &getType()
{
return type;
@ -229,11 +224,8 @@ class TFunction : public TSymbol
{
relateToExtension(ext);
}
virtual ~TFunction();
virtual bool isFunction() const
{
return true;
}
~TFunction() override;
bool isFunction() const override { return true; }
static TString mangleName(const TString &name)
{
@ -250,7 +242,7 @@ class TFunction : public TSymbol
mangledName = nullptr;
}
const TString &getMangledName() const
const TString &getMangledName() const override
{
if (mangledName == nullptr)
{
@ -412,6 +404,14 @@ class TSymbolTable : angle::NonCopyable
return insert(level, constant);
}
bool insertConstIntExt(ESymbolLevel level, const char *ext, const char *name, int value)
{
TVariable *constant =
new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
constant->getConstPointer()->setIConst(value);
return insert(level, ext, constant);
}
void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name,
const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0);

View File

@ -28,10 +28,10 @@ void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, i
void TranslatorESSL::translate(TIntermNode *root, int) {
TInfoSinkBase& sink = getInfoSink().obj;
int shaderVersion = getShaderVersion();
if (shaderVersion > 100)
int shaderVer = getShaderVersion();
if (shaderVer > 100)
{
sink << "#version " << shaderVersion << " es\n";
sink << "#version " << shaderVer << " es\n";
}
writePragma();
@ -43,7 +43,7 @@ void TranslatorESSL::translate(TIntermNode *root, int) {
if (precisionEmulation)
{
EmulatePrecision emulatePrecision;
EmulatePrecision emulatePrecision(getSymbolTable(), shaderVer);
root->traverse(&emulatePrecision);
emulatePrecision.updateTree();
emulatePrecision.writeEmulationHelpers(sink, SH_ESSL_OUTPUT);
@ -78,13 +78,8 @@ void TranslatorESSL::translate(TIntermNode *root, int) {
getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
// Write translated shader.
TOutputESSL outputESSL(sink,
getArrayIndexClampingStrategy(),
getHashFunction(),
getNameMap(),
getSymbolTable(),
shaderVersion,
precisionEmulation);
TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(),
getSymbolTable(), shaderVer, precisionEmulation);
root->traverse(&outputESSL);
}

View File

@ -44,7 +44,7 @@ void TranslatorGLSL::translate(TIntermNode *root, int) {
if (precisionEmulation)
{
EmulatePrecision emulatePrecision;
EmulatePrecision emulatePrecision(getSymbolTable(), getShaderVersion());
root->traverse(&emulatePrecision);
emulatePrecision.updateTree();
emulatePrecision.writeEmulationHelpers(sink, getOutputType());
@ -64,30 +64,70 @@ void TranslatorGLSL::translate(TIntermNode *root, int) {
// Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData
// if it's core profile shaders and they are used.
if (getShaderType() == GL_FRAGMENT_SHADER && IsGLSL130OrNewer(getOutputType()))
if (getShaderType() == GL_FRAGMENT_SHADER)
{
bool usesGLFragColor = false;
bool usesGLFragData = false;
for (auto outputVar : outputVariables)
const bool mayHaveESSL1SecondaryOutputs =
IsExtensionEnabled(getExtensionBehavior(), "GL_EXT_blend_func_extended") &&
getShaderVersion() == 100;
const bool declareGLFragmentOutputs = IsGLSL130OrNewer(getOutputType());
bool hasGLFragColor = false;
bool hasGLFragData = false;
bool hasGLSecondaryFragColor = false;
bool hasGLSecondaryFragData = false;
for (const auto &outputVar : outputVariables)
{
if (outputVar.name == "gl_FragColor")
if (declareGLFragmentOutputs)
{
usesGLFragColor = true;
if (outputVar.name == "gl_FragColor")
{
ASSERT(!hasGLFragColor);
hasGLFragColor = true;
continue;
}
else if (outputVar.name == "gl_FragData")
{
ASSERT(!hasGLFragData);
hasGLFragData = true;
continue;
}
}
else if (outputVar.name == "gl_FragData")
if (mayHaveESSL1SecondaryOutputs)
{
usesGLFragData = true;
if (outputVar.name == "gl_SecondaryFragColorEXT")
{
ASSERT(!hasGLSecondaryFragColor);
hasGLSecondaryFragColor = true;
continue;
}
else if (outputVar.name == "gl_SecondaryFragDataEXT")
{
ASSERT(!hasGLSecondaryFragData);
hasGLSecondaryFragData = true;
continue;
}
}
}
ASSERT(!(usesGLFragColor && usesGLFragData));
if (usesGLFragColor)
ASSERT(!((hasGLFragColor || hasGLSecondaryFragColor) &&
(hasGLFragData || hasGLSecondaryFragData)));
if (hasGLFragColor)
{
sink << "out vec4 webgl_FragColor;\n";
}
if (usesGLFragData)
if (hasGLFragData)
{
sink << "out vec4 webgl_FragData[gl_MaxDrawBuffers];\n";
}
if (hasGLSecondaryFragColor)
{
sink << "out vec4 angle_SecondaryFragColor;\n";
}
if (hasGLSecondaryFragData)
{
sink << "out vec4 angle_SecondaryFragData[" << getResources().MaxDualSourceDrawBuffers
<< "];\n";
}
}
// Write translated shader.

View File

@ -8,6 +8,7 @@
#include "compiler/translator/ArrayReturnValueToOutParameter.h"
#include "compiler/translator/OutputHLSL.h"
#include "compiler/translator/RemoveDynamicIndexing.h"
#include "compiler/translator/RewriteElseBlocks.h"
#include "compiler/translator/SeparateArrayInitialization.h"
#include "compiler/translator/SeparateDeclarations.h"
@ -40,6 +41,12 @@ void TranslatorHLSL::translate(TIntermNode *root, int compileOptions)
// as a return value to use an out parameter to transfer the array data instead.
ArrayReturnValueToOutParameter(root, &temporaryIndex);
if (!shouldRunLoopAndIndexingValidation(compileOptions))
{
// HLSL doesn't support dynamic indexing of vectors and matrices.
RemoveDynamicIndexing(root, &temporaryIndex, getSymbolTable(), getShaderVersion());
}
// Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
// use a vertex attribute as a condition, and some related computation in the else block.
if (getOutputType() == SH_HLSL9_OUTPUT && getShaderType() == GL_VERTEX_SHADER)

View File

@ -13,7 +13,7 @@ class TranslatorHLSL : public TCompiler
{
public:
TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; }
TranslatorHLSL *getAsTranslatorHLSL() override { return this; }
bool hasInterfaceBlock(const std::string &interfaceBlockName) const;
unsigned int getInterfaceBlockRegister(const std::string &interfaceBlockName) const;
@ -22,7 +22,10 @@ class TranslatorHLSL : public TCompiler
unsigned int getUniformRegister(const std::string &uniformName) const;
protected:
virtual void translate(TIntermNode *root, int compileOptions);
void translate(TIntermNode *root, int compileOptions) override;
// collectVariables needs to be run always so registers can be assigned.
bool shouldCollectVariables(int compileOptions) override { return true; }
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
std::map<std::string, unsigned int> mUniformRegisterMap;

View File

@ -201,6 +201,17 @@ bool TStructure::containsArrays() const
return false;
}
bool TStructure::containsType(TBasicType type) const
{
for (size_t i = 0; i < mFields->size(); ++i)
{
const TType *fieldType = (*mFields)[i]->type();
if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
return true;
}
return false;
}
bool TStructure::containsSamplers() const
{
for (size_t i = 0; i < mFields->size(); ++i)

View File

@ -124,6 +124,7 @@ class TStructure : public TFieldListCollection
return mDeepestNesting;
}
bool containsArrays() const;
bool containsType(TBasicType t) const;
bool containsSamplers() const;
bool equals(const TStructure &other) const;
@ -160,10 +161,7 @@ class TStructure : public TFieldListCollection
*mutableName = name;
}
virtual TString mangledNamePrefix() const
{
return "struct-";
}
TString mangledNamePrefix() const override { return "struct-"; }
int calculateDeepestNesting() const;
mutable int mDeepestNesting;
@ -211,10 +209,7 @@ class TInterfaceBlock : public TFieldListCollection
}
private:
virtual TString mangledNamePrefix() const
{
return "iblock-";
}
TString mangledNamePrefix() const override { return "iblock-"; }
const TString *mInstanceName; // for interface block instance names
int mArraySize; // 0 if not an array
@ -268,6 +263,9 @@ class TType
{
}
TType(const TType &) = default;
TType &operator=(const TType &) = default;
TBasicType getBasicType() const
{
return type;
@ -490,6 +488,11 @@ class TType
return structure ? structure->containsArrays() : false;
}
bool isStructureContainingType(TBasicType t) const
{
return structure ? structure->containsType(t) : false;
}
bool isStructureContainingSamplers() const
{
return structure ? structure->containsSamplers() : false;
@ -599,6 +602,16 @@ struct TPublicType
return userDef->isStructureContainingArrays();
}
bool isStructureContainingType(TBasicType t) const
{
if (!userDef)
{
return false;
}
return userDef->isStructureContainingType(t);
}
bool isMatrix() const
{
return primarySize > 1 && secondarySize > 1;

View File

@ -25,7 +25,7 @@ class UnfoldShortCircuitAST : public TIntermTraverser
{
}
virtual bool visitBinary(Visit visit, TIntermBinary *);
bool visitBinary(Visit visit, TIntermBinary *) override;
};
#endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_

View File

@ -8,6 +8,7 @@
//
#include "compiler/translator/UtilsHLSL.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/StructureHLSL.h"
#include "compiler/translator/SymbolTable.h"
@ -87,6 +88,30 @@ TString Decorate(const TString &string)
return string;
}
TString DecorateIfNeeded(const TName &name)
{
if (name.isInternal())
{
return name.getString();
}
else
{
return Decorate(name.getString());
}
}
TString DecorateFunctionIfNeeded(const TName &name)
{
if (name.isInternal())
{
return TFunction::unmangleName(name.getString());
}
else
{
return Decorate(TFunction::unmangleName(name.getString()));
}
}
TString TypeString(const TType &type)
{
const TStructure* structure = type.getStruct();

View File

@ -15,6 +15,8 @@
#include "angle_gl.h"
class TName;
namespace sh
{
@ -22,6 +24,9 @@ TString TextureString(const TType &type);
TString SamplerString(const TType &type);
// Prepends an underscore to avoid naming clashes
TString Decorate(const TString &string);
TString DecorateIfNeeded(const TName &name);
// Decorates and also unmangles the function name
TString DecorateFunctionIfNeeded(const TName &name);
TString DecorateUniform(const TString &string, const TType &type);
TString DecorateField(const TString &string, const TStructure &structure);
TString DecoratePrivate(const TString &privateText);

View File

@ -35,7 +35,7 @@ class ValidateConstIndexExpr : public TIntermTraverser
// Returns true if the parsed node represents a constant index expression.
bool isValid() const { return mValid; }
virtual void visitSymbol(TIntermSymbol *symbol)
void visitSymbol(TIntermSymbol *symbol) override
{
// Only constants and loop indices are allowed in a
// constant index expression.

View File

@ -21,10 +21,10 @@ class ValidateLimitations : public TIntermTraverser
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 *);
bool visitBinary(Visit, TIntermBinary *) override;
bool visitUnary(Visit, TIntermUnary *) override;
bool visitAggregate(Visit, TIntermAggregate *) override;
bool visitLoop(Visit, TIntermLoop *) override;
private:
void error(TSourceLoc loc, const char *reason, const char *token);

Some files were not shown because too many files have changed in this diff Show More