mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1211774. Update to ANGLE 2522.
--HG-- extra : rebase_source : 61b730037c24fc6d4ce6cd47a7bc176a6336d477
This commit is contained in:
parent
3aa7323650
commit
48d057951d
@ -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",
|
||||
]
|
||||
}
|
||||
|
@ -104,3 +104,4 @@ NVIDIA Corporation
|
||||
|
||||
Opera Software ASA
|
||||
Daniel Bratell
|
||||
Tomasz Moniuszko
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
@ -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
1524
gfx/angle/include/GLES3/gl31.h
Normal file
1524
gfx/angle/include/GLES3/gl31.h
Normal file
File diff suppressed because it is too large
Load Diff
1825
gfx/angle/include/GLES3/gl32.h
Normal file
1825
gfx/angle/include/GLES3/gl32.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -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_ */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
156
gfx/angle/src/common/BitSetIterator.h
Normal file
156
gfx/angle/src/common/BitSetIterator.h
Normal 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_
|
91
gfx/angle/src/common/BitSetIterator_unittest.cpp
Normal file
91
gfx/angle/src/common/BitSetIterator_unittest.cpp
Normal 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
|
@ -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; }
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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',
|
||||
}],
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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(¯oExpander, mDiagnostics);
|
||||
|
||||
int expression = 0;
|
||||
macroExpander.lex(token);
|
||||
expressionParser.parse(token, &expression);
|
||||
|
||||
// Check if there are tokens after #if expression.
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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_
|
||||
|
@ -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 ¯o,
|
||||
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 ¯o,
|
||||
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 ¯o,
|
||||
repl.setAtStartOfLine(identifier.atStartOfLine());
|
||||
repl.setHasLeadingSpace(identifier.hasLeadingSpace());
|
||||
}
|
||||
repl.location = identifier.location;
|
||||
repl.location = replacementLocation;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroExpander::collectMacroArgs(const Macro ¯o,
|
||||
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 ¯o,
|
||||
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 ¯o,
|
||||
{
|
||||
MacroArg &arg = args->at(i);
|
||||
TokenLexer lexer(&arg);
|
||||
MacroExpander expander(&lexer, mMacroSet, mDiagnostics);
|
||||
MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mParseDefined);
|
||||
|
||||
arg.clear();
|
||||
expander.lex(&token);
|
||||
|
@ -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 ¯o,
|
||||
const Token &identifier,
|
||||
std::vector<MacroArg> *args);
|
||||
std::vector<MacroArg> *args,
|
||||
SourceLocation *closingParenthesisLocation);
|
||||
void replaceMacroParams(const Macro ¯o,
|
||||
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;
|
||||
|
@ -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, ¯oSet, diag, directiveHandler),
|
||||
macroExpander(&directiveParser, ¯oSet, diag)
|
||||
macroExpander(&directiveParser, ¯oSet, 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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
%}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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_
|
||||
|
@ -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_
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 ¶meter, 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; }
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 &);
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -21,7 +21,8 @@ public:
|
||||
bool forceHighp);
|
||||
|
||||
protected:
|
||||
virtual bool writeVariablePrecision(TPrecision precision);
|
||||
bool writeVariablePrecision(TPrecision precision) override;
|
||||
|
||||
private:
|
||||
bool mForceHighp;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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_
|
||||
|
@ -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 << "}";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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(
|
||||
|
@ -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;
|
||||
|
508
gfx/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
Normal file
508
gfx/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
Normal 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();
|
||||
}
|
21
gfx/angle/src/compiler/translator/RemoveDynamicIndexing.h
Normal file
21
gfx/angle/src/compiler/translator/RemoveDynamicIndexing.h
Normal 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_
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
{}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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_
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user