mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-20 22:27:31 +09:00
Roll back to ANGLE/2845
This commit is contained in:
parent
59321284d8
commit
581db453db
582 changed files with 22757 additions and 56816 deletions
|
|
@ -6,8 +6,7 @@
|
||||||
import("//build/config/dcheck_always_on.gni")
|
import("//build/config/dcheck_always_on.gni")
|
||||||
import("//build/config/linux/pkg_config.gni")
|
import("//build/config/linux/pkg_config.gni")
|
||||||
import("//build/config/ui.gni")
|
import("//build/config/ui.gni")
|
||||||
import("//testing/libfuzzer/fuzzer_test.gni")
|
import("//third_party/angle/build/angle_common.gni")
|
||||||
import("//third_party/angle/gni/angle.gni")
|
|
||||||
import("//ui/ozone/ozone.gni")
|
import("//ui/ozone/ozone.gni")
|
||||||
|
|
||||||
if (ozone_platform_gbm) {
|
if (ozone_platform_gbm) {
|
||||||
|
|
@ -55,7 +54,6 @@ config("extra_warnings") {
|
||||||
cflags = [
|
cflags = [
|
||||||
"/we4244", # Conversion: possible loss of data.
|
"/we4244", # Conversion: possible loss of data.
|
||||||
"/we4456", # Variable shadowing.
|
"/we4456", # Variable shadowing.
|
||||||
"/we4458", # declaration hides class member.
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -73,6 +71,22 @@ if (is_win) {
|
||||||
|
|
||||||
angle_undefine_configs = [ "//build/config/compiler:default_include_dirs" ]
|
angle_undefine_configs = [ "//build/config/compiler:default_include_dirs" ]
|
||||||
|
|
||||||
|
component("translator") {
|
||||||
|
sources = [
|
||||||
|
"src/compiler/translator/ShaderLang.cpp",
|
||||||
|
"src/compiler/translator/ShaderVars.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
defines = [ "ANGLE_TRANSLATOR_IMPLEMENTATION" ]
|
||||||
|
|
||||||
|
configs -= angle_undefine_configs
|
||||||
|
configs += [ ":internal_config" ]
|
||||||
|
|
||||||
|
public_deps = [
|
||||||
|
":translator_lib",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
# Holds the shared includes so we only need to list them once.
|
# Holds the shared includes so we only need to list them once.
|
||||||
source_set("includes") {
|
source_set("includes") {
|
||||||
sources = [
|
sources = [
|
||||||
|
|
@ -96,14 +110,10 @@ static_library("preprocessor") {
|
||||||
|
|
||||||
configs -= angle_undefine_configs
|
configs -= angle_undefine_configs
|
||||||
configs += [ ":internal_config" ]
|
configs += [ ":internal_config" ]
|
||||||
|
|
||||||
public_deps = [
|
|
||||||
":angle_common",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config("translator_disable_pool_alloc") {
|
config("translator_static_config") {
|
||||||
defines = [ "ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC" ]
|
defines = [ "ANGLE_TRANSLATOR_STATIC" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
config("debug_annotations_config") {
|
config("debug_annotations_config") {
|
||||||
|
|
@ -162,33 +172,33 @@ static_library("angle_image_util") {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
static_library("translator") {
|
static_library("translator_lib") {
|
||||||
sources = rebase_path(compiler_gypi.angle_translator_sources, ".", "src")
|
sources = rebase_path(compiler_gypi.angle_translator_lib_sources, ".", "src")
|
||||||
defines = []
|
defines = []
|
||||||
|
|
||||||
if (angle_enable_essl || use_libfuzzer) {
|
if (angle_enable_essl) {
|
||||||
sources +=
|
sources +=
|
||||||
rebase_path(compiler_gypi.angle_translator_essl_sources, ".", "src")
|
rebase_path(compiler_gypi.angle_translator_lib_essl_sources, ".", "src")
|
||||||
defines += [ "ANGLE_ENABLE_ESSL" ]
|
defines += [ "ANGLE_ENABLE_ESSL" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (angle_enable_glsl || use_libfuzzer) {
|
if (angle_enable_glsl) {
|
||||||
sources +=
|
sources +=
|
||||||
rebase_path(compiler_gypi.angle_translator_glsl_sources, ".", "src")
|
rebase_path(compiler_gypi.angle_translator_lib_glsl_sources, ".", "src")
|
||||||
defines += [ "ANGLE_ENABLE_GLSL" ]
|
defines += [ "ANGLE_ENABLE_GLSL" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (angle_enable_hlsl || use_libfuzzer) {
|
if (angle_enable_hlsl) {
|
||||||
sources +=
|
sources +=
|
||||||
rebase_path(compiler_gypi.angle_translator_hlsl_sources, ".", "src")
|
rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src")
|
||||||
defines += [ "ANGLE_ENABLE_HLSL" ]
|
defines += [ "ANGLE_ENABLE_HLSL" ]
|
||||||
}
|
}
|
||||||
configs -= angle_undefine_configs
|
configs -= angle_undefine_configs
|
||||||
configs += [ ":internal_config" ]
|
configs += [
|
||||||
|
":internal_config",
|
||||||
|
":translator_static_config",
|
||||||
|
]
|
||||||
public_configs = [ ":external_config" ]
|
public_configs = [ ":external_config" ]
|
||||||
if (use_libfuzzer) {
|
|
||||||
all_dependent_configs = [ ":translator_disable_pool_alloc" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
":includes",
|
":includes",
|
||||||
|
|
@ -206,18 +216,22 @@ static_library("translator") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source_set("translator_fuzzer") {
|
static_library("translator_static") {
|
||||||
sources = [
|
sources = [
|
||||||
"src/compiler/fuzz/translator_fuzzer.cpp",
|
"src/compiler/translator/ShaderLang.cpp",
|
||||||
|
"src/compiler/translator/ShaderVars.cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
include_dirs = [
|
if (angle_enable_hlsl) {
|
||||||
"include",
|
defines = [ "ANGLE_ENABLE_HLSL" ]
|
||||||
"src",
|
}
|
||||||
]
|
|
||||||
|
|
||||||
deps = [
|
configs -= angle_undefine_configs
|
||||||
":translator",
|
configs += [ ":internal_config" ]
|
||||||
|
public_configs = [ ":translator_static_config" ]
|
||||||
|
|
||||||
|
public_deps = [
|
||||||
|
":translator_lib",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -271,13 +285,9 @@ config("libANGLE_config") {
|
||||||
if (angle_enable_vulkan) {
|
if (angle_enable_vulkan) {
|
||||||
defines += [ "ANGLE_ENABLE_VULKAN" ]
|
defines += [ "ANGLE_ENABLE_VULKAN" ]
|
||||||
}
|
}
|
||||||
if (angle_enable_null) {
|
|
||||||
defines += [ "ANGLE_ENABLE_NULL" ]
|
|
||||||
}
|
|
||||||
defines += [
|
defines += [
|
||||||
"GL_GLEXT_PROTOTYPES",
|
"GL_GLEXT_PROTOTYPES",
|
||||||
"EGL_EGLEXT_PROTOTYPES",
|
"EGL_EGLEXT_PROTOTYPES",
|
||||||
"LIBANGLE_IMPLEMENTATION",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if (is_win) {
|
if (is_win) {
|
||||||
|
|
@ -301,7 +311,7 @@ static_library("libANGLE") {
|
||||||
|
|
||||||
include_dirs = []
|
include_dirs = []
|
||||||
libs = []
|
libs = []
|
||||||
defines = []
|
defines = [ "LIBANGLE_IMPLEMENTATION" ]
|
||||||
public_deps = [
|
public_deps = [
|
||||||
":angle_common",
|
":angle_common",
|
||||||
]
|
]
|
||||||
|
|
@ -309,7 +319,7 @@ static_library("libANGLE") {
|
||||||
":angle_image_util",
|
":angle_image_util",
|
||||||
":commit_id",
|
":commit_id",
|
||||||
":includes",
|
":includes",
|
||||||
":translator",
|
":translator_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Shared D3D sources.
|
# Shared D3D sources.
|
||||||
|
|
@ -379,10 +389,6 @@ static_library("libANGLE") {
|
||||||
sources += rebase_path(gles_gypi.libangle_vulkan_sources, ".", "src")
|
sources += rebase_path(gles_gypi.libangle_vulkan_sources, ".", "src")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (angle_enable_null) {
|
|
||||||
sources += rebase_path(gles_gypi.libangle_null_sources, ".", "src")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_debug) {
|
if (is_debug) {
|
||||||
defines += [ "ANGLE_GENERATE_SHADER_DEBUG_INFO" ]
|
defines += [ "ANGLE_GENERATE_SHADER_DEBUG_INFO" ]
|
||||||
}
|
}
|
||||||
|
|
@ -491,7 +497,7 @@ config("angle_util_config") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_library("angle_util") {
|
static_library("angle_util") {
|
||||||
sources = rebase_path(util_gypi.util_sources, ".", "util")
|
sources = rebase_path(util_gypi.util_sources, ".", "util")
|
||||||
|
|
||||||
if (is_win) {
|
if (is_win) {
|
||||||
|
|
@ -508,10 +514,6 @@ shared_library("angle_util") {
|
||||||
|
|
||||||
if (is_mac) {
|
if (is_mac) {
|
||||||
sources += rebase_path(util_gypi.util_osx_sources, ".", "util")
|
sources += rebase_path(util_gypi.util_osx_sources, ".", "util")
|
||||||
libs = [
|
|
||||||
"AppKit.framework",
|
|
||||||
"QuartzCore.framework",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_x11) {
|
if (use_x11) {
|
||||||
|
|
@ -536,7 +538,6 @@ shared_library("angle_util") {
|
||||||
defines = [
|
defines = [
|
||||||
"GL_GLEXT_PROTOTYPES",
|
"GL_GLEXT_PROTOTYPES",
|
||||||
"EGL_EGLEXT_PROTOTYPES",
|
"EGL_EGLEXT_PROTOTYPES",
|
||||||
"LIBANGLE_UTIL_IMPLEMENTATION",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
configs += [
|
configs += [
|
||||||
|
|
@ -548,13 +549,6 @@ shared_library("angle_util") {
|
||||||
":angle_util_config",
|
":angle_util_config",
|
||||||
":internal_config",
|
":internal_config",
|
||||||
]
|
]
|
||||||
if (is_mac && !is_component_build) {
|
|
||||||
ldflags = [
|
|
||||||
"-install_name",
|
|
||||||
"@rpath/lib${target_name}.dylib",
|
|
||||||
]
|
|
||||||
public_configs += [ ":shared_library_public_config" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
":angle_common",
|
":angle_common",
|
||||||
|
|
|
||||||
|
|
@ -64,18 +64,12 @@ Intel Corporation
|
||||||
Andy Chen
|
Andy Chen
|
||||||
Josh Triplett
|
Josh Triplett
|
||||||
Sudarsana Nagineni
|
Sudarsana Nagineni
|
||||||
Jiajia Qin
|
|
||||||
Jiawei Shao
|
|
||||||
Jie Chen
|
|
||||||
Qiankun Miao
|
|
||||||
Bryan Bernhart
|
|
||||||
|
|
||||||
Klarälvdalens Datakonsult AB
|
Klarälvdalens Datakonsult AB
|
||||||
Milian Wolff
|
Milian Wolff
|
||||||
|
|
||||||
Mozilla Corp.
|
Mozilla Corp.
|
||||||
Ehsan Akhgari
|
Ehsan Akhgari
|
||||||
Edwin Flores
|
|
||||||
Jeff Gilbert
|
Jeff Gilbert
|
||||||
Mike Hommey
|
Mike Hommey
|
||||||
Benoit Jacob
|
Benoit Jacob
|
||||||
|
|
|
||||||
|
|
@ -3,30 +3,32 @@ vars = {
|
||||||
}
|
}
|
||||||
|
|
||||||
deps = {
|
deps = {
|
||||||
'third_party/gyp':
|
"third_party/gyp":
|
||||||
Var('chromium_git') + '/external/gyp' + '@' + '81c2e5ff92af29bab61c982808076ddce3d200a2',
|
Var('chromium_git') + "/external/gyp@81c2e5ff92af29bab61c982808076ddce3d200a2",
|
||||||
|
|
||||||
'testing/gtest':
|
# TODO(kbr): figure out how to better stay in sync with Chromium's
|
||||||
Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '6f8a66431cb592dad629028a50b3dd418a408c87',
|
# versions of googletest and googlemock.
|
||||||
|
"src/tests/third_party/googletest":
|
||||||
|
Var('chromium_git') + "/external/googletest.git@9855a87157778d39b95eccfb201a9dc90f6d61c6",
|
||||||
|
|
||||||
'testing/gmock':
|
"src/tests/third_party/googlemock":
|
||||||
Var('chromium_git') + '/external/googlemock.git' + '@' + '0421b6f358139f02e102c9c332ce19a33faf75be', # from svn revision 566
|
Var('chromium_git') + "/external/googlemock.git@b2cb211e49d872101d991201362d7b97d7d69910",
|
||||||
|
|
||||||
# Cherry is a dEQP management GUI written in Go. We use it for viewing test results.
|
# Cherry is a dEQP management GUI written in Go. We use it for viewing test results.
|
||||||
'third_party/cherry':
|
"third_party/cherry":
|
||||||
'https://android.googlesource.com/platform/external/cherry' + '@' + 'd2e26b4d864ec2a6757e7f1174e464949ca5bf73',
|
"https://android.googlesource.com/platform/external/cherry@d2e26b4d864ec2a6757e7f1174e464949ca5bf73",
|
||||||
|
|
||||||
'third_party/deqp/src':
|
"third_party/deqp/src":
|
||||||
'https://android.googlesource.com/platform/external/deqp' + '@' + 'f4f3d8079e7a37d7675ab93583e6438d0bca0e58',
|
"https://android.googlesource.com/platform/external/deqp@f4f3d8079e7a37d7675ab93583e6438d0bca0e58",
|
||||||
|
|
||||||
'third_party/libpng':
|
"third_party/libpng":
|
||||||
'https://android.googlesource.com/platform/external/libpng' + '@' + '094e181e79a3d6c23fd005679025058b7df1ad6c',
|
"https://android.googlesource.com/platform/external/libpng@094e181e79a3d6c23fd005679025058b7df1ad6c",
|
||||||
|
|
||||||
'third_party/zlib':
|
"third_party/zlib":
|
||||||
Var('chromium_git') + '/chromium/src/third_party/zlib' + '@' + 'afd8c4593c010c045902f6c0501718f1823064a3',
|
Var('chromium_git') + "/chromium/src/third_party/zlib@afd8c4593c010c045902f6c0501718f1823064a3",
|
||||||
|
|
||||||
'buildtools':
|
"buildtools":
|
||||||
Var('chromium_git') + '/chromium/buildtools.git' + '@' + '39b1db2ab4aa4b2ccaa263c29bdf63e7c1ee28aa',
|
Var('chromium_git') + '/chromium/buildtools.git@06e80a0e17319868d4a9b13f9bb6a248dc8d8b20',
|
||||||
}
|
}
|
||||||
|
|
||||||
hooks = [
|
hooks = [
|
||||||
|
|
@ -100,12 +102,7 @@ hooks = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
# A change to a .gyp, .gypi, or to GYP itself should run the generator.
|
# A change to a .gyp, .gypi, or to GYP itself should run the generator.
|
||||||
'pattern': '.',
|
"pattern": ".",
|
||||||
'action': ['python', 'gyp/gyp_angle'],
|
"action": ["python", "build/gyp_angle"],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
recursedeps = [
|
|
||||||
# buildtools provides clang_format.
|
|
||||||
'buildtools',
|
|
||||||
]
|
|
||||||
|
|
|
||||||
|
|
@ -472,11 +472,6 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR
|
||||||
#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2
|
#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2
|
||||||
#endif /* EGL_ANGLE_keyed_mutex */
|
#endif /* EGL_ANGLE_keyed_mutex */
|
||||||
|
|
||||||
#ifndef EGL_ANGLE_d3d_texture_client_buffer
|
|
||||||
#define EGL_ANGLE_d3d_texture_client_buffer 1
|
|
||||||
#define EGL_D3D_TEXTURE_ANGLE 0x33A3
|
|
||||||
#endif /* EGL_ANGLE_d3d_texture_client_buffer */
|
|
||||||
|
|
||||||
#ifndef EGL_ANGLE_query_surface_pointer
|
#ifndef EGL_ANGLE_query_surface_pointer
|
||||||
#define EGL_ANGLE_query_surface_pointer 1
|
#define EGL_ANGLE_query_surface_pointer 1
|
||||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
|
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
|
||||||
|
|
@ -531,11 +526,6 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
|
||||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
|
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
|
||||||
#endif /* EGL_ANGLE_platform_angle_opengl */
|
#endif /* EGL_ANGLE_platform_angle_opengl */
|
||||||
|
|
||||||
#ifndef EGL_ANGLE_platform_angle_null
|
|
||||||
#define EGL_ANGLE_platform_angle_null 1
|
|
||||||
#define EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE 0x33AE
|
|
||||||
#endif /* EGL_ANGLE_platform_angle_null */
|
|
||||||
|
|
||||||
#ifndef EGL_ANGLE_window_fixed_size
|
#ifndef EGL_ANGLE_window_fixed_size
|
||||||
#define EGL_ANGLE_window_fixed_size 1
|
#define EGL_ANGLE_window_fixed_size 1
|
||||||
#define EGL_FIXED_SIZE_ANGLE 0x3201
|
#define EGL_FIXED_SIZE_ANGLE 0x3201
|
||||||
|
|
@ -568,7 +558,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
|
||||||
|
|
||||||
#ifndef EGL_ANGLE_stream_producer_d3d_texture_nv12
|
#ifndef EGL_ANGLE_stream_producer_d3d_texture_nv12
|
||||||
#define EGL_ANGLE_stream_producer_d3d_texture_nv12
|
#define EGL_ANGLE_stream_producer_d3d_texture_nv12
|
||||||
#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x33AB
|
#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x3AAB
|
||||||
typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
|
typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
|
||||||
typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
|
typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
|
||||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||||
|
|
@ -577,16 +567,6 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, E
|
||||||
#endif
|
#endif
|
||||||
#endif /* EGL_ANGLE_stream_producer_d3d_texture_nv12 */
|
#endif /* EGL_ANGLE_stream_producer_d3d_texture_nv12 */
|
||||||
|
|
||||||
#ifndef EGL_ANGLE_create_context_webgl_compatibility
|
|
||||||
#define EGL_ANGLE_create_context_webgl_compatibility 1
|
|
||||||
#define EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE 0x3AAC
|
|
||||||
#endif /* EGL_ANGLE_create_context_webgl_compatibility */
|
|
||||||
|
|
||||||
#ifndef EGL_CHROMIUM_create_context_bind_generates_resource
|
|
||||||
#define EGL_CHROMIUM_create_context_bind_generates_resource 1
|
|
||||||
#define EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM 0x3AAD
|
|
||||||
#endif /* EGL_CHROMIUM_create_context_bind_generates_resource */
|
|
||||||
|
|
||||||
#ifndef EGL_ARM_pixmap_multisample_discard
|
#ifndef EGL_ARM_pixmap_multisample_discard
|
||||||
#define EGL_ARM_pixmap_multisample_discard 1
|
#define EGL_ARM_pixmap_multisample_discard 1
|
||||||
#define EGL_DISCARD_SAMPLES_ARM 0x3286
|
#define EGL_DISCARD_SAMPLES_ARM 0x3286
|
||||||
|
|
|
||||||
|
|
@ -821,14 +821,6 @@ GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GL
|
||||||
#endif
|
#endif
|
||||||
#endif /* GL_ANGLE_framebuffer_blit */
|
#endif /* GL_ANGLE_framebuffer_blit */
|
||||||
|
|
||||||
#ifndef GL_ANGLE_webgl_compatibility
|
|
||||||
#define GL_ANGLE_webgl_compatibility 1
|
|
||||||
typedef GLboolean(GL_APIENTRYP PFNGLENABLEEXTENSIONANGLEPROC) (const GLchar *name);
|
|
||||||
#ifdef GL_GLEXT_PROTOTYPES
|
|
||||||
GL_APICALL GLboolean GL_APIENTRY glEnableExtensionANGLE (const GLchar *name);
|
|
||||||
#endif
|
|
||||||
#endif /* GL_ANGLE_webgl_compatibility */
|
|
||||||
|
|
||||||
#ifndef GL_CHROMIUM_framebuffer_mixed_samples
|
#ifndef GL_CHROMIUM_framebuffer_mixed_samples
|
||||||
#define GL_CHROMIUM_frambuffer_mixed_samples 1
|
#define GL_CHROMIUM_frambuffer_mixed_samples 1
|
||||||
#define GL_COVERAGE_MODULATION_CHROMIUM 0x9332
|
#define GL_COVERAGE_MODULATION_CHROMIUM 0x9332
|
||||||
|
|
@ -838,11 +830,6 @@ GL_APICALL void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components);
|
||||||
#endif
|
#endif
|
||||||
#endif /* GL_CHROMIUM_framebuffer_mixed_samples */
|
#endif /* GL_CHROMIUM_framebuffer_mixed_samples */
|
||||||
|
|
||||||
#ifndef GL_CHROMIUM_bind_generates_resource
|
|
||||||
#define GL_CHROMIUM_bind_generates_resource 1
|
|
||||||
#define GL_BIND_GENERATES_RESOURCE_CHROMIUM 0x9244
|
|
||||||
#endif /* GL_CHROMIUM_bind_generates_resource */
|
|
||||||
|
|
||||||
// needed by NV_path_rendering (and thus CHROMIUM_path_rendering)
|
// needed by NV_path_rendering (and thus CHROMIUM_path_rendering)
|
||||||
// but CHROMIUM_path_rendering only needs MatrixLoadfEXT, MatrixLoadIdentityEXT
|
// but CHROMIUM_path_rendering only needs MatrixLoadfEXT, MatrixLoadIdentityEXT
|
||||||
#ifndef GL_EXT_direct_state_access
|
#ifndef GL_EXT_direct_state_access
|
||||||
|
|
@ -1316,14 +1303,6 @@ GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM(GLuint sourceId,
|
||||||
#endif
|
#endif
|
||||||
#endif /* GL_CHROMIUM_copy_texture */
|
#endif /* GL_CHROMIUM_copy_texture */
|
||||||
|
|
||||||
#ifndef GL_CHROMIUM_compressed_copy_texture
|
|
||||||
#define GL_CHROMIUM_compressed_copy_texture 1
|
|
||||||
typedef void(GL_APIENTRYP PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC)(GLuint sourceId, GLuint destId);
|
|
||||||
#ifdef GL_GLEXT_PROTOTYPES
|
|
||||||
GL_APICALL void GL_APIENTRY glCompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId);
|
|
||||||
#endif
|
|
||||||
#endif /* GL_CHROMIUM_compressed_copy_texture */
|
|
||||||
|
|
||||||
#ifndef GL_CHROMIUM_sync_query
|
#ifndef GL_CHROMIUM_sync_query
|
||||||
#define GL_CHROMIUM_sync_query 1
|
#define GL_CHROMIUM_sync_query 1
|
||||||
#define GL_COMMANDS_COMPLETED_CHROMIUM 0x84F7
|
#define GL_COMMANDS_COMPLETED_CHROMIUM 0x84F7
|
||||||
|
|
@ -3255,132 +3234,6 @@ GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
|
||||||
#define GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x969A
|
#define GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x969A
|
||||||
#endif /* GL_ANGLE_lossy_etc_decode */
|
#endif /* GL_ANGLE_lossy_etc_decode */
|
||||||
|
|
||||||
#ifndef GL_ANGLE_robust_client_memory
|
|
||||||
#define GL_ANGLE_robust_client_memory 1
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETBOOLEANVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *data);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETFLOATVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *data);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVROBUSTANGLE) (GLenum target, GLenum attachment, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETINTEGERVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVROBUSTANGLE) (GLuint program, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETSHADERIVROBUSTANGLE) (GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, void **pointer);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLREADPIXELSROBUSTANGLE) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, void *pixels);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLfloat *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETQUERYIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVROBUSTANGLE) (GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data);
|
|
||||||
typedef void (GL_APIENTRYP PFNGETINTERNALFORMATIVROBUSTANGLE) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVROBUSTANGLE) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETINTEGER64VROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint64 *data);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLfloat *param);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVROBUSTANGLE) (GLuint program, GLenum programInterface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETBOOLEANI_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLboolean *data);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETMULTISAMPLEFVROBUSTANGLE) (GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, GLfloat *val);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVROBUSTANGLE) (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVROBUSTANGLE) (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETPOINTERVROBUSTANGLEROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLREADNPIXELSROBUSTANGLE) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, void *data);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLuint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLuint *param);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
|
|
||||||
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint64 *params);
|
|
||||||
#ifdef GL_GLEXT_PROTOTYPES
|
|
||||||
GL_APICALL void GL_APIENTRY glGetBooleanvRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *data);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetBufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetFloatvRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *data);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameterivRobustANGLE (GLenum target, GLenum attachment, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetIntegervRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetProgramivRobustANGLE (GLuint program, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetRenderbufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetShaderivRobustANGLE (GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetTexParameterfvRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetTexParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetUniformfvRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetUniformivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetVertexAttribfvRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetVertexAttribivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetVertexAttribPointervRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, void **pointer);
|
|
||||||
GL_APICALL void GL_APIENTRY glReadPixelsRobustANGLE (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, void *pixels);
|
|
||||||
GL_APICALL void GL_APIENTRY glTexImage2DRobustANGLE (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
|
||||||
GL_APICALL void GL_APIENTRY glTexParameterfvRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLfloat *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glTexParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glTexSubImage2DRobustANGLE (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
|
||||||
GL_APICALL void GL_APIENTRY glTexImage3DRobustANGLE (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
|
||||||
GL_APICALL void GL_APIENTRY glTexSubImage3DRobustANGLE (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetQueryivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetQueryObjectuivRobustANGLE (GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetBufferPointervRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetIntegeri_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetInternalformativRobustANGLE (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetVertexAttribIivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetVertexAttribIuivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetUniformuivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetActiveUniformBlockivRobustANGLE (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetInteger64vRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetInteger64i_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint64 *data);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetBufferParameteri64vRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glSamplerParameterivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
|
|
||||||
GL_APICALL void GL_APIENTRY glSamplerParameterfvRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLfloat *param);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetSamplerParameterivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetSamplerParameterfvRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetFramebufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetProgramInterfaceivRobustANGLE (GLuint program, GLenum programInterface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetBooleani_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLboolean *data);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetMultisamplefvRobustANGLE (GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, GLfloat *val);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetTexLevelParameterivRobustANGLE (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetTexLevelParameterfvRobustANGLE (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetPointervRobustANGLERobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
|
|
||||||
GL_APICALL void GL_APIENTRY glReadnPixelsRobustANGLE (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, void *data);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetnUniformfvRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetnUniformivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetnUniformuivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glTexParameterIivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glTexParameterIuivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLuint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetTexParameterIivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetTexParameterIuivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glSamplerParameterIivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
|
|
||||||
GL_APICALL void GL_APIENTRY glSamplerParameterIuivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLuint *param);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetSamplerParameterIivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetQueryObjectivRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetQueryObjecti64vRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
|
|
||||||
GL_APICALL void GL_APIENTRY glGetQueryObjectui64vRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint64 *params);
|
|
||||||
#endif
|
|
||||||
#endif /* GL_ANGLE_robust_client_memory */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,23 @@
|
||||||
#ifndef GLSLANG_SHADERLANG_H_
|
#ifndef GLSLANG_SHADERLANG_H_
|
||||||
#define GLSLANG_SHADERLANG_H_
|
#define GLSLANG_SHADERLANG_H_
|
||||||
|
|
||||||
|
#if defined(COMPONENT_BUILD) && !defined(ANGLE_TRANSLATOR_STATIC)
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
|
||||||
|
#if defined(ANGLE_TRANSLATOR_IMPLEMENTATION)
|
||||||
|
#define COMPILER_EXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define COMPILER_EXPORT __declspec(dllimport)
|
||||||
|
#endif // defined(ANGLE_TRANSLATOR_IMPLEMENTATION)
|
||||||
|
|
||||||
|
#else // defined(_WIN32) || defined(_WIN64)
|
||||||
|
#define COMPILER_EXPORT __attribute__((visibility("default")))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else // defined(COMPONENT_BUILD) && !defined(ANGLE_TRANSLATOR_STATIC)
|
||||||
|
#define COMPILER_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "KHR/khrplatform.h"
|
#include "KHR/khrplatform.h"
|
||||||
|
|
@ -32,10 +49,9 @@ typedef unsigned int GLenum;
|
||||||
|
|
||||||
// Version number for shader translation API.
|
// Version number for shader translation API.
|
||||||
// It is incremented every time the API changes.
|
// It is incremented every time the API changes.
|
||||||
#define ANGLE_SH_VERSION 167
|
#define ANGLE_SH_VERSION 155
|
||||||
|
|
||||||
enum ShShaderSpec
|
typedef enum {
|
||||||
{
|
|
||||||
SH_GLES2_SPEC,
|
SH_GLES2_SPEC,
|
||||||
SH_WEBGL_SPEC,
|
SH_WEBGL_SPEC,
|
||||||
|
|
||||||
|
|
@ -44,9 +60,31 @@ enum ShShaderSpec
|
||||||
|
|
||||||
SH_GLES3_1_SPEC,
|
SH_GLES3_1_SPEC,
|
||||||
SH_WEBGL3_SPEC,
|
SH_WEBGL3_SPEC,
|
||||||
};
|
|
||||||
|
|
||||||
enum ShShaderOutput
|
// The CSS Shaders spec is a subset of the WebGL spec.
|
||||||
|
//
|
||||||
|
// In both CSS vertex and fragment shaders, ANGLE:
|
||||||
|
// (1) Reserves the "css_" prefix.
|
||||||
|
// (2) Renames the main function to css_main.
|
||||||
|
// (3) Disables the gl_MaxDrawBuffers built-in.
|
||||||
|
//
|
||||||
|
// In CSS fragment shaders, ANGLE:
|
||||||
|
// (1) Disables the gl_FragColor built-in.
|
||||||
|
// (2) Disables the gl_FragData built-in.
|
||||||
|
// (3) Enables the css_MixColor built-in.
|
||||||
|
// (4) Enables the css_ColorMatrix built-in.
|
||||||
|
//
|
||||||
|
// After passing a CSS shader through ANGLE, the browser is expected to append
|
||||||
|
// a new main function to it.
|
||||||
|
// This new main function will call the css_main function.
|
||||||
|
// It may also perform additional operations like varying assignment, texture
|
||||||
|
// access, and gl_FragColor assignment in order to implement the CSS Shaders
|
||||||
|
// blend modes.
|
||||||
|
//
|
||||||
|
SH_CSS_SHADERS_SPEC
|
||||||
|
} ShShaderSpec;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
{
|
{
|
||||||
// ESSL output only supported in some configurations.
|
// ESSL output only supported in some configurations.
|
||||||
SH_ESSL_OUTPUT = 0x8B45,
|
SH_ESSL_OUTPUT = 0x8B45,
|
||||||
|
|
@ -65,171 +103,166 @@ enum ShShaderOutput
|
||||||
SH_GLSL_440_CORE_OUTPUT = 0x8B87,
|
SH_GLSL_440_CORE_OUTPUT = 0x8B87,
|
||||||
SH_GLSL_450_CORE_OUTPUT = 0x8B88,
|
SH_GLSL_450_CORE_OUTPUT = 0x8B88,
|
||||||
|
|
||||||
|
// HLSL output only supported in some configurations.
|
||||||
|
// Deprecated:
|
||||||
|
SH_HLSL_OUTPUT = 0x8B48,
|
||||||
|
SH_HLSL9_OUTPUT = 0x8B48,
|
||||||
|
SH_HLSL11_OUTPUT = 0x8B49,
|
||||||
|
|
||||||
// Prefer using these to specify HLSL output type:
|
// Prefer using these to specify HLSL output type:
|
||||||
SH_HLSL_3_0_OUTPUT = 0x8B48, // D3D 9
|
SH_HLSL_3_0_OUTPUT = 0x8B48, // D3D 9
|
||||||
SH_HLSL_4_1_OUTPUT = 0x8B49, // D3D 11
|
SH_HLSL_4_1_OUTPUT = 0x8B49, // D3D 11
|
||||||
SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A // D3D 11 feature level 9_3
|
SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A // D3D 11 feature level 9_3
|
||||||
};
|
} ShShaderOutput;
|
||||||
|
|
||||||
// Compile options.
|
// Compile options.
|
||||||
|
typedef enum {
|
||||||
|
SH_VALIDATE = 0,
|
||||||
|
SH_VALIDATE_LOOP_INDEXING = 0x0001,
|
||||||
|
SH_INTERMEDIATE_TREE = 0x0002,
|
||||||
|
SH_OBJECT_CODE = 0x0004,
|
||||||
|
SH_VARIABLES = 0x0008,
|
||||||
|
SH_LINE_DIRECTIVES = 0x0010,
|
||||||
|
SH_SOURCE_PATH = 0x0020,
|
||||||
|
SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX = 0x0040,
|
||||||
|
// If a sampler array index happens to be a loop index,
|
||||||
|
// 1) if its type is integer, unroll the loop.
|
||||||
|
// 2) if its type is float, fail the shader compile.
|
||||||
|
// This is to work around a mac driver bug.
|
||||||
|
SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX = 0x0080,
|
||||||
|
|
||||||
using ShCompileOptions = uint64_t;
|
// This is needed only as a workaround for certain OpenGL driver bugs.
|
||||||
|
SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100,
|
||||||
|
|
||||||
const ShCompileOptions SH_VALIDATE = 0;
|
// This is an experimental flag to enforce restrictions that aim to prevent
|
||||||
const ShCompileOptions SH_VALIDATE_LOOP_INDEXING = UINT64_C(1) << 0;
|
// timing attacks.
|
||||||
const ShCompileOptions SH_INTERMEDIATE_TREE = UINT64_C(1) << 1;
|
// It generates compilation errors for shaders that could expose sensitive
|
||||||
const ShCompileOptions SH_OBJECT_CODE = UINT64_C(1) << 2;
|
// texture information via the timing channel.
|
||||||
const ShCompileOptions SH_VARIABLES = UINT64_C(1) << 3;
|
// To use this flag, you must compile the shader under the WebGL spec
|
||||||
const ShCompileOptions SH_LINE_DIRECTIVES = UINT64_C(1) << 4;
|
// (using the SH_WEBGL_SPEC flag).
|
||||||
const ShCompileOptions SH_SOURCE_PATH = UINT64_C(1) << 5;
|
SH_TIMING_RESTRICTIONS = 0x0200,
|
||||||
const ShCompileOptions SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX = UINT64_C(1) << 6;
|
|
||||||
// If a sampler array index happens to be a loop index,
|
|
||||||
// 1) if its type is integer, unroll the loop.
|
|
||||||
// 2) if its type is float, fail the shader compile.
|
|
||||||
// This is to work around a mac driver bug.
|
|
||||||
const ShCompileOptions SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX = UINT64_C(1) << 7;
|
|
||||||
|
|
||||||
// This flag works around bug in Intel Mac drivers related to abs(i) where
|
// This flag prints the dependency graph that is used to enforce timing
|
||||||
// i is an integer.
|
// restrictions on fragment shaders.
|
||||||
const ShCompileOptions SH_EMULATE_ABS_INT_FUNCTION = UINT64_C(1) << 8;
|
// This flag only has an effect if all of the following are true:
|
||||||
|
// - The shader spec is SH_WEBGL_SPEC.
|
||||||
|
// - The compile options contain the SH_TIMING_RESTRICTIONS flag.
|
||||||
|
// - The shader type is GL_FRAGMENT_SHADER.
|
||||||
|
SH_DEPENDENCY_GRAPH = 0x0400,
|
||||||
|
|
||||||
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
|
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
|
||||||
// This flag only enforces (and can only enforce) the packing
|
// This flag only enforces (and can only enforce) the packing
|
||||||
// restrictions for uniform variables in both vertex and fragment
|
// restrictions for uniform variables in both vertex and fragment
|
||||||
// shaders. ShCheckVariablesWithinPackingLimits() lets embedders
|
// shaders. ShCheckVariablesWithinPackingLimits() lets embedders
|
||||||
// enforce the packing restrictions for varying variables during
|
// enforce the packing restrictions for varying variables during
|
||||||
// program link time.
|
// program link time.
|
||||||
const ShCompileOptions SH_ENFORCE_PACKING_RESTRICTIONS = UINT64_C(1) << 9;
|
SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800,
|
||||||
|
|
||||||
// This flag ensures all indirect (expression-based) array indexing
|
// This flag ensures all indirect (expression-based) array indexing
|
||||||
// is clamped to the bounds of the array. This ensures, for example,
|
// is clamped to the bounds of the array. This ensures, for example,
|
||||||
// that you cannot read off the end of a uniform, whether an array
|
// that you cannot read off the end of a uniform, whether an array
|
||||||
// vec234, or mat234 type. The ShArrayIndexClampingStrategy enum,
|
// vec234, or mat234 type. The ShArrayIndexClampingStrategy enum,
|
||||||
// specified in the ShBuiltInResources when constructing the
|
// specified in the ShBuiltInResources when constructing the
|
||||||
// compiler, selects the strategy for the clamping implementation.
|
// compiler, selects the strategy for the clamping implementation.
|
||||||
const ShCompileOptions SH_CLAMP_INDIRECT_ARRAY_BOUNDS = UINT64_C(1) << 10;
|
SH_CLAMP_INDIRECT_ARRAY_BOUNDS = 0x1000,
|
||||||
|
|
||||||
// This flag limits the complexity of an expression.
|
// This flag limits the complexity of an expression.
|
||||||
const ShCompileOptions SH_LIMIT_EXPRESSION_COMPLEXITY = UINT64_C(1) << 11;
|
SH_LIMIT_EXPRESSION_COMPLEXITY = 0x2000,
|
||||||
|
|
||||||
// This flag limits the depth of the call stack.
|
// This flag limits the depth of the call stack.
|
||||||
const ShCompileOptions SH_LIMIT_CALL_STACK_DEPTH = UINT64_C(1) << 12;
|
SH_LIMIT_CALL_STACK_DEPTH = 0x4000,
|
||||||
|
|
||||||
// This flag initializes gl_Position to vec4(0,0,0,0) at the
|
// This flag initializes gl_Position to vec4(0,0,0,0) at the
|
||||||
// beginning of the vertex shader's main(), and has no effect in the
|
// beginning of the vertex shader's main(), and has no effect in the
|
||||||
// fragment shader. It is intended as a workaround for drivers which
|
// fragment shader. It is intended as a workaround for drivers which
|
||||||
// incorrectly fail to link programs if gl_Position is not written.
|
// incorrectly fail to link programs if gl_Position is not written.
|
||||||
const ShCompileOptions SH_INIT_GL_POSITION = UINT64_C(1) << 13;
|
SH_INIT_GL_POSITION = 0x8000,
|
||||||
|
|
||||||
// This flag replaces
|
// This flag replaces
|
||||||
// "a && b" with "a ? b : false",
|
// "a && b" with "a ? b : false",
|
||||||
// "a || b" with "a ? true : b".
|
// "a || b" with "a ? true : b".
|
||||||
// This is to work around a MacOSX driver bug that |b| is executed
|
// This is to work around a MacOSX driver bug that |b| is executed
|
||||||
// independent of |a|'s value.
|
// independent of |a|'s value.
|
||||||
const ShCompileOptions SH_UNFOLD_SHORT_CIRCUIT = UINT64_C(1) << 14;
|
SH_UNFOLD_SHORT_CIRCUIT = 0x10000,
|
||||||
|
|
||||||
// This flag initializes output variables to 0 at the beginning of main().
|
// This flag initializes output variables to 0 at the beginning of main().
|
||||||
// It is to avoid undefined behaviors.
|
// It is to avoid undefined behaviors.
|
||||||
const ShCompileOptions SH_INIT_OUTPUT_VARIABLES = UINT64_C(1) << 15;
|
SH_INIT_OUTPUT_VARIABLES = 0x20000,
|
||||||
|
// TODO(zmo): obsolete, remove after ANGLE roll into Chromium.
|
||||||
|
SH_INIT_VARYINGS_WITHOUT_STATIC_USE = 0x20000,
|
||||||
|
|
||||||
// This flag scalarizes vec/ivec/bvec/mat constructor args.
|
// This flag scalarizes vec/ivec/bvec/mat constructor args.
|
||||||
// It is intended as a workaround for Linux/Mac driver bugs.
|
// It is intended as a workaround for Linux/Mac driver bugs.
|
||||||
const ShCompileOptions SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = UINT64_C(1) << 16;
|
SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = 0x40000,
|
||||||
|
|
||||||
// This flag overwrites a struct name with a unique prefix.
|
// This flag overwrites a struct name with a unique prefix.
|
||||||
// It is intended as a workaround for drivers that do not handle
|
// It is intended as a workaround for drivers that do not handle
|
||||||
// struct scopes correctly, including all Mac drivers and Linux AMD.
|
// struct scopes correctly, including all Mac drivers and Linux AMD.
|
||||||
const ShCompileOptions SH_REGENERATE_STRUCT_NAMES = UINT64_C(1) << 17;
|
SH_REGENERATE_STRUCT_NAMES = 0x80000,
|
||||||
|
|
||||||
// This flag makes the compiler not prune unused function early in the
|
// This flag makes the compiler not prune unused function early in the
|
||||||
// compilation process. Pruning coupled with SH_LIMIT_CALL_STACK_DEPTH
|
// compilation process. Pruning coupled with SH_LIMIT_CALL_STACK_DEPTH
|
||||||
// helps avoid bad shaders causing stack overflows.
|
// helps avoid bad shaders causing stack overflows.
|
||||||
const ShCompileOptions SH_DONT_PRUNE_UNUSED_FUNCTIONS = UINT64_C(1) << 18;
|
SH_DONT_PRUNE_UNUSED_FUNCTIONS = 0x100000,
|
||||||
|
|
||||||
// This flag works around a bug in NVIDIA 331 series drivers related
|
// This flag works around a bug in NVIDIA 331 series drivers related
|
||||||
// to pow(x, y) where y is a constant vector.
|
// to pow(x, y) where y is a constant vector.
|
||||||
const ShCompileOptions SH_REMOVE_POW_WITH_CONSTANT_EXPONENT = UINT64_C(1) << 19;
|
SH_REMOVE_POW_WITH_CONSTANT_EXPONENT = 0x200000,
|
||||||
|
|
||||||
// This flag works around bugs in Mac drivers related to do-while by
|
// This flag works around bugs in Mac drivers related to do-while by
|
||||||
// transforming them into an other construct.
|
// transforming them into an other construct.
|
||||||
const ShCompileOptions SH_REWRITE_DO_WHILE_LOOPS = UINT64_C(1) << 20;
|
SH_REWRITE_DO_WHILE_LOOPS = 0x400000,
|
||||||
|
|
||||||
// This flag works around a bug in the HLSL compiler optimizer that folds certain
|
// This flag works around a bug in the HLSL compiler optimizer that folds certain
|
||||||
// constant pow expressions incorrectly. Only applies to the HLSL back-end. It works
|
// constant pow expressions incorrectly. Only applies to the HLSL back-end. It works
|
||||||
// by expanding the integer pow expressions into a series of multiplies.
|
// by expanding the integer pow expressions into a series of multiplies.
|
||||||
const ShCompileOptions SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS = UINT64_C(1) << 21;
|
SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS = 0x800000,
|
||||||
|
|
||||||
// Flatten "#pragma STDGL invariant(all)" into the declarations of
|
// Flatten "#pragma STDGL invariant(all)" into the declarations of
|
||||||
// varying variables and built-in GLSL variables. This compiler
|
// varying variables and built-in GLSL variables. This compiler
|
||||||
// option is enabled automatically when needed.
|
// option is enabled automatically when needed.
|
||||||
const ShCompileOptions SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL = UINT64_C(1) << 22;
|
SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL = 0x1000000,
|
||||||
|
|
||||||
// Some drivers do not take into account the base level of the texture in the results of the
|
// Some drivers do not take into account the base level of the texture in the results of the
|
||||||
// HLSL GetDimensions builtin. This flag instructs the compiler to manually add the base level
|
// HLSL GetDimensions builtin. This flag instructs the compiler to manually add the base level
|
||||||
// offsetting.
|
// offsetting.
|
||||||
const ShCompileOptions SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL = UINT64_C(1) << 23;
|
SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL = 0x2000000,
|
||||||
|
|
||||||
// This flag works around an issue in translating GLSL function texelFetchOffset on
|
// This flag works around an issue in translating GLSL function texelFetchOffset on
|
||||||
// INTEL drivers. It works by translating texelFetchOffset into texelFetch.
|
// INTEL drivers. It works by translating texelFetchOffset into texelFetch.
|
||||||
const ShCompileOptions SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH = UINT64_C(1) << 24;
|
SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH = 0x4000000,
|
||||||
|
} ShCompileOptions;
|
||||||
// This flag works around condition bug of for and while loops in Intel Mac OSX drivers.
|
|
||||||
// Condition calculation is not correct. Rewrite it from "CONDITION" to "CONDITION && true".
|
|
||||||
const ShCompileOptions SH_ADD_AND_TRUE_TO_LOOP_CONDITION = UINT64_C(1) << 25;
|
|
||||||
|
|
||||||
// This flag works around a bug in evaluating unary minus operator on integer on some INTEL
|
|
||||||
// drivers. It works by translating -(int) into ~(int) + 1.
|
|
||||||
const ShCompileOptions SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR = UINT64_C(1) << 26;
|
|
||||||
|
|
||||||
// This flag works around a bug in evaluating isnan() on some INTEL D3D and Mac OSX drivers.
|
|
||||||
// It works by using an expression to emulate this function.
|
|
||||||
const ShCompileOptions SH_EMULATE_ISNAN_FLOAT_FUNCTION = UINT64_C(1) << 27;
|
|
||||||
|
|
||||||
// This flag will use all uniforms of unused std140 and shared uniform blocks at the
|
|
||||||
// beginning of the vertex/fragment shader's main(). It is intended as a workaround for Mac
|
|
||||||
// drivers with shader version 4.10. In those drivers, they will treat unused
|
|
||||||
// std140 and shared uniform blocks' members as inactive. However, WebGL2.0 based on
|
|
||||||
// OpenGL ES3.0.4 requires all members of a named uniform block declared with a shared or std140
|
|
||||||
// layout qualifier to be considered active. The uniform block itself is also considered active.
|
|
||||||
const ShCompileOptions SH_USE_UNUSED_STANDARD_SHARED_BLOCKS = UINT64_C(1) << 28;
|
|
||||||
|
|
||||||
// This flag will keep invariant declaration for input in fragment shader for GLSL >=4.20 on AMD.
|
|
||||||
// From GLSL >= 4.20, it's optional to add invariant for fragment input, but GPU vendors have
|
|
||||||
// different implementations about this. Some drivers forbid invariant in fragment for GLSL>= 4.20,
|
|
||||||
// e.g. Linux Mesa, some drivers treat that as optional, e.g. NVIDIA, some drivers require invariant
|
|
||||||
// must match between vertex and fragment shader, e.g. AMD. The behavior on AMD is obviously wrong.
|
|
||||||
// Remove invariant for input in fragment shader to workaround the restriction on Intel Mesa.
|
|
||||||
// But don't remove on AMD Linux to avoid triggering the bug on AMD.
|
|
||||||
const ShCompileOptions SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT = UINT64_C(1) << 29;
|
|
||||||
|
|
||||||
// Due to spec difference between GLSL 4.1 or lower and ESSL3, some platforms (for example, Mac OSX
|
|
||||||
// core profile) require a variable's "invariant"/"centroid" qualifiers to match between vertex and
|
|
||||||
// fragment shader. A simple solution to allow such shaders to link is to omit the two qualifiers.
|
|
||||||
// Note that the two flags only take effect on ESSL3 input shaders translated to GLSL 4.1 or lower.
|
|
||||||
// TODO(zmo): This is not a good long-term solution. Simply dropping these qualifiers may break some
|
|
||||||
// developers' content. A more complex workaround of dynamically generating, compiling, and
|
|
||||||
// re-linking shaders that use these qualifiers should be implemented.
|
|
||||||
const ShCompileOptions SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3 = UINT64_C(1) << 30;
|
|
||||||
|
|
||||||
// Defines alternate strategies for implementing array index clamping.
|
// Defines alternate strategies for implementing array index clamping.
|
||||||
enum ShArrayIndexClampingStrategy
|
typedef enum {
|
||||||
{
|
// Use the clamp intrinsic for array index clamping.
|
||||||
// Use the clamp intrinsic for array index clamping.
|
SH_CLAMP_WITH_CLAMP_INTRINSIC = 1,
|
||||||
SH_CLAMP_WITH_CLAMP_INTRINSIC = 1,
|
|
||||||
|
|
||||||
// Use a user-defined function for array index clamping.
|
// Use a user-defined function for array index clamping.
|
||||||
SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION
|
SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION
|
||||||
};
|
} ShArrayIndexClampingStrategy;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Driver must call this first, once, before doing any other
|
||||||
|
// compiler operations.
|
||||||
|
// If the function succeeds, the return value is true, else false.
|
||||||
|
//
|
||||||
|
COMPILER_EXPORT bool ShInitialize();
|
||||||
|
//
|
||||||
|
// Driver should call this at shutdown.
|
||||||
|
// If the function succeeds, the return value is true, else false.
|
||||||
|
//
|
||||||
|
COMPILER_EXPORT bool ShFinalize();
|
||||||
|
|
||||||
// The 64 bits hash function. The first parameter is the input string; the
|
// The 64 bits hash function. The first parameter is the input string; the
|
||||||
// second parameter is the string length.
|
// second parameter is the string length.
|
||||||
using ShHashFunction64 = khronos_uint64_t (*)(const char *, size_t);
|
typedef khronos_uint64_t (*ShHashFunction64)(const char*, size_t);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Implementation dependent built-in resources (constants and extensions).
|
// Implementation dependent built-in resources (constants and extensions).
|
||||||
// The names for these resources has been obtained by stripping gl_/GL_.
|
// The names for these resources has been obtained by stripping gl_/GL_.
|
||||||
//
|
//
|
||||||
struct ShBuiltInResources
|
typedef struct
|
||||||
{
|
{
|
||||||
// Constants.
|
// Constants.
|
||||||
int MaxVertexAttribs;
|
int MaxVertexAttribs;
|
||||||
|
|
@ -361,7 +394,15 @@ struct ShBuiltInResources
|
||||||
|
|
||||||
// maximum number of buffer object storage in machine units
|
// maximum number of buffer object storage in machine units
|
||||||
int MaxAtomicCounterBufferSize;
|
int MaxAtomicCounterBufferSize;
|
||||||
};
|
|
||||||
|
} ShBuiltInResources;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize built-in resources with minimum expected values.
|
||||||
|
// Parameters:
|
||||||
|
// resources: The object to initialize. Will be comparable with memcmp.
|
||||||
|
//
|
||||||
|
COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources);
|
||||||
|
|
||||||
//
|
//
|
||||||
// ShHandle held by but opaque to the driver. It is allocated,
|
// ShHandle held by but opaque to the driver. It is allocated,
|
||||||
|
|
@ -370,26 +411,7 @@ struct ShBuiltInResources
|
||||||
//
|
//
|
||||||
// If handle creation fails, 0 will be returned.
|
// If handle creation fails, 0 will be returned.
|
||||||
//
|
//
|
||||||
using ShHandle = void *;
|
typedef void *ShHandle;
|
||||||
|
|
||||||
//
|
|
||||||
// Driver must call this first, once, before doing any other
|
|
||||||
// compiler operations.
|
|
||||||
// If the function succeeds, the return value is true, else false.
|
|
||||||
//
|
|
||||||
bool ShInitialize();
|
|
||||||
//
|
|
||||||
// Driver should call this at shutdown.
|
|
||||||
// If the function succeeds, the return value is true, else false.
|
|
||||||
//
|
|
||||||
bool ShFinalize();
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize built-in resources with minimum expected values.
|
|
||||||
// Parameters:
|
|
||||||
// resources: The object to initialize. Will be comparable with memcmp.
|
|
||||||
//
|
|
||||||
void ShInitBuiltInResources(ShBuiltInResources *resources);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Returns the a concatenated list of the items in ShBuiltInResources as a
|
// Returns the a concatenated list of the items in ShBuiltInResources as a
|
||||||
|
|
@ -397,7 +419,7 @@ void ShInitBuiltInResources(ShBuiltInResources *resources);
|
||||||
// This function must be updated whenever ShBuiltInResources is changed.
|
// This function must be updated whenever ShBuiltInResources is changed.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// handle: Specifies the handle of the compiler to be used.
|
// handle: Specifies the handle of the compiler to be used.
|
||||||
const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
|
COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Driver calls these to create and destroy compiler objects.
|
// Driver calls these to create and destroy compiler objects.
|
||||||
|
|
@ -412,11 +434,12 @@ const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
|
||||||
// SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only
|
// SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only
|
||||||
// be supported in some configurations.
|
// be supported in some configurations.
|
||||||
// resources: Specifies the built-in resources.
|
// resources: Specifies the built-in resources.
|
||||||
ShHandle ShConstructCompiler(sh::GLenum type,
|
COMPILER_EXPORT ShHandle ShConstructCompiler(
|
||||||
ShShaderSpec spec,
|
sh::GLenum type,
|
||||||
ShShaderOutput output,
|
ShShaderSpec spec,
|
||||||
const ShBuiltInResources *resources);
|
ShShaderOutput output,
|
||||||
void ShDestruct(ShHandle handle);
|
const ShBuiltInResources *resources);
|
||||||
|
COMPILER_EXPORT void ShDestruct(ShHandle handle);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Compiles the given shader source.
|
// Compiles the given shader source.
|
||||||
|
|
@ -436,42 +459,45 @@ void ShDestruct(ShHandle handle);
|
||||||
// There is no need to specify this parameter when
|
// There is no need to specify this parameter when
|
||||||
// compiling for WebGL - it is implied.
|
// compiling for WebGL - it is implied.
|
||||||
// SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
|
// SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
|
||||||
// Can be queried by calling sh::GetInfoLog().
|
// Can be queried by calling ShGetInfoLog().
|
||||||
// SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
|
// SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
|
||||||
// Can be queried by calling sh::GetObjectCode().
|
// Can be queried by calling ShGetObjectCode().
|
||||||
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
|
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
|
||||||
// Can be queried by calling ShGetVariableInfo().
|
// Can be queried by calling ShGetVariableInfo().
|
||||||
//
|
//
|
||||||
bool ShCompile(const ShHandle handle,
|
COMPILER_EXPORT bool ShCompile(
|
||||||
const char *const shaderStrings[],
|
const ShHandle handle,
|
||||||
size_t numStrings,
|
const char * const shaderStrings[],
|
||||||
ShCompileOptions compileOptions);
|
size_t numStrings,
|
||||||
|
int compileOptions);
|
||||||
|
|
||||||
// Clears the results from the previous compilation.
|
// Clears the results from the previous compilation.
|
||||||
void ShClearResults(const ShHandle handle);
|
COMPILER_EXPORT void ShClearResults(const ShHandle handle);
|
||||||
|
|
||||||
// Return the version of the shader language.
|
// Return the version of the shader language.
|
||||||
int ShGetShaderVersion(const ShHandle handle);
|
COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle);
|
||||||
|
|
||||||
// Return the currently set language output type.
|
// Return the currently set language output type.
|
||||||
ShShaderOutput ShGetShaderOutputType(const ShHandle handle);
|
COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType(
|
||||||
|
const ShHandle handle);
|
||||||
|
|
||||||
// Returns null-terminated information log for a compiled shader.
|
// Returns null-terminated information log for a compiled shader.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// handle: Specifies the compiler
|
// handle: Specifies the compiler
|
||||||
const std::string &ShGetInfoLog(const ShHandle handle);
|
COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle);
|
||||||
|
|
||||||
// Returns null-terminated object code for a compiled shader.
|
// Returns null-terminated object code for a compiled shader.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// handle: Specifies the compiler
|
// handle: Specifies the compiler
|
||||||
const std::string &ShGetObjectCode(const ShHandle handle);
|
COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle);
|
||||||
|
|
||||||
// Returns a (original_name, hash) map containing all the user defined
|
// Returns a (original_name, hash) map containing all the user defined
|
||||||
// names in the shader, including variable names, function names, struct
|
// names in the shader, including variable names, function names, struct
|
||||||
// names, and struct field names.
|
// names, and struct field names.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// handle: Specifies the compiler
|
// handle: Specifies the compiler
|
||||||
const std::map<std::string, std::string> *ShGetNameHashingMap(const ShHandle handle);
|
COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
|
||||||
|
const ShHandle handle);
|
||||||
|
|
||||||
// Shader variable inspection.
|
// Shader variable inspection.
|
||||||
// Returns a pointer to a list of variables of the designated type.
|
// Returns a pointer to a list of variables of the designated type.
|
||||||
|
|
@ -479,12 +505,18 @@ const std::map<std::string, std::string> *ShGetNameHashingMap(const ShHandle han
|
||||||
// Returns NULL on failure.
|
// Returns NULL on failure.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// handle: Specifies the compiler
|
// handle: Specifies the compiler
|
||||||
const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle);
|
COMPILER_EXPORT const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle);
|
||||||
const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle);
|
COMPILER_EXPORT const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle);
|
||||||
const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle);
|
COMPILER_EXPORT const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle);
|
||||||
const std::vector<sh::OutputVariable> *ShGetOutputVariables(const ShHandle handle);
|
COMPILER_EXPORT const std::vector<sh::OutputVariable> *ShGetOutputVariables(const ShHandle handle);
|
||||||
const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle);
|
COMPILER_EXPORT const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle);
|
||||||
sh::WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle);
|
COMPILER_EXPORT sh::WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
sh::GLenum type;
|
||||||
|
int size;
|
||||||
|
} ShVariableInfo;
|
||||||
|
|
||||||
// Returns true if the passed in variables pack in maxVectors following
|
// Returns true if the passed in variables pack in maxVectors following
|
||||||
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
|
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
|
||||||
|
|
@ -493,8 +525,9 @@ sh::WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle);
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// maxVectors: the available rows of registers.
|
// maxVectors: the available rows of registers.
|
||||||
// variables: an array of variables.
|
// variables: an array of variables.
|
||||||
bool ShCheckVariablesWithinPackingLimits(int maxVectors,
|
COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
|
||||||
const std::vector<sh::ShaderVariable> &variables);
|
int maxVectors,
|
||||||
|
const std::vector<sh::ShaderVariable> &variables);
|
||||||
|
|
||||||
// Gives the compiler-assigned register for an interface block.
|
// Gives the compiler-assigned register for an interface block.
|
||||||
// The method writes the value to the output variable "indexOut".
|
// The method writes the value to the output variable "indexOut".
|
||||||
|
|
@ -503,155 +536,14 @@ bool ShCheckVariablesWithinPackingLimits(int maxVectors,
|
||||||
// handle: Specifies the compiler
|
// handle: Specifies the compiler
|
||||||
// interfaceBlockName: Specifies the interface block
|
// interfaceBlockName: Specifies the interface block
|
||||||
// indexOut: output variable that stores the assigned register
|
// indexOut: output variable that stores the assigned register
|
||||||
bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||||
const std::string &interfaceBlockName,
|
const std::string &interfaceBlockName,
|
||||||
unsigned int *indexOut);
|
unsigned int *indexOut);
|
||||||
|
|
||||||
// Gives a map from uniform names to compiler-assigned registers in the default
|
// Gives a map from uniform names to compiler-assigned registers in the default
|
||||||
// interface block. Note that the map contains also registers of samplers that
|
// interface block. Note that the map contains also registers of samplers that
|
||||||
// have been extracted from structs.
|
// have been extracted from structs.
|
||||||
const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(const ShHandle handle);
|
COMPILER_EXPORT const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(
|
||||||
|
const ShHandle handle);
|
||||||
// Temporary duplicate of the scoped APIs, to be removed when we roll ANGLE and fix Chromium.
|
|
||||||
// TODO(jmadill): Consolidate with these APIs once we roll ANGLE.
|
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
|
||||||
// Driver must call this first, once, before doing any other compiler operations.
|
|
||||||
// If the function succeeds, the return value is true, else false.
|
|
||||||
//
|
|
||||||
bool Initialize();
|
|
||||||
//
|
|
||||||
// Driver should call this at shutdown.
|
|
||||||
// If the function succeeds, the return value is true, else false.
|
|
||||||
//
|
|
||||||
bool Finalize();
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize built-in resources with minimum expected values.
|
|
||||||
// Parameters:
|
|
||||||
// resources: The object to initialize. Will be comparable with memcmp.
|
|
||||||
//
|
|
||||||
void InitBuiltInResources(ShBuiltInResources *resources);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Returns the a concatenated list of the items in ShBuiltInResources as a null-terminated string.
|
|
||||||
// This function must be updated whenever ShBuiltInResources is changed.
|
|
||||||
// Parameters:
|
|
||||||
// handle: Specifies the handle of the compiler to be used.
|
|
||||||
const std::string &GetBuiltInResourcesString(const ShHandle handle);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Driver calls these to create and destroy compiler objects.
|
|
||||||
//
|
|
||||||
// Returns the handle of constructed compiler, null if the requested compiler is not supported.
|
|
||||||
// Parameters:
|
|
||||||
// type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER.
|
|
||||||
// spec: Specifies the language spec the compiler must conform to - SH_GLES2_SPEC or SH_WEBGL_SPEC.
|
|
||||||
// output: Specifies the output code type - for example SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
|
|
||||||
// SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only
|
|
||||||
// be supported in some configurations.
|
|
||||||
// resources: Specifies the built-in resources.
|
|
||||||
ShHandle ConstructCompiler(sh::GLenum type,
|
|
||||||
ShShaderSpec spec,
|
|
||||||
ShShaderOutput output,
|
|
||||||
const ShBuiltInResources *resources);
|
|
||||||
void Destruct(ShHandle handle);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Compiles the given shader source.
|
|
||||||
// If the function succeeds, the return value is true, else false.
|
|
||||||
// Parameters:
|
|
||||||
// handle: Specifies the handle of compiler to be used.
|
|
||||||
// shaderStrings: Specifies an array of pointers to null-terminated strings containing the shader
|
|
||||||
// source code.
|
|
||||||
// numStrings: Specifies the number of elements in shaderStrings array.
|
|
||||||
// compileOptions: A mask containing the following parameters:
|
|
||||||
// SH_VALIDATE: Validates shader to ensure that it conforms to the spec
|
|
||||||
// specified during compiler construction.
|
|
||||||
// SH_VALIDATE_LOOP_INDEXING: Validates loop and indexing in the shader to
|
|
||||||
// ensure that they do not exceed the minimum
|
|
||||||
// functionality mandated in GLSL 1.0 spec,
|
|
||||||
// Appendix A, Section 4 and 5.
|
|
||||||
// There is no need to specify this parameter when
|
|
||||||
// compiling for WebGL - it is implied.
|
|
||||||
// SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
|
|
||||||
// Can be queried by calling sh::GetInfoLog().
|
|
||||||
// SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
|
|
||||||
// Can be queried by calling sh::GetObjectCode().
|
|
||||||
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
|
|
||||||
// Can be queried by calling ShGetVariableInfo().
|
|
||||||
//
|
|
||||||
bool Compile(const ShHandle handle,
|
|
||||||
const char *const shaderStrings[],
|
|
||||||
size_t numStrings,
|
|
||||||
ShCompileOptions compileOptions);
|
|
||||||
|
|
||||||
// Clears the results from the previous compilation.
|
|
||||||
void ClearResults(const ShHandle handle);
|
|
||||||
|
|
||||||
// Return the version of the shader language.
|
|
||||||
int GetShaderVersion(const ShHandle handle);
|
|
||||||
|
|
||||||
// Return the currently set language output type.
|
|
||||||
ShShaderOutput GetShaderOutputType(const ShHandle handle);
|
|
||||||
|
|
||||||
// Returns null-terminated information log for a compiled shader.
|
|
||||||
// Parameters:
|
|
||||||
// handle: Specifies the compiler
|
|
||||||
const std::string &GetInfoLog(const ShHandle handle);
|
|
||||||
|
|
||||||
// Returns null-terminated object code for a compiled shader.
|
|
||||||
// Parameters:
|
|
||||||
// handle: Specifies the compiler
|
|
||||||
const std::string &GetObjectCode(const ShHandle handle);
|
|
||||||
|
|
||||||
// Returns a (original_name, hash) map containing all the user defined names in the shader,
|
|
||||||
// including variable names, function names, struct names, and struct field names.
|
|
||||||
// Parameters:
|
|
||||||
// handle: Specifies the compiler
|
|
||||||
const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle);
|
|
||||||
|
|
||||||
// Shader variable inspection.
|
|
||||||
// Returns a pointer to a list of variables of the designated type.
|
|
||||||
// (See ShaderVars.h for type definitions, included above)
|
|
||||||
// Returns NULL on failure.
|
|
||||||
// Parameters:
|
|
||||||
// handle: Specifies the compiler
|
|
||||||
const std::vector<sh::Uniform> *GetUniforms(const ShHandle handle);
|
|
||||||
const std::vector<sh::Varying> *GetVaryings(const ShHandle handle);
|
|
||||||
const std::vector<sh::Attribute> *GetAttributes(const ShHandle handle);
|
|
||||||
const std::vector<sh::OutputVariable> *GetOutputVariables(const ShHandle handle);
|
|
||||||
const std::vector<sh::InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle);
|
|
||||||
sh::WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle);
|
|
||||||
|
|
||||||
// Returns true if the passed in variables pack in maxVectors followingthe packing rules from the
|
|
||||||
// GLSL 1.017 spec, Appendix A, section 7.
|
|
||||||
// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
|
|
||||||
// flag above.
|
|
||||||
// Parameters:
|
|
||||||
// maxVectors: the available rows of registers.
|
|
||||||
// variables: an array of variables.
|
|
||||||
bool CheckVariablesWithinPackingLimits(int maxVectors,
|
|
||||||
const std::vector<sh::ShaderVariable> &variables);
|
|
||||||
|
|
||||||
// Gives the compiler-assigned register for an interface block.
|
|
||||||
// The method writes the value to the output variable "indexOut".
|
|
||||||
// Returns true if it found a valid interface block, false otherwise.
|
|
||||||
// Parameters:
|
|
||||||
// handle: Specifies the compiler
|
|
||||||
// interfaceBlockName: Specifies the interface block
|
|
||||||
// indexOut: output variable that stores the assigned register
|
|
||||||
bool GetInterfaceBlockRegister(const ShHandle handle,
|
|
||||||
const std::string &interfaceBlockName,
|
|
||||||
unsigned int *indexOut);
|
|
||||||
|
|
||||||
// Gives a map from uniform names to compiler-assigned registers in the default interface block.
|
|
||||||
// Note that the map contains also registers of samplers that have been extracted from structs.
|
|
||||||
const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle);
|
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // GLSLANG_SHADERLANG_H_
|
#endif // GLSLANG_SHADERLANG_H_
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ enum InterpolationType
|
||||||
};
|
};
|
||||||
|
|
||||||
// Validate link & SSO consistency of interpolation qualifiers
|
// Validate link & SSO consistency of interpolation qualifiers
|
||||||
bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
|
COMPILER_EXPORT bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
|
||||||
|
|
||||||
// Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
|
// Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
|
||||||
enum BlockLayoutType
|
enum BlockLayoutType
|
||||||
|
|
@ -43,7 +43,7 @@ enum BlockLayoutType
|
||||||
// Note: we must override the copy constructor and assignment operator so we can
|
// Note: we must override the copy constructor and assignment operator so we can
|
||||||
// work around excessive GCC binary bloating:
|
// work around excessive GCC binary bloating:
|
||||||
// See https://code.google.com/p/angleproject/issues/detail?id=697
|
// See https://code.google.com/p/angleproject/issues/detail?id=697
|
||||||
struct ShaderVariable
|
struct COMPILER_EXPORT ShaderVariable
|
||||||
{
|
{
|
||||||
ShaderVariable();
|
ShaderVariable();
|
||||||
ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
|
ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
|
||||||
|
|
@ -92,7 +92,7 @@ struct ShaderVariable
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Uniform : public ShaderVariable
|
struct COMPILER_EXPORT Uniform : public ShaderVariable
|
||||||
{
|
{
|
||||||
Uniform();
|
Uniform();
|
||||||
~Uniform();
|
~Uniform();
|
||||||
|
|
@ -113,7 +113,7 @@ struct Uniform : public ShaderVariable
|
||||||
// An interface variable is a variable which passes data between the GL data structures and the
|
// 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
|
// shader execution: either vertex shader inputs or fragment shader outputs. These variables can
|
||||||
// have integer locations to pass back to the GL API.
|
// have integer locations to pass back to the GL API.
|
||||||
struct InterfaceVariable : public ShaderVariable
|
struct COMPILER_EXPORT InterfaceVariable : public ShaderVariable
|
||||||
{
|
{
|
||||||
InterfaceVariable();
|
InterfaceVariable();
|
||||||
~InterfaceVariable();
|
~InterfaceVariable();
|
||||||
|
|
@ -125,7 +125,7 @@ struct InterfaceVariable : public ShaderVariable
|
||||||
int location;
|
int location;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Attribute : public InterfaceVariable
|
struct COMPILER_EXPORT Attribute : public InterfaceVariable
|
||||||
{
|
{
|
||||||
Attribute();
|
Attribute();
|
||||||
~Attribute();
|
~Attribute();
|
||||||
|
|
@ -135,7 +135,7 @@ struct Attribute : public InterfaceVariable
|
||||||
bool operator!=(const Attribute &other) const { return !operator==(other); }
|
bool operator!=(const Attribute &other) const { return !operator==(other); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OutputVariable : public InterfaceVariable
|
struct COMPILER_EXPORT OutputVariable : public InterfaceVariable
|
||||||
{
|
{
|
||||||
OutputVariable();
|
OutputVariable();
|
||||||
~OutputVariable();
|
~OutputVariable();
|
||||||
|
|
@ -145,7 +145,7 @@ struct OutputVariable : public InterfaceVariable
|
||||||
bool operator!=(const OutputVariable &other) const { return !operator==(other); }
|
bool operator!=(const OutputVariable &other) const { return !operator==(other); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InterfaceBlockField : public ShaderVariable
|
struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
|
||||||
{
|
{
|
||||||
InterfaceBlockField();
|
InterfaceBlockField();
|
||||||
~InterfaceBlockField();
|
~InterfaceBlockField();
|
||||||
|
|
@ -167,7 +167,7 @@ struct InterfaceBlockField : public ShaderVariable
|
||||||
bool isRowMajorLayout;
|
bool isRowMajorLayout;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Varying : public ShaderVariable
|
struct COMPILER_EXPORT Varying : public ShaderVariable
|
||||||
{
|
{
|
||||||
Varying();
|
Varying();
|
||||||
~Varying();
|
~Varying();
|
||||||
|
|
@ -193,7 +193,7 @@ struct Varying : public ShaderVariable
|
||||||
bool isInvariant;
|
bool isInvariant;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InterfaceBlock
|
struct COMPILER_EXPORT InterfaceBlock
|
||||||
{
|
{
|
||||||
InterfaceBlock();
|
InterfaceBlock();
|
||||||
~InterfaceBlock();
|
~InterfaceBlock();
|
||||||
|
|
@ -216,7 +216,7 @@ struct InterfaceBlock
|
||||||
std::vector<InterfaceBlockField> fields;
|
std::vector<InterfaceBlockField> fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WorkGroupSize
|
struct COMPILER_EXPORT WorkGroupSize
|
||||||
{
|
{
|
||||||
void fill(int fillValue);
|
void fill(int fillValue);
|
||||||
void setLocalSize(int localSizeX, int localSizeY, int localSizeZ);
|
void setLocalSize(int localSizeX, int localSizeY, int localSizeZ);
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,13 @@
|
||||||
#define LIBGLESV2_EXPORT_H_
|
#define LIBGLESV2_EXPORT_H_
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) || \
|
# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION)
|
||||||
defined(LIBANGLE_UTIL_IMPLEMENTATION)
|
|
||||||
# define ANGLE_EXPORT __declspec(dllexport)
|
# define ANGLE_EXPORT __declspec(dllexport)
|
||||||
# else
|
# else
|
||||||
# define ANGLE_EXPORT __declspec(dllimport)
|
# define ANGLE_EXPORT __declspec(dllimport)
|
||||||
# endif
|
# endif
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) || \
|
# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION)
|
||||||
defined(LIBANGLE_UTIL_IMPLEMENTATION)
|
|
||||||
# define ANGLE_EXPORT __attribute__((visibility ("default")))
|
# define ANGLE_EXPORT __attribute__((visibility ("default")))
|
||||||
# else
|
# else
|
||||||
# define ANGLE_EXPORT
|
# define ANGLE_EXPORT
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,11 @@ UNIFIED_SOURCES += [
|
||||||
'src/compiler/preprocessor/Preprocessor.cpp',
|
'src/compiler/preprocessor/Preprocessor.cpp',
|
||||||
'src/compiler/preprocessor/Token.cpp',
|
'src/compiler/preprocessor/Token.cpp',
|
||||||
'src/compiler/preprocessor/Tokenizer.cpp',
|
'src/compiler/preprocessor/Tokenizer.cpp',
|
||||||
'src/compiler/translator/AddAndTrueToLoopCondition.cpp',
|
|
||||||
'src/compiler/translator/AddDefaultReturnStatements.cpp',
|
'src/compiler/translator/AddDefaultReturnStatements.cpp',
|
||||||
'src/compiler/translator/ArrayReturnValueToOutParameter.cpp',
|
'src/compiler/translator/ArrayReturnValueToOutParameter.cpp',
|
||||||
'src/compiler/translator/ASTMetadataHLSL.cpp',
|
'src/compiler/translator/ASTMetadataHLSL.cpp',
|
||||||
'src/compiler/translator/blocklayout.cpp',
|
'src/compiler/translator/blocklayout.cpp',
|
||||||
'src/compiler/translator/blocklayoutHLSL.cpp',
|
'src/compiler/translator/blocklayoutHLSL.cpp',
|
||||||
'src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp',
|
|
||||||
'src/compiler/translator/BuiltInFunctionEmulator.cpp',
|
'src/compiler/translator/BuiltInFunctionEmulator.cpp',
|
||||||
'src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
|
'src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
|
||||||
'src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp',
|
'src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp',
|
||||||
|
|
@ -42,8 +40,11 @@ UNIFIED_SOURCES += [
|
||||||
'src/compiler/translator/CallDAG.cpp',
|
'src/compiler/translator/CallDAG.cpp',
|
||||||
'src/compiler/translator/CodeGen.cpp',
|
'src/compiler/translator/CodeGen.cpp',
|
||||||
'src/compiler/translator/Compiler.cpp',
|
'src/compiler/translator/Compiler.cpp',
|
||||||
'src/compiler/translator/ConstantUnion.cpp',
|
|
||||||
'src/compiler/translator/DeferGlobalInitializers.cpp',
|
'src/compiler/translator/DeferGlobalInitializers.cpp',
|
||||||
|
'src/compiler/translator/depgraph/DependencyGraph.cpp',
|
||||||
|
'src/compiler/translator/depgraph/DependencyGraphBuilder.cpp',
|
||||||
|
'src/compiler/translator/depgraph/DependencyGraphOutput.cpp',
|
||||||
|
'src/compiler/translator/depgraph/DependencyGraphTraverse.cpp',
|
||||||
'src/compiler/translator/Diagnostics.cpp',
|
'src/compiler/translator/Diagnostics.cpp',
|
||||||
'src/compiler/translator/DirectiveHandler.cpp',
|
'src/compiler/translator/DirectiveHandler.cpp',
|
||||||
'src/compiler/translator/EmulatePrecision.cpp',
|
'src/compiler/translator/EmulatePrecision.cpp',
|
||||||
|
|
@ -70,27 +71,28 @@ UNIFIED_SOURCES += [
|
||||||
'src/compiler/translator/ParseContext.cpp',
|
'src/compiler/translator/ParseContext.cpp',
|
||||||
'src/compiler/translator/PoolAlloc.cpp',
|
'src/compiler/translator/PoolAlloc.cpp',
|
||||||
'src/compiler/translator/PruneEmptyDeclarations.cpp',
|
'src/compiler/translator/PruneEmptyDeclarations.cpp',
|
||||||
'src/compiler/translator/QualifierTypes.cpp',
|
|
||||||
'src/compiler/translator/RecordConstantPrecision.cpp',
|
'src/compiler/translator/RecordConstantPrecision.cpp',
|
||||||
'src/compiler/translator/RegenerateStructNames.cpp',
|
'src/compiler/translator/RegenerateStructNames.cpp',
|
||||||
'src/compiler/translator/RemoveDynamicIndexing.cpp',
|
'src/compiler/translator/RemoveDynamicIndexing.cpp',
|
||||||
'src/compiler/translator/RemoveInvariantDeclaration.cpp',
|
|
||||||
'src/compiler/translator/RemovePow.cpp',
|
'src/compiler/translator/RemovePow.cpp',
|
||||||
'src/compiler/translator/RemoveSwitchFallThrough.cpp',
|
'src/compiler/translator/RemoveSwitchFallThrough.cpp',
|
||||||
'src/compiler/translator/RewriteDoWhile.cpp',
|
'src/compiler/translator/RewriteDoWhile.cpp',
|
||||||
'src/compiler/translator/RewriteElseBlocks.cpp',
|
'src/compiler/translator/RewriteElseBlocks.cpp',
|
||||||
'src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
|
'src/compiler/translator/RewriteTexelFetchOffset.cpp',
|
||||||
'src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
|
'src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
|
||||||
'src/compiler/translator/SearchSymbol.cpp',
|
'src/compiler/translator/SearchSymbol.cpp',
|
||||||
'src/compiler/translator/SeparateArrayInitialization.cpp',
|
'src/compiler/translator/SeparateArrayInitialization.cpp',
|
||||||
'src/compiler/translator/SeparateDeclarations.cpp',
|
'src/compiler/translator/SeparateDeclarations.cpp',
|
||||||
'src/compiler/translator/SeparateExpressionsReturningArrays.cpp',
|
'src/compiler/translator/SeparateExpressionsReturningArrays.cpp',
|
||||||
|
'src/compiler/translator/ShaderLang.cpp',
|
||||||
'src/compiler/translator/ShaderVars.cpp',
|
'src/compiler/translator/ShaderVars.cpp',
|
||||||
'src/compiler/translator/SimplifyLoopConditions.cpp',
|
'src/compiler/translator/SimplifyLoopConditions.cpp',
|
||||||
'src/compiler/translator/SplitSequenceOperator.cpp',
|
'src/compiler/translator/SplitSequenceOperator.cpp',
|
||||||
'src/compiler/translator/StructureHLSL.cpp',
|
'src/compiler/translator/StructureHLSL.cpp',
|
||||||
'src/compiler/translator/SymbolTable.cpp',
|
'src/compiler/translator/SymbolTable.cpp',
|
||||||
'src/compiler/translator/TextureFunctionHLSL.cpp',
|
'src/compiler/translator/TextureFunctionHLSL.cpp',
|
||||||
|
'src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp',
|
||||||
|
'src/compiler/translator/timing/RestrictVertexShaderTiming.cpp',
|
||||||
'src/compiler/translator/TranslatorESSL.cpp',
|
'src/compiler/translator/TranslatorESSL.cpp',
|
||||||
'src/compiler/translator/TranslatorGLSL.cpp',
|
'src/compiler/translator/TranslatorGLSL.cpp',
|
||||||
'src/compiler/translator/TranslatorHLSL.cpp',
|
'src/compiler/translator/TranslatorHLSL.cpp',
|
||||||
|
|
@ -98,7 +100,6 @@ UNIFIED_SOURCES += [
|
||||||
'src/compiler/translator/UnfoldShortCircuitAST.cpp',
|
'src/compiler/translator/UnfoldShortCircuitAST.cpp',
|
||||||
'src/compiler/translator/UnfoldShortCircuitToIf.cpp',
|
'src/compiler/translator/UnfoldShortCircuitToIf.cpp',
|
||||||
'src/compiler/translator/UniformHLSL.cpp',
|
'src/compiler/translator/UniformHLSL.cpp',
|
||||||
'src/compiler/translator/UseInterfaceBlockFields.cpp',
|
|
||||||
'src/compiler/translator/util.cpp',
|
'src/compiler/translator/util.cpp',
|
||||||
'src/compiler/translator/UtilsHLSL.cpp',
|
'src/compiler/translator/UtilsHLSL.cpp',
|
||||||
'src/compiler/translator/ValidateGlobalInitializer.cpp',
|
'src/compiler/translator/ValidateGlobalInitializer.cpp',
|
||||||
|
|
@ -115,8 +116,6 @@ SOURCES += [
|
||||||
'src/compiler/translator/EmulateGLFragColorBroadcast.cpp',
|
'src/compiler/translator/EmulateGLFragColorBroadcast.cpp',
|
||||||
'src/compiler/translator/glslang_lex.cpp',
|
'src/compiler/translator/glslang_lex.cpp',
|
||||||
'src/compiler/translator/glslang_tab.cpp',
|
'src/compiler/translator/glslang_tab.cpp',
|
||||||
'src/compiler/translator/RewriteTexelFetchOffset.cpp',
|
|
||||||
'src/compiler/translator/ShaderLang.cpp',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@
|
||||||
'angle_enable_gl%': 1,
|
'angle_enable_gl%': 1,
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
'angle_enable_null%': 1, # Available on all platforms
|
|
||||||
},
|
},
|
||||||
'includes':
|
'includes':
|
||||||
[
|
[
|
||||||
|
|
@ -59,7 +58,7 @@
|
||||||
{
|
{
|
||||||
'target_name': 'angle_common',
|
'target_name': 'angle_common',
|
||||||
'type': 'static_library',
|
'type': 'static_library',
|
||||||
'includes': [ '../gyp/common_defines.gypi', ],
|
'includes': [ '../build/common_defines.gypi', ],
|
||||||
'sources':
|
'sources':
|
||||||
[
|
[
|
||||||
'<@(libangle_common_sources)',
|
'<@(libangle_common_sources)',
|
||||||
|
|
@ -146,7 +145,7 @@
|
||||||
{
|
{
|
||||||
'target_name': 'angle_image_util',
|
'target_name': 'angle_image_util',
|
||||||
'type': 'static_library',
|
'type': 'static_library',
|
||||||
'includes': [ '../gyp/common_defines.gypi', ],
|
'includes': [ '../build/common_defines.gypi', ],
|
||||||
'sources':
|
'sources':
|
||||||
[
|
[
|
||||||
'<@(libangle_image_util_sources)',
|
'<@(libangle_image_util_sources)',
|
||||||
|
|
@ -173,7 +172,7 @@
|
||||||
{
|
{
|
||||||
'target_name': 'copy_scripts',
|
'target_name': 'copy_scripts',
|
||||||
'type': 'none',
|
'type': 'none',
|
||||||
'includes': [ '../gyp/common_defines.gypi', ],
|
'includes': [ '../build/common_defines.gypi', ],
|
||||||
'hard_dependency': 1,
|
'hard_dependency': 1,
|
||||||
'copies':
|
'copies':
|
||||||
[
|
[
|
||||||
|
|
@ -200,7 +199,7 @@
|
||||||
{
|
{
|
||||||
'target_name': 'commit_id',
|
'target_name': 'commit_id',
|
||||||
'type': 'none',
|
'type': 'none',
|
||||||
'includes': [ '../gyp/common_defines.gypi', ],
|
'includes': [ '../build/common_defines.gypi', ],
|
||||||
'dependencies': [ 'copy_scripts', ],
|
'dependencies': [ 'copy_scripts', ],
|
||||||
'hard_dependency': 1,
|
'hard_dependency': 1,
|
||||||
'actions':
|
'actions':
|
||||||
|
|
@ -242,7 +241,7 @@
|
||||||
'target_name': 'commit_id',
|
'target_name': 'commit_id',
|
||||||
'type': 'none',
|
'type': 'none',
|
||||||
'hard_dependency': 1,
|
'hard_dependency': 1,
|
||||||
'includes': [ '../gyp/common_defines.gypi', ],
|
'includes': [ '../build/common_defines.gypi', ],
|
||||||
'copies':
|
'copies':
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
|
@ -275,7 +274,7 @@
|
||||||
'target_name': 'copy_compiler_dll',
|
'target_name': 'copy_compiler_dll',
|
||||||
'type': 'none',
|
'type': 'none',
|
||||||
'dependencies': [ 'copy_scripts', ],
|
'dependencies': [ 'copy_scripts', ],
|
||||||
'includes': [ '../gyp/common_defines.gypi', ],
|
'includes': [ '../build/common_defines.gypi', ],
|
||||||
'conditions':
|
'conditions':
|
||||||
[
|
[
|
||||||
['angle_build_winrt==0',
|
['angle_build_winrt==0',
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
#define ANGLE_COMMIT_HASH "2a250c8a0e15"
|
#define ANGLE_COMMIT_HASH ""
|
||||||
#define ANGLE_COMMIT_HASH_SIZE 12
|
#define ANGLE_COMMIT_HASH_SIZE 12
|
||||||
#define ANGLE_COMMIT_DATE "2016-11-23 17:58:16 +0800"
|
#define ANGLE_COMMIT_DATE ""
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ inline unsigned long ScanForward(unsigned long bits)
|
||||||
unsigned long firstBitIndex = 0ul;
|
unsigned long firstBitIndex = 0ul;
|
||||||
unsigned char ret = _BitScanForward(&firstBitIndex, bits);
|
unsigned char ret = _BitScanForward(&firstBitIndex, bits);
|
||||||
ASSERT(ret != 0);
|
ASSERT(ret != 0);
|
||||||
|
UNUSED_ASSERTION_VARIABLE(ret);
|
||||||
return firstBitIndex;
|
return firstBitIndex;
|
||||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||||
return static_cast<unsigned long>(__builtin_ctzl(bits));
|
return static_cast<unsigned long>(__builtin_ctzl(bits));
|
||||||
|
|
|
||||||
|
|
@ -156,14 +156,6 @@ size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>
|
||||||
std::string FormatString(const char *fmt, va_list vararg);
|
std::string FormatString(const char *fmt, va_list vararg);
|
||||||
std::string FormatString(const char *fmt, ...);
|
std::string FormatString(const char *fmt, ...);
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::string ToString(const T &value)
|
|
||||||
{
|
|
||||||
std::ostringstream o;
|
|
||||||
o << value;
|
|
||||||
return o.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// snprintf is not defined with MSVC prior to to msvc14
|
// snprintf is not defined with MSVC prior to to msvc14
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
|
|
|
||||||
|
|
@ -171,9 +171,4 @@ ScopedPerfEventHelper::~ScopedPerfEventHelper()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &DummyStream()
|
|
||||||
{
|
|
||||||
return std::cout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace gl
|
|
||||||
|
|
|
||||||
|
|
@ -57,20 +57,7 @@ void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator);
|
||||||
void UninitializeDebugAnnotations();
|
void UninitializeDebugAnnotations();
|
||||||
bool DebugAnnotationsActive();
|
bool DebugAnnotationsActive();
|
||||||
|
|
||||||
// This class is used to explicitly ignore values in the conditional logging macros. This avoids
|
}
|
||||||
// compiler warnings like "value computed is not used" and "statement has no effect".
|
|
||||||
class LogMessageVoidify
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LogMessageVoidify() {}
|
|
||||||
// This has to be an operator with a precedence lower than << but higher than ?:
|
|
||||||
void operator&(std::ostream &) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// This can be any ostream, it is unused, but needs to be a valid reference.
|
|
||||||
std::ostream &DummyStream();
|
|
||||||
|
|
||||||
} // namespace gl
|
|
||||||
|
|
||||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||||
#define ANGLE_TRACE_ENABLED
|
#define ANGLE_TRACE_ENABLED
|
||||||
|
|
@ -117,58 +104,61 @@ std::ostream &DummyStream();
|
||||||
#undef ANGLE_TRACE_ENABLED
|
#undef ANGLE_TRACE_ENABLED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(COMPILER_GCC) || defined(__clang__)
|
|
||||||
#define ANGLE_CRASH() __builtin_trap()
|
|
||||||
#else
|
|
||||||
#define ANGLE_CRASH() ((void)(*(volatile char *)0 = 0))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
#define ANGLE_ASSERT_IMPL(expression) assert(expression)
|
#define ANGLE_ASSERT_IMPL(expression) assert(expression)
|
||||||
#else
|
#else
|
||||||
// TODO(jmadill): Detect if debugger is attached and break.
|
// TODO(jmadill): Detect if debugger is attached and break.
|
||||||
#define ANGLE_ASSERT_IMPL(expression) ANGLE_CRASH()
|
#define ANGLE_ASSERT_IMPL(expression) abort()
|
||||||
#endif // !defined(NDEBUG)
|
#endif // !defined(NDEBUG)
|
||||||
|
|
||||||
// Helper macro which avoids evaluating the arguments to a stream if the condition doesn't hold.
|
|
||||||
// Condition is evaluated once and only once.
|
|
||||||
#define ANGLE_LAZY_STREAM(stream, condition) \
|
|
||||||
!(condition) ? static_cast<void>(0) : ::gl::LogMessageVoidify() & (stream)
|
|
||||||
|
|
||||||
#if defined(NDEBUG) && !defined(ANGLE_ENABLE_ASSERTS)
|
|
||||||
#define ANGLE_ASSERTS_ON 0
|
|
||||||
#else
|
|
||||||
#define ANGLE_ASSERTS_ON 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// A macro asserting a condition and outputting failures to the debug log
|
// A macro asserting a condition and outputting failures to the debug log
|
||||||
#if ANGLE_ASSERTS_ON
|
#if defined(ANGLE_ENABLE_ASSERTS)
|
||||||
#define ASSERT(expression) \
|
#define ASSERT(expression) \
|
||||||
(expression ? static_cast<void>(0) \
|
{ \
|
||||||
: (ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression), \
|
if (!(expression)) \
|
||||||
ANGLE_ASSERT_IMPL(expression)))
|
{ \
|
||||||
|
ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression); \
|
||||||
|
ANGLE_ASSERT_IMPL(expression); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
ANGLE_EMPTY_STATEMENT
|
||||||
|
#define UNUSED_ASSERTION_VARIABLE(variable)
|
||||||
#else
|
#else
|
||||||
#define ASSERT(condition) \
|
#define ASSERT(expression) (void(0))
|
||||||
ANGLE_LAZY_STREAM(::gl::DummyStream(), ANGLE_ASSERTS_ON ? !(condition) : false) \
|
#define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
|
||||||
<< "Check failed: " #condition ". "
|
#endif
|
||||||
#endif // ANGLE_ASSERTS_ON
|
|
||||||
|
|
||||||
#define UNUSED_VARIABLE(variable) ((void)variable)
|
#define UNUSED_VARIABLE(variable) ((void)variable)
|
||||||
|
|
||||||
// A macro to indicate unimplemented functionality
|
// A macro to indicate unimplemented functionality
|
||||||
#ifndef NOASSERT_UNIMPLEMENTED
|
|
||||||
|
#if defined (ANGLE_TEST_CONFIG)
|
||||||
#define NOASSERT_UNIMPLEMENTED 1
|
#define NOASSERT_UNIMPLEMENTED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UNIMPLEMENTED() \
|
// Define NOASSERT_UNIMPLEMENTED to non zero to skip the assert fail in the unimplemented checks
|
||||||
{ \
|
// This will allow us to test with some automated test suites (eg dEQP) without crashing
|
||||||
ERR("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \
|
#ifndef NOASSERT_UNIMPLEMENTED
|
||||||
ASSERT(NOASSERT_UNIMPLEMENTED); \
|
#define NOASSERT_UNIMPLEMENTED 0
|
||||||
} \
|
#endif
|
||||||
ANGLE_EMPTY_STATEMENT
|
|
||||||
|
#if !defined(NDEBUG)
|
||||||
|
#define UNIMPLEMENTED() { \
|
||||||
|
FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \
|
||||||
|
assert(NOASSERT_UNIMPLEMENTED); \
|
||||||
|
} ANGLE_EMPTY_STATEMENT
|
||||||
|
#else
|
||||||
|
#define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__)
|
||||||
|
#endif
|
||||||
|
|
||||||
// A macro for code which is not expected to be reached under valid assumptions
|
// A macro for code which is not expected to be reached under valid assumptions
|
||||||
#define UNREACHABLE() \
|
#if !defined(NDEBUG)
|
||||||
(ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__), ASSERT(false))
|
#define UNREACHABLE() { \
|
||||||
|
ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \
|
||||||
|
assert(false); \
|
||||||
|
} ANGLE_EMPTY_STATEMENT
|
||||||
|
#else
|
||||||
|
#define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // COMMON_DEBUG_H_
|
#endif // COMMON_DEBUG_H_
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,6 @@
|
||||||
namespace gl
|
namespace gl
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
struct RGB9E5Data
|
struct RGB9E5Data
|
||||||
{
|
{
|
||||||
unsigned int R : 9;
|
unsigned int R : 9;
|
||||||
|
|
@ -26,20 +23,17 @@ struct RGB9E5Data
|
||||||
};
|
};
|
||||||
|
|
||||||
// B is the exponent bias (15)
|
// B is the exponent bias (15)
|
||||||
constexpr int g_sharedexp_bias = 15;
|
static const int g_sharedexp_bias = 15;
|
||||||
|
|
||||||
// N is the number of mantissa bits per component (9)
|
// N is the number of mantissa bits per component (9)
|
||||||
constexpr int g_sharedexp_mantissabits = 9;
|
static const int g_sharedexp_mantissabits = 9;
|
||||||
|
|
||||||
// Emax is the maximum allowed biased exponent value (31)
|
// Emax is the maximum allowed biased exponent value (31)
|
||||||
constexpr int g_sharedexp_maxexponent = 31;
|
static const int g_sharedexp_maxexponent = 31;
|
||||||
|
|
||||||
constexpr float g_sharedexp_max =
|
static const float g_sharedexp_max = ((pow(2.0f, g_sharedexp_mantissabits) - 1) /
|
||||||
((static_cast<float>(1 << g_sharedexp_mantissabits) - 1) /
|
pow(2.0f, g_sharedexp_mantissabits)) *
|
||||||
static_cast<float>(1 << g_sharedexp_mantissabits)) *
|
pow(2.0f, g_sharedexp_maxexponent - g_sharedexp_bias);
|
||||||
static_cast<float>(1 << (g_sharedexp_maxexponent - g_sharedexp_bias));
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
unsigned int convertRGBFloatsTo999E5(float red, float green, float blue)
|
unsigned int convertRGBFloatsTo999E5(float red, float green, float blue)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -44,15 +44,6 @@ struct Vector4
|
||||||
float w;
|
float w;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vector2
|
|
||||||
{
|
|
||||||
Vector2() {}
|
|
||||||
Vector2(float x, float y) : x(x), y(y) {}
|
|
||||||
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool isPow2(int x)
|
inline bool isPow2(int x)
|
||||||
{
|
{
|
||||||
return (x & (x - 1)) == 0 && (x != 0);
|
return (x & (x - 1)) == 0 && (x != 0);
|
||||||
|
|
@ -765,40 +756,6 @@ constexpr unsigned int iSquareRoot()
|
||||||
return priv::iSquareRoot<N, 1>::value;
|
return priv::iSquareRoot<N, 1>::value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sum, difference and multiplication operations for signed ints that wrap on 32-bit overflow.
|
|
||||||
//
|
|
||||||
// Unsigned types are defined to do arithmetic modulo 2^n in C++. For signed types, overflow
|
|
||||||
// behavior is undefined.
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T WrappingSum(T lhs, T rhs)
|
|
||||||
{
|
|
||||||
uint32_t lhsUnsigned = static_cast<uint32_t>(lhs);
|
|
||||||
uint32_t rhsUnsigned = static_cast<uint32_t>(rhs);
|
|
||||||
return static_cast<T>(lhsUnsigned + rhsUnsigned);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T WrappingDiff(T lhs, T rhs)
|
|
||||||
{
|
|
||||||
uint32_t lhsUnsigned = static_cast<uint32_t>(lhs);
|
|
||||||
uint32_t rhsUnsigned = static_cast<uint32_t>(rhs);
|
|
||||||
return static_cast<T>(lhsUnsigned - rhsUnsigned);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int32_t WrappingMul(int32_t lhs, int32_t rhs)
|
|
||||||
{
|
|
||||||
int64_t lhsWide = static_cast<int64_t>(lhs);
|
|
||||||
int64_t rhsWide = static_cast<int64_t>(rhs);
|
|
||||||
// The multiplication is guaranteed not to overflow.
|
|
||||||
int64_t resultWide = lhsWide * rhsWide;
|
|
||||||
// Implement the desired wrapping behavior by masking out the high-order 32 bits.
|
|
||||||
resultWide = resultWide & 0xffffffffll;
|
|
||||||
// Casting to a narrower signed type is fine since the casted value is representable in the
|
|
||||||
// narrower type.
|
|
||||||
return static_cast<int32_t>(resultWide);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace gl
|
} // namespace gl
|
||||||
|
|
||||||
namespace rx
|
namespace rx
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
// Unfortunately ANGLE relies on ASSERT being an empty statement, which these libs don't respect.
|
// Unfortunately ANGLE relies on ASSERT being an empty statement, which these libs don't respect.
|
||||||
#ifndef NOTREACHED
|
#ifndef NOTREACHED
|
||||||
#define NOTREACHED() UNREACHABLE()
|
#define NOTREACHED() 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // BASE_LOGGING_H_
|
#endif // BASE_LOGGING_H_
|
||||||
|
|
@ -92,7 +92,7 @@ struct StaticDstRangeRelationToSrcRange<Dst,
|
||||||
static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED;
|
static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RangeConstraint : unsigned char
|
enum RangeConstraint
|
||||||
{
|
{
|
||||||
RANGE_VALID = 0x0, // Value can be represented by the destination type.
|
RANGE_VALID = 0x0, // Value can be represented by the destination type.
|
||||||
RANGE_UNDERFLOW = 0x1, // Value would overflow.
|
RANGE_UNDERFLOW = 0x1, // Value would overflow.
|
||||||
|
|
|
||||||
|
|
@ -247,19 +247,7 @@ int VariableRowCount(GLenum type)
|
||||||
case GL_SAMPLER_2D_SHADOW:
|
case GL_SAMPLER_2D_SHADOW:
|
||||||
case GL_SAMPLER_CUBE_SHADOW:
|
case GL_SAMPLER_CUBE_SHADOW:
|
||||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||||
case GL_IMAGE_2D:
|
return 1;
|
||||||
case GL_INT_IMAGE_2D:
|
|
||||||
case GL_UNSIGNED_INT_IMAGE_2D:
|
|
||||||
case GL_IMAGE_2D_ARRAY:
|
|
||||||
case GL_INT_IMAGE_2D_ARRAY:
|
|
||||||
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
|
|
||||||
case GL_IMAGE_3D:
|
|
||||||
case GL_INT_IMAGE_3D:
|
|
||||||
case GL_UNSIGNED_INT_IMAGE_3D:
|
|
||||||
case GL_IMAGE_CUBE:
|
|
||||||
case GL_INT_IMAGE_CUBE:
|
|
||||||
case GL_UNSIGNED_INT_IMAGE_CUBE:
|
|
||||||
return 1;
|
|
||||||
case GL_FLOAT_MAT2:
|
case GL_FLOAT_MAT2:
|
||||||
case GL_FLOAT_MAT3x2:
|
case GL_FLOAT_MAT3x2:
|
||||||
case GL_FLOAT_MAT4x2:
|
case GL_FLOAT_MAT4x2:
|
||||||
|
|
@ -656,29 +644,6 @@ std::string ParseUniformName(const std::string &name, size_t *outSubscript)
|
||||||
return name.substr(0, open);
|
return name.substr(0, open);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
GLuint ConvertToGLuint(GLfloat param)
|
|
||||||
{
|
|
||||||
return uiround<GLuint>(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
GLint ConvertToGLint(GLfloat param)
|
|
||||||
{
|
|
||||||
return iround<GLint>(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
GLint ConvertFromGLfloat(GLfloat param)
|
|
||||||
{
|
|
||||||
return iround<GLint>(param);
|
|
||||||
}
|
|
||||||
template <>
|
|
||||||
GLuint ConvertFromGLfloat(GLfloat param)
|
|
||||||
{
|
|
||||||
return uiround<GLuint>(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int ParseAndStripArrayIndex(std::string *name)
|
unsigned int ParseAndStripArrayIndex(std::string *name)
|
||||||
{
|
{
|
||||||
unsigned int subscript = GL_INVALID_INDEX;
|
unsigned int subscript = GL_INVALID_INDEX;
|
||||||
|
|
|
||||||
|
|
@ -68,76 +68,6 @@ bool IsTriangleMode(GLenum drawMode);
|
||||||
template <typename outT> outT iround(GLfloat value) { return static_cast<outT>(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); }
|
template <typename outT> outT iround(GLfloat value) { return static_cast<outT>(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); }
|
||||||
template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(value + 0.5f); }
|
template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(value + 0.5f); }
|
||||||
|
|
||||||
// Helper for converting arbitrary GL types to other GL types used in queries and state setting
|
|
||||||
template <typename ParamType>
|
|
||||||
GLuint ConvertToGLuint(ParamType param)
|
|
||||||
{
|
|
||||||
return static_cast<GLuint>(param);
|
|
||||||
}
|
|
||||||
template <>
|
|
||||||
GLuint ConvertToGLuint(GLfloat param);
|
|
||||||
|
|
||||||
template <typename ParamType>
|
|
||||||
GLint ConvertToGLint(ParamType param)
|
|
||||||
{
|
|
||||||
return static_cast<GLint>(param);
|
|
||||||
}
|
|
||||||
template <>
|
|
||||||
GLint ConvertToGLint(GLfloat param);
|
|
||||||
|
|
||||||
// Same conversion as uint
|
|
||||||
template <typename ParamType>
|
|
||||||
GLenum ConvertToGLenum(ParamType param)
|
|
||||||
{
|
|
||||||
return static_cast<GLenum>(ConvertToGLuint(param));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParamType>
|
|
||||||
GLfloat ConvertToGLfloat(ParamType param)
|
|
||||||
{
|
|
||||||
return static_cast<GLfloat>(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParamType>
|
|
||||||
ParamType ConvertFromGLfloat(GLfloat param)
|
|
||||||
{
|
|
||||||
return static_cast<ParamType>(param);
|
|
||||||
}
|
|
||||||
template <>
|
|
||||||
GLint ConvertFromGLfloat(GLfloat param);
|
|
||||||
template <>
|
|
||||||
GLuint ConvertFromGLfloat(GLfloat param);
|
|
||||||
|
|
||||||
template <typename ParamType>
|
|
||||||
ParamType ConvertFromGLenum(GLenum param)
|
|
||||||
{
|
|
||||||
return static_cast<ParamType>(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParamType>
|
|
||||||
ParamType ConvertFromGLuint(GLuint param)
|
|
||||||
{
|
|
||||||
return static_cast<ParamType>(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParamType>
|
|
||||||
ParamType ConvertFromGLint(GLint param)
|
|
||||||
{
|
|
||||||
return static_cast<ParamType>(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParamType>
|
|
||||||
ParamType ConvertFromGLboolean(GLboolean param)
|
|
||||||
{
|
|
||||||
return static_cast<ParamType>(param ? GL_TRUE : GL_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParamType>
|
|
||||||
ParamType ConvertFromGLint64(GLint64 param)
|
|
||||||
{
|
|
||||||
return clampCast<ParamType>(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int ParseAndStripArrayIndex(std::string *name);
|
unsigned int ParseAndStripArrayIndex(std::string *name);
|
||||||
|
|
||||||
} // namespace gl
|
} // namespace gl
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
'variables':
|
'variables':
|
||||||
{
|
{
|
||||||
# These file lists are shared with the GN build.
|
# These file lists are shared with the GN build.
|
||||||
'angle_translator_sources':
|
'angle_translator_lib_sources':
|
||||||
[
|
[
|
||||||
'../include/EGL/egl.h',
|
'../include/EGL/egl.h',
|
||||||
'../include/EGL/eglext.h',
|
'../include/EGL/eglext.h',
|
||||||
|
|
@ -22,13 +22,9 @@
|
||||||
'../include/GLSLANG/ShaderVars.h',
|
'../include/GLSLANG/ShaderVars.h',
|
||||||
'../include/KHR/khrplatform.h',
|
'../include/KHR/khrplatform.h',
|
||||||
'../include/angle_gl.h',
|
'../include/angle_gl.h',
|
||||||
'compiler/translator/AddAndTrueToLoopCondition.cpp',
|
|
||||||
'compiler/translator/AddAndTrueToLoopCondition.h',
|
|
||||||
'compiler/translator/BaseTypes.h',
|
'compiler/translator/BaseTypes.h',
|
||||||
'compiler/translator/BuiltInFunctionEmulator.cpp',
|
'compiler/translator/BuiltInFunctionEmulator.cpp',
|
||||||
'compiler/translator/BuiltInFunctionEmulator.h',
|
'compiler/translator/BuiltInFunctionEmulator.h',
|
||||||
'compiler/translator/BreakVariableAliasingInInnerLoops.cpp',
|
|
||||||
'compiler/translator/BreakVariableAliasingInInnerLoops.h',
|
|
||||||
'compiler/translator/Cache.cpp',
|
'compiler/translator/Cache.cpp',
|
||||||
'compiler/translator/Cache.h',
|
'compiler/translator/Cache.h',
|
||||||
'compiler/translator/CallDAG.cpp',
|
'compiler/translator/CallDAG.cpp',
|
||||||
|
|
@ -37,7 +33,6 @@
|
||||||
'compiler/translator/Common.h',
|
'compiler/translator/Common.h',
|
||||||
'compiler/translator/Compiler.cpp',
|
'compiler/translator/Compiler.cpp',
|
||||||
'compiler/translator/Compiler.h',
|
'compiler/translator/Compiler.h',
|
||||||
'compiler/translator/ConstantUnion.cpp',
|
|
||||||
'compiler/translator/ConstantUnion.h',
|
'compiler/translator/ConstantUnion.h',
|
||||||
'compiler/translator/DeferGlobalInitializers.cpp',
|
'compiler/translator/DeferGlobalInitializers.cpp',
|
||||||
'compiler/translator/DeferGlobalInitializers.h',
|
'compiler/translator/DeferGlobalInitializers.h',
|
||||||
|
|
@ -86,36 +81,27 @@
|
||||||
'compiler/translator/Pragma.h',
|
'compiler/translator/Pragma.h',
|
||||||
'compiler/translator/PruneEmptyDeclarations.cpp',
|
'compiler/translator/PruneEmptyDeclarations.cpp',
|
||||||
'compiler/translator/PruneEmptyDeclarations.h',
|
'compiler/translator/PruneEmptyDeclarations.h',
|
||||||
'compiler/translator/QualifierTypes.h',
|
|
||||||
'compiler/translator/QualifierTypes.cpp',
|
|
||||||
'compiler/translator/RecordConstantPrecision.cpp',
|
'compiler/translator/RecordConstantPrecision.cpp',
|
||||||
'compiler/translator/RecordConstantPrecision.h',
|
'compiler/translator/RecordConstantPrecision.h',
|
||||||
'compiler/translator/RegenerateStructNames.cpp',
|
'compiler/translator/RegenerateStructNames.cpp',
|
||||||
'compiler/translator/RegenerateStructNames.h',
|
'compiler/translator/RegenerateStructNames.h',
|
||||||
'compiler/translator/RemoveInvariantDeclaration.cpp',
|
|
||||||
'compiler/translator/RemoveInvariantDeclaration.h',
|
|
||||||
'compiler/translator/RemovePow.cpp',
|
'compiler/translator/RemovePow.cpp',
|
||||||
'compiler/translator/RemovePow.h',
|
'compiler/translator/RemovePow.h',
|
||||||
'compiler/translator/RewriteDoWhile.cpp',
|
'compiler/translator/RewriteDoWhile.cpp',
|
||||||
'compiler/translator/RewriteDoWhile.h',
|
'compiler/translator/RewriteDoWhile.h',
|
||||||
'compiler/translator/RewriteTexelFetchOffset.cpp',
|
'compiler/translator/RewriteTexelFetchOffset.cpp',
|
||||||
'compiler/translator/RewriteTexelFetchOffset.h',
|
'compiler/translator/RewriteTexelFetchOffset.h',
|
||||||
'compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
|
'compiler/translator/RenameFunction.h',
|
||||||
'compiler/translator/RewriteUnaryMinusOperatorInt.h',
|
|
||||||
'compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
|
'compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
|
||||||
'compiler/translator/ScalarizeVecAndMatConstructorArgs.h',
|
'compiler/translator/ScalarizeVecAndMatConstructorArgs.h',
|
||||||
'compiler/translator/SearchSymbol.cpp',
|
'compiler/translator/SearchSymbol.cpp',
|
||||||
'compiler/translator/SearchSymbol.h',
|
'compiler/translator/SearchSymbol.h',
|
||||||
'compiler/translator/ShaderLang.cpp',
|
|
||||||
'compiler/translator/ShaderVars.cpp',
|
|
||||||
'compiler/translator/SymbolTable.cpp',
|
'compiler/translator/SymbolTable.cpp',
|
||||||
'compiler/translator/SymbolTable.h',
|
'compiler/translator/SymbolTable.h',
|
||||||
'compiler/translator/Types.cpp',
|
'compiler/translator/Types.cpp',
|
||||||
'compiler/translator/Types.h',
|
'compiler/translator/Types.h',
|
||||||
'compiler/translator/UnfoldShortCircuitAST.cpp',
|
'compiler/translator/UnfoldShortCircuitAST.cpp',
|
||||||
'compiler/translator/UnfoldShortCircuitAST.h',
|
'compiler/translator/UnfoldShortCircuitAST.h',
|
||||||
'compiler/translator/UseInterfaceBlockFields.cpp',
|
|
||||||
'compiler/translator/UseInterfaceBlockFields.h',
|
|
||||||
'compiler/translator/ValidateGlobalInitializer.cpp',
|
'compiler/translator/ValidateGlobalInitializer.cpp',
|
||||||
'compiler/translator/ValidateGlobalInitializer.h',
|
'compiler/translator/ValidateGlobalInitializer.h',
|
||||||
'compiler/translator/ValidateLimitations.cpp',
|
'compiler/translator/ValidateLimitations.cpp',
|
||||||
|
|
@ -132,6 +118,13 @@
|
||||||
'compiler/translator/VariablePacker.h',
|
'compiler/translator/VariablePacker.h',
|
||||||
'compiler/translator/blocklayout.cpp',
|
'compiler/translator/blocklayout.cpp',
|
||||||
'compiler/translator/blocklayout.h',
|
'compiler/translator/blocklayout.h',
|
||||||
|
'compiler/translator/depgraph/DependencyGraph.cpp',
|
||||||
|
'compiler/translator/depgraph/DependencyGraph.h',
|
||||||
|
'compiler/translator/depgraph/DependencyGraphBuilder.cpp',
|
||||||
|
'compiler/translator/depgraph/DependencyGraphBuilder.h',
|
||||||
|
'compiler/translator/depgraph/DependencyGraphOutput.cpp',
|
||||||
|
'compiler/translator/depgraph/DependencyGraphOutput.h',
|
||||||
|
'compiler/translator/depgraph/DependencyGraphTraverse.cpp',
|
||||||
'compiler/translator/glslang.h',
|
'compiler/translator/glslang.h',
|
||||||
'compiler/translator/glslang.l',
|
'compiler/translator/glslang.l',
|
||||||
'compiler/translator/glslang.y',
|
'compiler/translator/glslang.y',
|
||||||
|
|
@ -140,19 +133,23 @@
|
||||||
'compiler/translator/glslang_tab.h',
|
'compiler/translator/glslang_tab.h',
|
||||||
'compiler/translator/intermOut.cpp',
|
'compiler/translator/intermOut.cpp',
|
||||||
'compiler/translator/length_limits.h',
|
'compiler/translator/length_limits.h',
|
||||||
|
'compiler/translator/timing/RestrictFragmentShaderTiming.cpp',
|
||||||
|
'compiler/translator/timing/RestrictFragmentShaderTiming.h',
|
||||||
|
'compiler/translator/timing/RestrictVertexShaderTiming.cpp',
|
||||||
|
'compiler/translator/timing/RestrictVertexShaderTiming.h',
|
||||||
'compiler/translator/util.cpp',
|
'compiler/translator/util.cpp',
|
||||||
'compiler/translator/util.h',
|
'compiler/translator/util.h',
|
||||||
'third_party/compiler/ArrayBoundsClamper.cpp',
|
'third_party/compiler/ArrayBoundsClamper.cpp',
|
||||||
'third_party/compiler/ArrayBoundsClamper.h',
|
'third_party/compiler/ArrayBoundsClamper.h',
|
||||||
],
|
],
|
||||||
'angle_translator_essl_sources':
|
'angle_translator_lib_essl_sources':
|
||||||
[
|
[
|
||||||
'compiler/translator/OutputESSL.cpp',
|
'compiler/translator/OutputESSL.cpp',
|
||||||
'compiler/translator/OutputESSL.h',
|
'compiler/translator/OutputESSL.h',
|
||||||
'compiler/translator/TranslatorESSL.cpp',
|
'compiler/translator/TranslatorESSL.cpp',
|
||||||
'compiler/translator/TranslatorESSL.h',
|
'compiler/translator/TranslatorESSL.h',
|
||||||
],
|
],
|
||||||
'angle_translator_glsl_sources':
|
'angle_translator_lib_glsl_sources':
|
||||||
[
|
[
|
||||||
'compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
|
'compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
|
||||||
'compiler/translator/BuiltInFunctionEmulatorGLSL.h',
|
'compiler/translator/BuiltInFunctionEmulatorGLSL.h',
|
||||||
|
|
@ -167,7 +164,7 @@
|
||||||
'compiler/translator/VersionGLSL.cpp',
|
'compiler/translator/VersionGLSL.cpp',
|
||||||
'compiler/translator/VersionGLSL.h',
|
'compiler/translator/VersionGLSL.h',
|
||||||
],
|
],
|
||||||
'angle_translator_hlsl_sources':
|
'angle_translator_lib_hlsl_sources':
|
||||||
[
|
[
|
||||||
'compiler/translator/AddDefaultReturnStatements.cpp',
|
'compiler/translator/AddDefaultReturnStatements.cpp',
|
||||||
'compiler/translator/AddDefaultReturnStatements.h',
|
'compiler/translator/AddDefaultReturnStatements.h',
|
||||||
|
|
@ -240,6 +237,7 @@
|
||||||
'compiler/preprocessor/Tokenizer.h',
|
'compiler/preprocessor/Tokenizer.h',
|
||||||
'compiler/preprocessor/Tokenizer.l',
|
'compiler/preprocessor/Tokenizer.l',
|
||||||
'compiler/preprocessor/numeric_lex.h',
|
'compiler/preprocessor/numeric_lex.h',
|
||||||
|
'compiler/preprocessor/pp_utils.h',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
# Everything below this is duplicated in the GN build. If you change
|
# Everything below this is duplicated in the GN build. If you change
|
||||||
|
|
@ -249,23 +247,28 @@
|
||||||
{
|
{
|
||||||
'target_name': 'preprocessor',
|
'target_name': 'preprocessor',
|
||||||
'type': 'static_library',
|
'type': 'static_library',
|
||||||
'dependencies': [ 'angle_common' ],
|
'includes': [ '../build/common_defines.gypi', ],
|
||||||
'includes': [ '../gyp/common_defines.gypi', ],
|
|
||||||
'sources': [ '<@(angle_preprocessor_sources)', ],
|
'sources': [ '<@(angle_preprocessor_sources)', ],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'target_name': 'translator',
|
'target_name': 'translator_lib',
|
||||||
'type': 'static_library',
|
'type': 'static_library',
|
||||||
'dependencies': [ 'preprocessor', 'angle_common' ],
|
'dependencies': [ 'preprocessor', 'angle_common' ],
|
||||||
'includes': [ '../gyp/common_defines.gypi', ],
|
'includes': [ '../build/common_defines.gypi', ],
|
||||||
'include_dirs':
|
'include_dirs':
|
||||||
[
|
[
|
||||||
'.',
|
'.',
|
||||||
'../include',
|
'../include',
|
||||||
],
|
],
|
||||||
|
'defines':
|
||||||
|
[
|
||||||
|
# define the static translator to indicate exported
|
||||||
|
# classes are (in fact) locally defined
|
||||||
|
'ANGLE_TRANSLATOR_STATIC',
|
||||||
|
],
|
||||||
'sources':
|
'sources':
|
||||||
[
|
[
|
||||||
'<@(angle_translator_sources)',
|
'<@(angle_translator_lib_sources)',
|
||||||
],
|
],
|
||||||
'msvs_settings':
|
'msvs_settings':
|
||||||
{
|
{
|
||||||
|
|
@ -291,7 +294,7 @@
|
||||||
},
|
},
|
||||||
'sources':
|
'sources':
|
||||||
[
|
[
|
||||||
'<@(angle_translator_essl_sources)',
|
'<@(angle_translator_lib_essl_sources)',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
['angle_enable_glsl==1',
|
['angle_enable_glsl==1',
|
||||||
|
|
@ -309,7 +312,7 @@
|
||||||
},
|
},
|
||||||
'sources':
|
'sources':
|
||||||
[
|
[
|
||||||
'<@(angle_translator_glsl_sources)',
|
'<@(angle_translator_lib_glsl_sources)',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
['angle_enable_hlsl==1',
|
['angle_enable_hlsl==1',
|
||||||
|
|
@ -327,10 +330,59 @@
|
||||||
},
|
},
|
||||||
'sources':
|
'sources':
|
||||||
[
|
[
|
||||||
'<@(angle_translator_hlsl_sources)',
|
'<@(angle_translator_lib_hlsl_sources)',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
'target_name': 'translator',
|
||||||
|
'type': '<(component)',
|
||||||
|
'dependencies': [ 'translator_lib', 'angle_common' ],
|
||||||
|
'includes': [ '../build/common_defines.gypi', ],
|
||||||
|
'include_dirs':
|
||||||
|
[
|
||||||
|
'.',
|
||||||
|
'../include',
|
||||||
|
],
|
||||||
|
'defines':
|
||||||
|
[
|
||||||
|
'ANGLE_TRANSLATOR_IMPLEMENTATION',
|
||||||
|
],
|
||||||
|
'sources':
|
||||||
|
[
|
||||||
|
'compiler/translator/ShaderLang.cpp',
|
||||||
|
'compiler/translator/ShaderVars.cpp'
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
'target_name': 'translator_static',
|
||||||
|
'type': 'static_library',
|
||||||
|
'dependencies': [ 'translator_lib' ],
|
||||||
|
'includes': [ '../build/common_defines.gypi', ],
|
||||||
|
'include_dirs':
|
||||||
|
[
|
||||||
|
'.',
|
||||||
|
'../include',
|
||||||
|
],
|
||||||
|
'defines':
|
||||||
|
[
|
||||||
|
'ANGLE_TRANSLATOR_STATIC',
|
||||||
|
],
|
||||||
|
'direct_dependent_settings':
|
||||||
|
{
|
||||||
|
'defines':
|
||||||
|
[
|
||||||
|
'ANGLE_TRANSLATOR_STATIC',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'sources':
|
||||||
|
[
|
||||||
|
'compiler/translator/ShaderLang.cpp',
|
||||||
|
'compiler/translator/ShaderVars.cpp'
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,161 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2016 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.
|
|
||||||
//
|
|
||||||
|
|
||||||
// translator_fuzzer.cpp: A libfuzzer fuzzer for the shader translator.
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "compiler/translator/Compiler.h"
|
|
||||||
#include "angle_gl.h"
|
|
||||||
|
|
||||||
using namespace sh;
|
|
||||||
|
|
||||||
struct TranslatorCacheKey
|
|
||||||
{
|
|
||||||
bool operator==(const TranslatorCacheKey &other) const
|
|
||||||
{
|
|
||||||
return type == other.type && spec == other.spec && output == other.output;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t type = 0;
|
|
||||||
uint32_t spec = 0;
|
|
||||||
uint32_t output = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct hash<TranslatorCacheKey>
|
|
||||||
{
|
|
||||||
std::size_t operator()(const TranslatorCacheKey &k) const
|
|
||||||
{
|
|
||||||
return (hash<uint32_t>()(k.type) << 1) ^ (hash<uint32_t>()(k.spec) >> 1) ^
|
|
||||||
hash<uint32_t>()(k.output);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
static std::unordered_map<TranslatorCacheKey, TCompiler *> translators;
|
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
|
||||||
{
|
|
||||||
// Reserve some size for future compile options
|
|
||||||
const size_t kHeaderSize = 128;
|
|
||||||
|
|
||||||
if (size <= kHeaderSize)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the rest of data will be a valid C string so that we don't have to copy it.
|
|
||||||
if (data[size - 1] != 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t type = *reinterpret_cast<const uint32_t *>(data);
|
|
||||||
uint32_t spec = *reinterpret_cast<const uint32_t *>(data + 4);
|
|
||||||
uint32_t output = *reinterpret_cast<const uint32_t *>(data + 8);
|
|
||||||
uint64_t options = *reinterpret_cast<const uint64_t *>(data + 12);
|
|
||||||
|
|
||||||
if (type != GL_FRAGMENT_SHADER && type != GL_VERTEX_SHADER)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spec != SH_GLES2_SPEC && type != SH_WEBGL_SPEC && spec != SH_GLES3_SPEC &&
|
|
||||||
spec != SH_WEBGL2_SPEC)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint32_t> validOutputs;
|
|
||||||
validOutputs.push_back(SH_ESSL_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_COMPATIBILITY_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_130_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_140_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_150_CORE_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_330_CORE_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_400_CORE_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_410_CORE_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_420_CORE_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_430_CORE_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_440_CORE_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_GLSL_450_CORE_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_HLSL_3_0_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_HLSL_4_1_OUTPUT);
|
|
||||||
validOutputs.push_back(SH_HLSL_4_0_FL9_3_OUTPUT);
|
|
||||||
bool found = false;
|
|
||||||
for (auto valid : validOutputs)
|
|
||||||
{
|
|
||||||
found = found || (valid == output);
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size -= kHeaderSize;
|
|
||||||
data += kHeaderSize;
|
|
||||||
|
|
||||||
if (!ShInitialize())
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TranslatorCacheKey key;
|
|
||||||
key.type = type;
|
|
||||||
key.spec = spec;
|
|
||||||
key.output = output;
|
|
||||||
|
|
||||||
if (translators.find(key) == translators.end())
|
|
||||||
{
|
|
||||||
TCompiler *translator = ConstructCompiler(type, static_cast<ShShaderSpec>(spec),
|
|
||||||
static_cast<ShShaderOutput>(output));
|
|
||||||
|
|
||||||
if (!translator)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShBuiltInResources resources;
|
|
||||||
ShInitBuiltInResources(&resources);
|
|
||||||
|
|
||||||
// Enable all the extensions to have more coverage
|
|
||||||
resources.OES_standard_derivatives = 1;
|
|
||||||
resources.OES_EGL_image_external = 1;
|
|
||||||
resources.OES_EGL_image_external_essl3 = 1;
|
|
||||||
resources.NV_EGL_stream_consumer_external = 1;
|
|
||||||
resources.ARB_texture_rectangle = 1;
|
|
||||||
resources.EXT_blend_func_extended = 1;
|
|
||||||
resources.EXT_draw_buffers = 1;
|
|
||||||
resources.EXT_frag_depth = 1;
|
|
||||||
resources.EXT_shader_texture_lod = 1;
|
|
||||||
resources.WEBGL_debug_shader_precision = 1;
|
|
||||||
resources.EXT_shader_framebuffer_fetch = 1;
|
|
||||||
resources.NV_shader_framebuffer_fetch = 1;
|
|
||||||
resources.ARM_shader_framebuffer_fetch = 1;
|
|
||||||
|
|
||||||
if (!translator->Init(resources))
|
|
||||||
{
|
|
||||||
DeleteCompiler(translator);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
translators[key] = translator;
|
|
||||||
}
|
|
||||||
|
|
||||||
TCompiler *translator = translators[key];
|
|
||||||
|
|
||||||
const char *shaderStrings[] = {reinterpret_cast<const char *>(data)};
|
|
||||||
translator->compile(shaderStrings, 1, options);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,79 +1,31 @@
|
||||||
diff --git a/src/compiler/preprocessor/Tokenizer.cpp b/src/compiler/preprocessor/Tokenizer.cpp
|
|
||||||
index 0d7ad58..5ef0e5e 100644
|
|
||||||
--- a/src/compiler/preprocessor/Tokenizer.cpp
|
--- a/src/compiler/preprocessor/Tokenizer.cpp
|
||||||
+++ b/src/compiler/preprocessor/Tokenizer.cpp
|
+++ b/src/compiler/preprocessor/Tokenizer.cpp
|
||||||
@@ -1703,7 +1703,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
@@ -56,6 +56,7 @@ typedef int16_t flex_int16_t;
|
||||||
else
|
typedef uint16_t flex_uint16_t;
|
||||||
{
|
typedef int32_t flex_int32_t;
|
||||||
int num_to_read =
|
typedef uint32_t flex_uint32_t;
|
||||||
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
|
+typedef uint64_t flex_uint64_t;
|
||||||
+ static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1);
|
#else
|
||||||
|
typedef signed char flex_int8_t;
|
||||||
while ( num_to_read <= 0 )
|
typedef short int flex_int16_t;
|
||||||
{ /* Not enough room in the buffer - grow it. */
|
@@ -179,6 +180,11 @@ typedef void* yyscan_t;
|
||||||
@@ -1737,8 +1737,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||||
|
#endif
|
||||||
yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
|
|
||||||
|
+#ifndef YY_TYPEDEF_YY_SIZE_T
|
||||||
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
|
+#define YY_TYPEDEF_YY_SIZE_T
|
||||||
- number_to_move - 1;
|
+typedef size_t yy_size_t;
|
||||||
+ num_to_read = static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
|
+#endif
|
||||||
+ number_to_move - 1);
|
+
|
||||||
|
#define EOB_ACT_CONTINUE_SCAN 0
|
||||||
}
|
#define EOB_ACT_END_OF_FILE 1
|
||||||
|
#define EOB_ACT_LAST_MATCH 2
|
||||||
@@ -1746,8 +1746,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
@@ -353,7 +354,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
|
||||||
num_to_read = YY_READ_BUF_SIZE;
|
|
||||||
|
|
||||||
/* Read in more data. */
|
|
||||||
+ yy_size_t ret = 0;
|
|
||||||
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
|
|
||||||
- yyg->yy_n_chars, num_to_read );
|
|
||||||
+ ret, num_to_read );
|
|
||||||
+ yyg->yy_n_chars = static_cast<int>(ret);
|
|
||||||
|
|
||||||
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
|
|
||||||
}
|
|
||||||
@@ -1773,13 +1775,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
|
||||||
|
|
||||||
if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
|
|
||||||
/* Extend the array by 50%, plus the number we really need. */
|
|
||||||
- int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
|
|
||||||
+ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
|
|
||||||
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
|
|
||||||
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
|
|
||||||
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
|
|
||||||
}
|
|
||||||
|
|
||||||
- yyg->yy_n_chars += number_to_move;
|
|
||||||
+ yyg->yy_n_chars += static_cast<int>(number_to_move);
|
|
||||||
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
|
|
||||||
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
|
|
||||||
|
|
||||||
@@ -2171,7 +2173,7 @@ void pppop_buffer_state (yyscan_t yyscanner)
|
|
||||||
*/
|
*/
|
||||||
static void ppensure_buffer_stack (yyscan_t yyscanner)
|
#define YY_DO_BEFORE_ACTION \
|
||||||
{
|
yyg->yytext_ptr = yy_bp; \
|
||||||
- int num_to_alloc;
|
- yyleng = (size_t) (yy_cp - yy_bp); \
|
||||||
+ yy_size_t num_to_alloc;
|
+ yyleng = (yy_size_t) (yy_cp - yy_bp); \
|
||||||
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
|
yyg->yy_hold_char = *yy_cp; \
|
||||||
|
*yy_cp = '\0'; \
|
||||||
if (!yyg->yy_buffer_stack) {
|
yyg->yy_c_buf_p = yy_cp;
|
||||||
@@ -2238,7 +2240,7 @@ YY_BUFFER_STATE pp_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann
|
|
||||||
if ( ! b )
|
|
||||||
YY_FATAL_ERROR( "out of dynamic memory in pp_scan_buffer()" );
|
|
||||||
|
|
||||||
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
|
|
||||||
+ b->yy_buf_size = static_cast<int>(size - 2); /* "- 2" to take care of EOB's */
|
|
||||||
b->yy_buf_pos = b->yy_ch_buf = base;
|
|
||||||
b->yy_is_our_buffer = 0;
|
|
||||||
b->yy_input_file = NULL;
|
|
||||||
@@ -2293,7 +2295,7 @@ YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, int _yybytes_len , yysc
|
|
||||||
if ( ! buf )
|
|
||||||
YY_FATAL_ERROR( "out of dynamic memory in pp_scan_bytes()" );
|
|
||||||
|
|
||||||
- for ( i = 0; i < _yybytes_len; ++i )
|
|
||||||
+ for ( i = 0; i < static_cast<yy_size_t>(_yybytes_len); ++i )
|
|
||||||
buf[i] = yybytes[i];
|
|
||||||
|
|
||||||
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
|
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
#include "DiagnosticsBase.h"
|
||||||
|
|
||||||
#include "common/debug.h"
|
#include <cassert>
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
@ -31,7 +31,7 @@ Diagnostics::Severity Diagnostics::severity(ID id)
|
||||||
if ((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END))
|
if ((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END))
|
||||||
return PP_WARNING;
|
return PP_WARNING;
|
||||||
|
|
||||||
UNREACHABLE();
|
assert(false);
|
||||||
return PP_ERROR;
|
return PP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,8 +74,6 @@ std::string Diagnostics::message(ID id)
|
||||||
return "predefined macro undefined";
|
return "predefined macro undefined";
|
||||||
case PP_MACRO_UNTERMINATED_INVOCATION:
|
case PP_MACRO_UNTERMINATED_INVOCATION:
|
||||||
return "unterminated macro invocation";
|
return "unterminated macro invocation";
|
||||||
case PP_MACRO_UNDEFINED_WHILE_INVOKED:
|
|
||||||
return "macro undefined while being invoked";
|
|
||||||
case PP_MACRO_TOO_FEW_ARGS:
|
case PP_MACRO_TOO_FEW_ARGS:
|
||||||
return "Not enough arguments for macro";
|
return "Not enough arguments for macro";
|
||||||
case PP_MACRO_TOO_MANY_ARGS:
|
case PP_MACRO_TOO_MANY_ARGS:
|
||||||
|
|
@ -133,8 +131,8 @@ std::string Diagnostics::message(ID id)
|
||||||
return "macro name with a double underscore is reserved - unintented behavior is possible";
|
return "macro name with a double underscore is reserved - unintented behavior is possible";
|
||||||
// Warnings end.
|
// Warnings end.
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
assert(false);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ class Diagnostics
|
||||||
PP_MACRO_PREDEFINED_REDEFINED,
|
PP_MACRO_PREDEFINED_REDEFINED,
|
||||||
PP_MACRO_PREDEFINED_UNDEFINED,
|
PP_MACRO_PREDEFINED_UNDEFINED,
|
||||||
PP_MACRO_UNTERMINATED_INVOCATION,
|
PP_MACRO_UNTERMINATED_INVOCATION,
|
||||||
PP_MACRO_UNDEFINED_WHILE_INVOKED,
|
|
||||||
PP_MACRO_TOO_FEW_ARGS,
|
PP_MACRO_TOO_FEW_ARGS,
|
||||||
PP_MACRO_TOO_MANY_ARGS,
|
PP_MACRO_TOO_MANY_ARGS,
|
||||||
PP_MACRO_DUPLICATE_PARAMETER_NAMES,
|
PP_MACRO_DUPLICATE_PARAMETER_NAMES,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "compiler/preprocessor/DirectiveHandlerBase.h"
|
#include "DirectiveHandlerBase.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,19 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "compiler/preprocessor/DirectiveParser.h"
|
#include "DirectiveParser.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "common/debug.h"
|
#include "DiagnosticsBase.h"
|
||||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
#include "DirectiveHandlerBase.h"
|
||||||
#include "compiler/preprocessor/DirectiveHandlerBase.h"
|
#include "ExpressionParser.h"
|
||||||
#include "compiler/preprocessor/ExpressionParser.h"
|
#include "MacroExpander.h"
|
||||||
#include "compiler/preprocessor/MacroExpander.h"
|
#include "Token.h"
|
||||||
#include "compiler/preprocessor/Token.h"
|
#include "Tokenizer.h"
|
||||||
#include "compiler/preprocessor/Tokenizer.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
enum DirectiveType
|
enum DirectiveType
|
||||||
|
|
@ -248,7 +248,7 @@ void DirectiveParser::lex(Token *token)
|
||||||
|
|
||||||
void DirectiveParser::parseDirective(Token *token)
|
void DirectiveParser::parseDirective(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(token->type == Token::PP_HASH);
|
assert(token->type == Token::PP_HASH);
|
||||||
|
|
||||||
mTokenizer->lex(token);
|
mTokenizer->lex(token);
|
||||||
if (isEOD(token))
|
if (isEOD(token))
|
||||||
|
|
@ -314,8 +314,8 @@ void DirectiveParser::parseDirective(Token *token)
|
||||||
parseLine(token);
|
parseLine(token);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
assert(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
skipUntilEOD(mTokenizer, token);
|
skipUntilEOD(mTokenizer, token);
|
||||||
|
|
@ -328,7 +328,7 @@ void DirectiveParser::parseDirective(Token *token)
|
||||||
|
|
||||||
void DirectiveParser::parseDefine(Token *token)
|
void DirectiveParser::parseDefine(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_DEFINE);
|
assert(getDirective(token) == DIRECTIVE_DEFINE);
|
||||||
|
|
||||||
mTokenizer->lex(token);
|
mTokenizer->lex(token);
|
||||||
if (token->type != Token::IDENTIFIER)
|
if (token->type != Token::IDENTIFIER)
|
||||||
|
|
@ -428,7 +428,7 @@ void DirectiveParser::parseDefine(Token *token)
|
||||||
|
|
||||||
void DirectiveParser::parseUndef(Token *token)
|
void DirectiveParser::parseUndef(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_UNDEF);
|
assert(getDirective(token) == DIRECTIVE_UNDEF);
|
||||||
|
|
||||||
mTokenizer->lex(token);
|
mTokenizer->lex(token);
|
||||||
if (token->type != Token::IDENTIFIER)
|
if (token->type != Token::IDENTIFIER)
|
||||||
|
|
@ -445,13 +445,6 @@ void DirectiveParser::parseUndef(Token *token)
|
||||||
{
|
{
|
||||||
mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,
|
mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,
|
||||||
token->location, token->text);
|
token->location, token->text);
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (iter->second.expansionCount > 0)
|
|
||||||
{
|
|
||||||
mDiagnostics->report(Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED, token->location,
|
|
||||||
token->text);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -470,25 +463,25 @@ void DirectiveParser::parseUndef(Token *token)
|
||||||
|
|
||||||
void DirectiveParser::parseIf(Token *token)
|
void DirectiveParser::parseIf(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_IF);
|
assert(getDirective(token) == DIRECTIVE_IF);
|
||||||
parseConditionalIf(token);
|
parseConditionalIf(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectiveParser::parseIfdef(Token *token)
|
void DirectiveParser::parseIfdef(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_IFDEF);
|
assert(getDirective(token) == DIRECTIVE_IFDEF);
|
||||||
parseConditionalIf(token);
|
parseConditionalIf(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectiveParser::parseIfndef(Token *token)
|
void DirectiveParser::parseIfndef(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_IFNDEF);
|
assert(getDirective(token) == DIRECTIVE_IFNDEF);
|
||||||
parseConditionalIf(token);
|
parseConditionalIf(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectiveParser::parseElse(Token *token)
|
void DirectiveParser::parseElse(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_ELSE);
|
assert(getDirective(token) == DIRECTIVE_ELSE);
|
||||||
|
|
||||||
if (mConditionalStack.empty())
|
if (mConditionalStack.empty())
|
||||||
{
|
{
|
||||||
|
|
@ -529,7 +522,7 @@ void DirectiveParser::parseElse(Token *token)
|
||||||
|
|
||||||
void DirectiveParser::parseElif(Token *token)
|
void DirectiveParser::parseElif(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_ELIF);
|
assert(getDirective(token) == DIRECTIVE_ELIF);
|
||||||
|
|
||||||
if (mConditionalStack.empty())
|
if (mConditionalStack.empty())
|
||||||
{
|
{
|
||||||
|
|
@ -569,7 +562,7 @@ void DirectiveParser::parseElif(Token *token)
|
||||||
|
|
||||||
void DirectiveParser::parseEndif(Token *token)
|
void DirectiveParser::parseEndif(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_ENDIF);
|
assert(getDirective(token) == DIRECTIVE_ENDIF);
|
||||||
|
|
||||||
if (mConditionalStack.empty())
|
if (mConditionalStack.empty())
|
||||||
{
|
{
|
||||||
|
|
@ -593,7 +586,7 @@ void DirectiveParser::parseEndif(Token *token)
|
||||||
|
|
||||||
void DirectiveParser::parseError(Token *token)
|
void DirectiveParser::parseError(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_ERROR);
|
assert(getDirective(token) == DIRECTIVE_ERROR);
|
||||||
|
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
mTokenizer->lex(token);
|
mTokenizer->lex(token);
|
||||||
|
|
@ -608,7 +601,7 @@ void DirectiveParser::parseError(Token *token)
|
||||||
// Parses pragma of form: #pragma name[(value)].
|
// Parses pragma of form: #pragma name[(value)].
|
||||||
void DirectiveParser::parsePragma(Token *token)
|
void DirectiveParser::parsePragma(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_PRAGMA);
|
assert(getDirective(token) == DIRECTIVE_PRAGMA);
|
||||||
|
|
||||||
enum State
|
enum State
|
||||||
{
|
{
|
||||||
|
|
@ -669,7 +662,7 @@ void DirectiveParser::parsePragma(Token *token)
|
||||||
|
|
||||||
void DirectiveParser::parseExtension(Token *token)
|
void DirectiveParser::parseExtension(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_EXTENSION);
|
assert(getDirective(token) == DIRECTIVE_EXTENSION);
|
||||||
|
|
||||||
enum State
|
enum State
|
||||||
{
|
{
|
||||||
|
|
@ -750,7 +743,7 @@ void DirectiveParser::parseExtension(Token *token)
|
||||||
|
|
||||||
void DirectiveParser::parseVersion(Token *token)
|
void DirectiveParser::parseVersion(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_VERSION);
|
assert(getDirective(token) == DIRECTIVE_VERSION);
|
||||||
|
|
||||||
if (mPastFirstStatement)
|
if (mPastFirstStatement)
|
||||||
{
|
{
|
||||||
|
|
@ -837,7 +830,7 @@ void DirectiveParser::parseVersion(Token *token)
|
||||||
|
|
||||||
void DirectiveParser::parseLine(Token *token)
|
void DirectiveParser::parseLine(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT(getDirective(token) == DIRECTIVE_LINE);
|
assert(getDirective(token) == DIRECTIVE_LINE);
|
||||||
|
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
bool parsedFileNumber = false;
|
bool parsedFileNumber = false;
|
||||||
|
|
@ -938,8 +931,8 @@ void DirectiveParser::parseConditionalIf(Token *token)
|
||||||
expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
|
expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
assert(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
block.skipGroup = expression == 0;
|
block.skipGroup = expression == 0;
|
||||||
block.foundValidGroup = expression != 0;
|
block.foundValidGroup = expression != 0;
|
||||||
|
|
@ -949,7 +942,8 @@ void DirectiveParser::parseConditionalIf(Token *token)
|
||||||
|
|
||||||
int DirectiveParser::parseExpressionIf(Token *token)
|
int DirectiveParser::parseExpressionIf(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF));
|
assert((getDirective(token) == DIRECTIVE_IF) ||
|
||||||
|
(getDirective(token) == DIRECTIVE_ELIF));
|
||||||
|
|
||||||
DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics);
|
DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics);
|
||||||
MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics);
|
MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics);
|
||||||
|
|
@ -976,7 +970,8 @@ int DirectiveParser::parseExpressionIf(Token *token)
|
||||||
|
|
||||||
int DirectiveParser::parseExpressionIfdef(Token *token)
|
int DirectiveParser::parseExpressionIfdef(Token *token)
|
||||||
{
|
{
|
||||||
ASSERT((getDirective(token) == DIRECTIVE_IFDEF) || (getDirective(token) == DIRECTIVE_IFNDEF));
|
assert((getDirective(token) == DIRECTIVE_IFDEF) ||
|
||||||
|
(getDirective(token) == DIRECTIVE_IFNDEF));
|
||||||
|
|
||||||
mTokenizer->lex(token);
|
mTokenizer->lex(token);
|
||||||
if (token->type != Token::IDENTIFIER)
|
if (token->type != Token::IDENTIFIER)
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,10 @@
|
||||||
#ifndef COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
#ifndef COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
||||||
#define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
#define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
||||||
|
|
||||||
#include "compiler/preprocessor/Lexer.h"
|
#include "Lexer.h"
|
||||||
#include "compiler/preprocessor/Macro.h"
|
#include "Macro.h"
|
||||||
#include "compiler/preprocessor/SourceLocation.h"
|
#include "pp_utils.h"
|
||||||
|
#include "SourceLocation.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
@ -29,6 +30,7 @@ class DirectiveParser : public Lexer
|
||||||
void lex(Token *token) override;
|
void lex(Token *token) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser);
|
||||||
|
|
||||||
void parseDirective(Token *token);
|
void parseDirective(Token *token);
|
||||||
void parseDefine(Token *token);
|
void parseDefine(Token *token);
|
||||||
|
|
|
||||||
|
|
@ -99,15 +99,17 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "DiagnosticsBase.h"
|
#include "DiagnosticsBase.h"
|
||||||
#include "Lexer.h"
|
#include "Lexer.h"
|
||||||
#include "Token.h"
|
#include "Token.h"
|
||||||
#include "common/mathutil.h"
|
|
||||||
|
|
||||||
typedef int32_t YYSTYPE;
|
#if defined(_MSC_VER)
|
||||||
typedef uint32_t UNSIGNED_TYPE;
|
typedef __int64 YYSTYPE;
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef intmax_t YYSTYPE;
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#define YYENABLE_NLS 0
|
#define YYENABLE_NLS 0
|
||||||
#define YYLTYPE_IS_TRIVIAL 1
|
#define YYLTYPE_IS_TRIVIAL 1
|
||||||
|
|
@ -496,12 +498,9 @@ static const yytype_uint8 yytranslate[] =
|
||||||
|
|
||||||
#if YYDEBUG
|
#if YYDEBUG
|
||||||
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
|
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
|
||||||
static const yytype_uint16 yyrline[] =
|
static const yytype_uint16 yyrline[] = {0, 110, 110, 117, 118, 129, 129, 150, 150, 171,
|
||||||
{
|
174, 177, 180, 183, 186, 189, 192, 195, 198, 218,
|
||||||
0, 108, 108, 115, 116, 127, 127, 148, 148, 169,
|
238, 241, 244, 264, 284, 287, 290, 293, 296, 299};
|
||||||
172, 175, 178, 181, 184, 187, 190, 193, 196, 221,
|
|
||||||
246, 249, 252, 278, 305, 308, 311, 314, 326, 329
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if YYDEBUG || YYERROR_VERBOSE || 0
|
#if YYDEBUG || YYERROR_VERBOSE || 0
|
||||||
|
|
@ -1493,7 +1492,7 @@ yyreduce:
|
||||||
case 18:
|
case 18:
|
||||||
|
|
||||||
{
|
{
|
||||||
if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31)
|
if ((yyvsp[0]) < 0)
|
||||||
{
|
{
|
||||||
if (!context->isIgnoringErrors())
|
if (!context->isIgnoringErrors())
|
||||||
{
|
{
|
||||||
|
|
@ -1501,17 +1500,11 @@ yyreduce:
|
||||||
stream << (yyvsp[-2]) << " >> " << (yyvsp[0]);
|
stream << (yyvsp[-2]) << " >> " << (yyvsp[0]);
|
||||||
std::string text = stream.str();
|
std::string text = stream.str();
|
||||||
context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
|
context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
|
||||||
context->token->location,
|
context->token->location, text.c_str());
|
||||||
text.c_str());
|
|
||||||
*(context->valid) = false;
|
*(context->valid) = false;
|
||||||
}
|
}
|
||||||
(yyval) = static_cast<YYSTYPE>(0);
|
(yyval) = static_cast<YYSTYPE>(0);
|
||||||
}
|
}
|
||||||
else if ((yyvsp[-2]) < 0)
|
|
||||||
{
|
|
||||||
// Logical shift right.
|
|
||||||
(yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) >> (yyvsp[0]));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(yyval) = (yyvsp[-2]) >> (yyvsp[0]);
|
(yyval) = (yyvsp[-2]) >> (yyvsp[0]);
|
||||||
|
|
@ -1523,7 +1516,7 @@ yyreduce:
|
||||||
case 19:
|
case 19:
|
||||||
|
|
||||||
{
|
{
|
||||||
if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31)
|
if ((yyvsp[0]) < 0)
|
||||||
{
|
{
|
||||||
if (!context->isIgnoringErrors())
|
if (!context->isIgnoringErrors())
|
||||||
{
|
{
|
||||||
|
|
@ -1531,17 +1524,11 @@ yyreduce:
|
||||||
stream << (yyvsp[-2]) << " << " << (yyvsp[0]);
|
stream << (yyvsp[-2]) << " << " << (yyvsp[0]);
|
||||||
std::string text = stream.str();
|
std::string text = stream.str();
|
||||||
context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
|
context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
|
||||||
context->token->location,
|
context->token->location, text.c_str());
|
||||||
text.c_str());
|
|
||||||
*(context->valid) = false;
|
*(context->valid) = false;
|
||||||
}
|
}
|
||||||
(yyval) = static_cast<YYSTYPE>(0);
|
(yyval) = static_cast<YYSTYPE>(0);
|
||||||
}
|
}
|
||||||
else if ((yyvsp[-2]) < 0)
|
|
||||||
{
|
|
||||||
// Logical shift left.
|
|
||||||
(yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) << (yyvsp[0]));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(yyval) = (yyvsp[-2]) << (yyvsp[0]);
|
(yyval) = (yyvsp[-2]) << (yyvsp[0]);
|
||||||
|
|
@ -1553,7 +1540,7 @@ yyreduce:
|
||||||
case 20:
|
case 20:
|
||||||
|
|
||||||
{
|
{
|
||||||
(yyval) = gl::WrappingDiff<YYSTYPE>((yyvsp[-2]), (yyvsp[0]));
|
(yyval) = (yyvsp[-2]) - (yyvsp[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1561,7 +1548,7 @@ yyreduce:
|
||||||
case 21:
|
case 21:
|
||||||
|
|
||||||
{
|
{
|
||||||
(yyval) = gl::WrappingSum<YYSTYPE>((yyvsp[-2]), (yyvsp[0]));
|
(yyval) = (yyvsp[-2]) + (yyvsp[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1583,12 +1570,6 @@ yyreduce:
|
||||||
}
|
}
|
||||||
(yyval) = static_cast<YYSTYPE>(0);
|
(yyval) = static_cast<YYSTYPE>(0);
|
||||||
}
|
}
|
||||||
else if (((yyvsp[-2]) == std::numeric_limits<YYSTYPE>::min()) && ((yyvsp[0]) == -1))
|
|
||||||
{
|
|
||||||
// Check for the special case where the minimum representable number is
|
|
||||||
// divided by -1. If left alone this has undefined results.
|
|
||||||
(yyval) = 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(yyval) = (yyvsp[-2]) % (yyvsp[0]);
|
(yyval) = (yyvsp[-2]) % (yyvsp[0]);
|
||||||
|
|
@ -1614,13 +1595,6 @@ yyreduce:
|
||||||
}
|
}
|
||||||
(yyval) = static_cast<YYSTYPE>(0);
|
(yyval) = static_cast<YYSTYPE>(0);
|
||||||
}
|
}
|
||||||
else if (((yyvsp[-2]) == std::numeric_limits<YYSTYPE>::min()) && ((yyvsp[0]) == -1))
|
|
||||||
{
|
|
||||||
// Check for the special case where the minimum representable number is
|
|
||||||
// divided by -1. If left alone this leads to integer overflow in C++, which
|
|
||||||
// has undefined results.
|
|
||||||
(yyval) = std::numeric_limits<YYSTYPE>::max();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(yyval) = (yyvsp[-2]) / (yyvsp[0]);
|
(yyval) = (yyvsp[-2]) / (yyvsp[0]);
|
||||||
|
|
@ -1632,7 +1606,7 @@ yyreduce:
|
||||||
case 24:
|
case 24:
|
||||||
|
|
||||||
{
|
{
|
||||||
(yyval) = gl::WrappingMul((yyvsp[-2]), (yyvsp[0]));
|
(yyval) = (yyvsp[-2]) * (yyvsp[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1656,16 +1630,7 @@ yyreduce:
|
||||||
case 27:
|
case 27:
|
||||||
|
|
||||||
{
|
{
|
||||||
// Check for negation of minimum representable integer to prevent undefined signed int
|
(yyval) = - (yyvsp[0]);
|
||||||
// overflow.
|
|
||||||
if ((yyvsp[0]) == std::numeric_limits<YYSTYPE>::min())
|
|
||||||
{
|
|
||||||
(yyval) = std::numeric_limits<YYSTYPE>::min();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(yyval) = -(yyvsp[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
#ifndef COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
#ifndef COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
||||||
#define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
#define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
||||||
|
|
||||||
#include "common/angleutils.h"
|
#include "DiagnosticsBase.h"
|
||||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
#include "pp_utils.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
@ -16,7 +16,7 @@ namespace pp
|
||||||
class Lexer;
|
class Lexer;
|
||||||
struct Token;
|
struct Token;
|
||||||
|
|
||||||
class ExpressionParser : angle::NonCopyable
|
class ExpressionParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct ErrorSettings
|
struct ErrorSettings
|
||||||
|
|
@ -34,6 +34,8 @@ class ExpressionParser : angle::NonCopyable
|
||||||
bool *valid);
|
bool *valid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser);
|
||||||
|
|
||||||
Lexer *mLexer;
|
Lexer *mLexer;
|
||||||
Diagnostics *mDiagnostics;
|
Diagnostics *mDiagnostics;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -41,15 +41,17 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser.
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "DiagnosticsBase.h"
|
#include "DiagnosticsBase.h"
|
||||||
#include "Lexer.h"
|
#include "Lexer.h"
|
||||||
#include "Token.h"
|
#include "Token.h"
|
||||||
#include "common/mathutil.h"
|
|
||||||
|
|
||||||
typedef int32_t YYSTYPE;
|
#if defined(_MSC_VER)
|
||||||
typedef uint32_t UNSIGNED_TYPE;
|
typedef __int64 YYSTYPE;
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef intmax_t YYSTYPE;
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#define YYENABLE_NLS 0
|
#define YYENABLE_NLS 0
|
||||||
#define YYLTYPE_IS_TRIVIAL 1
|
#define YYLTYPE_IS_TRIVIAL 1
|
||||||
|
|
@ -194,7 +196,7 @@ expression
|
||||||
$$ = $1 < $3;
|
$$ = $1 < $3;
|
||||||
}
|
}
|
||||||
| expression TOK_OP_RIGHT expression {
|
| expression TOK_OP_RIGHT expression {
|
||||||
if ($3 < 0 || $3 > 31)
|
if ($3 < 0)
|
||||||
{
|
{
|
||||||
if (!context->isIgnoringErrors())
|
if (!context->isIgnoringErrors())
|
||||||
{
|
{
|
||||||
|
|
@ -208,18 +210,13 @@ expression
|
||||||
}
|
}
|
||||||
$$ = static_cast<YYSTYPE>(0);
|
$$ = static_cast<YYSTYPE>(0);
|
||||||
}
|
}
|
||||||
else if ($1 < 0)
|
|
||||||
{
|
|
||||||
// Logical shift right.
|
|
||||||
$$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) >> $3);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$$ = $1 >> $3;
|
$$ = $1 >> $3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| expression TOK_OP_LEFT expression {
|
| expression TOK_OP_LEFT expression {
|
||||||
if ($3 < 0 || $3 > 31)
|
if ($3 < 0)
|
||||||
{
|
{
|
||||||
if (!context->isIgnoringErrors())
|
if (!context->isIgnoringErrors())
|
||||||
{
|
{
|
||||||
|
|
@ -233,21 +230,16 @@ expression
|
||||||
}
|
}
|
||||||
$$ = static_cast<YYSTYPE>(0);
|
$$ = static_cast<YYSTYPE>(0);
|
||||||
}
|
}
|
||||||
else if ($1 < 0)
|
|
||||||
{
|
|
||||||
// Logical shift left.
|
|
||||||
$$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) << $3);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$$ = $1 << $3;
|
$$ = $1 << $3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| expression '-' expression {
|
| expression '-' expression {
|
||||||
$$ = gl::WrappingDiff<YYSTYPE>($1, $3);
|
$$ = $1 - $3;
|
||||||
}
|
}
|
||||||
| expression '+' expression {
|
| expression '+' expression {
|
||||||
$$ = gl::WrappingSum<YYSTYPE>($1, $3);
|
$$ = $1 + $3;
|
||||||
}
|
}
|
||||||
| expression '%' expression {
|
| expression '%' expression {
|
||||||
if ($3 == 0)
|
if ($3 == 0)
|
||||||
|
|
@ -264,12 +256,6 @@ expression
|
||||||
}
|
}
|
||||||
$$ = static_cast<YYSTYPE>(0);
|
$$ = static_cast<YYSTYPE>(0);
|
||||||
}
|
}
|
||||||
else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1))
|
|
||||||
{
|
|
||||||
// Check for the special case where the minimum representable number is
|
|
||||||
// divided by -1. If left alone this has undefined results.
|
|
||||||
$$ = 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$$ = $1 % $3;
|
$$ = $1 % $3;
|
||||||
|
|
@ -290,20 +276,13 @@ expression
|
||||||
}
|
}
|
||||||
$$ = static_cast<YYSTYPE>(0);
|
$$ = static_cast<YYSTYPE>(0);
|
||||||
}
|
}
|
||||||
else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1))
|
|
||||||
{
|
|
||||||
// Check for the special case where the minimum representable number is
|
|
||||||
// divided by -1. If left alone this leads to integer overflow in C++, which
|
|
||||||
// has undefined results.
|
|
||||||
$$ = std::numeric_limits<YYSTYPE>::max();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$$ = $1 / $3;
|
$$ = $1 / $3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| expression '*' expression {
|
| expression '*' expression {
|
||||||
$$ = gl::WrappingMul($1, $3);
|
$$ = $1 * $3;
|
||||||
}
|
}
|
||||||
| '!' expression %prec TOK_UNARY {
|
| '!' expression %prec TOK_UNARY {
|
||||||
$$ = ! $2;
|
$$ = ! $2;
|
||||||
|
|
@ -312,16 +291,7 @@ expression
|
||||||
$$ = ~ $2;
|
$$ = ~ $2;
|
||||||
}
|
}
|
||||||
| '-' expression %prec TOK_UNARY {
|
| '-' expression %prec TOK_UNARY {
|
||||||
// Check for negation of minimum representable integer to prevent undefined signed int
|
$$ = - $2;
|
||||||
// overflow.
|
|
||||||
if ($2 == std::numeric_limits<YYSTYPE>::min())
|
|
||||||
{
|
|
||||||
$$ = std::numeric_limits<YYSTYPE>::min();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$$ = -$2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
| '+' expression %prec TOK_UNARY {
|
| '+' expression %prec TOK_UNARY {
|
||||||
$$ = + $2;
|
$$ = + $2;
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,12 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "compiler/preprocessor/Input.h"
|
#include "Input.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "common/debug.h"
|
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -33,7 +32,7 @@ Input::Input(size_t count, const char *const string[], const int length[]) :
|
||||||
const char *Input::skipChar()
|
const char *Input::skipChar()
|
||||||
{
|
{
|
||||||
// This function should only be called when there is a character to skip.
|
// This function should only be called when there is a character to skip.
|
||||||
ASSERT(mReadLoc.cIndex < mLength[mReadLoc.sIndex]);
|
assert(mReadLoc.cIndex < mLength[mReadLoc.sIndex]);
|
||||||
++mReadLoc.cIndex;
|
++mReadLoc.cIndex;
|
||||||
if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
|
if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
#ifndef COMPILER_PREPROCESSOR_INPUT_H_
|
#ifndef COMPILER_PREPROCESSOR_INPUT_H_
|
||||||
#define COMPILER_PREPROCESSOR_INPUT_H_
|
#define COMPILER_PREPROCESSOR_INPUT_H_
|
||||||
|
|
||||||
#include <cstddef>
|
#include <stddef.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "compiler/preprocessor/Lexer.h"
|
#include "Lexer.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,12 @@
|
||||||
#ifndef COMPILER_PREPROCESSOR_LEXER_H_
|
#ifndef COMPILER_PREPROCESSOR_LEXER_H_
|
||||||
#define COMPILER_PREPROCESSOR_LEXER_H_
|
#define COMPILER_PREPROCESSOR_LEXER_H_
|
||||||
|
|
||||||
#include "common/angleutils.h"
|
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Token;
|
struct Token;
|
||||||
|
|
||||||
class Lexer : angle::NonCopyable
|
class Lexer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Lexer();
|
virtual ~Lexer();
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,11 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "compiler/preprocessor/Macro.h"
|
#include "Macro.h"
|
||||||
|
|
||||||
#include "common/angleutils.h"
|
#include <sstream>
|
||||||
#include "compiler/preprocessor/Token.h"
|
|
||||||
|
#include "Token.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
@ -22,9 +23,12 @@ bool Macro::equals(const Macro &other) const
|
||||||
|
|
||||||
void PredefineMacro(MacroSet *macroSet, const char *name, int value)
|
void PredefineMacro(MacroSet *macroSet, const char *name, int value)
|
||||||
{
|
{
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << value;
|
||||||
|
|
||||||
Token token;
|
Token token;
|
||||||
token.type = Token::CONST_INT;
|
token.type = Token::CONST_INT;
|
||||||
token.text = ToString(value);
|
token.text = stream.str();
|
||||||
|
|
||||||
Macro macro;
|
Macro macro;
|
||||||
macro.predefined = true;
|
macro.predefined = true;
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,16 @@ struct Macro
|
||||||
typedef std::vector<std::string> Parameters;
|
typedef std::vector<std::string> Parameters;
|
||||||
typedef std::vector<Token> Replacements;
|
typedef std::vector<Token> Replacements;
|
||||||
|
|
||||||
Macro() : predefined(false), disabled(false), expansionCount(0), type(kTypeObj) {}
|
Macro()
|
||||||
|
: predefined(false),
|
||||||
|
disabled(false),
|
||||||
|
type(kTypeObj)
|
||||||
|
{
|
||||||
|
}
|
||||||
bool equals(const Macro &other) const;
|
bool equals(const Macro &other) const;
|
||||||
|
|
||||||
bool predefined;
|
bool predefined;
|
||||||
mutable bool disabled;
|
mutable bool disabled;
|
||||||
mutable int expansionCount;
|
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,17 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "compiler/preprocessor/MacroExpander.h"
|
#include "MacroExpander.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "common/debug.h"
|
#include "DiagnosticsBase.h"
|
||||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
#include "Token.h"
|
||||||
#include "compiler/preprocessor/Token.h"
|
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
const size_t kMaxContextTokens = 10000;
|
|
||||||
|
|
||||||
class TokenLexer : public Lexer
|
class TokenLexer : public Lexer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -45,52 +40,22 @@ class TokenLexer : public Lexer
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PP_DISALLOW_COPY_AND_ASSIGN(TokenLexer);
|
||||||
|
|
||||||
TokenVector mTokens;
|
TokenVector mTokens;
|
||||||
TokenVector::const_iterator mIter;
|
TokenVector::const_iterator mIter;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
class MacroExpander::ScopedMacroReenabler final : angle::NonCopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ScopedMacroReenabler(MacroExpander *expander);
|
|
||||||
~ScopedMacroReenabler();
|
|
||||||
|
|
||||||
private:
|
|
||||||
MacroExpander *mExpander;
|
|
||||||
};
|
|
||||||
|
|
||||||
MacroExpander::ScopedMacroReenabler::ScopedMacroReenabler(MacroExpander *expander)
|
|
||||||
: mExpander(expander)
|
|
||||||
{
|
|
||||||
mExpander->mDeferReenablingMacros = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MacroExpander::ScopedMacroReenabler::~ScopedMacroReenabler()
|
|
||||||
{
|
|
||||||
mExpander->mDeferReenablingMacros = false;
|
|
||||||
for (auto *macro : mExpander->mMacrosToReenable)
|
|
||||||
{
|
|
||||||
macro->disabled = false;
|
|
||||||
}
|
|
||||||
mExpander->mMacrosToReenable.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
MacroExpander::MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics)
|
MacroExpander::MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics)
|
||||||
: mLexer(lexer),
|
: mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics)
|
||||||
mMacroSet(macroSet),
|
|
||||||
mDiagnostics(diagnostics),
|
|
||||||
mTotalTokensInContexts(0),
|
|
||||||
mDeferReenablingMacros(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MacroExpander::~MacroExpander()
|
MacroExpander::~MacroExpander()
|
||||||
{
|
{
|
||||||
for (MacroContext *context : mContextStack)
|
for (std::size_t i = 0; i < mContextStack.size(); ++i)
|
||||||
{
|
{
|
||||||
delete context;
|
delete mContextStack[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,15 +82,10 @@ void MacroExpander::lex(Token *token)
|
||||||
token->setExpansionDisabled(true);
|
token->setExpansionDisabled(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bump the expansion count before peeking if the next token is a '('
|
|
||||||
// otherwise there could be a #undef of the macro before the next token.
|
|
||||||
macro.expansionCount++;
|
|
||||||
if ((macro.type == Macro::kTypeFunc) && !isNextTokenLeftParen())
|
if ((macro.type == Macro::kTypeFunc) && !isNextTokenLeftParen())
|
||||||
{
|
{
|
||||||
// If the token immediately after the macro name is not a '(',
|
// If the token immediately after the macro name is not a '(',
|
||||||
// this macro should not be expanded.
|
// this macro should not be expanded.
|
||||||
macro.expansionCount--;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,7 +114,6 @@ void MacroExpander::getToken(Token *token)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERT(mTotalTokensInContexts == 0);
|
|
||||||
mLexer->lex(token);
|
mLexer->lex(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -165,11 +124,11 @@ void MacroExpander::ungetToken(const Token &token)
|
||||||
{
|
{
|
||||||
MacroContext *context = mContextStack.back();
|
MacroContext *context = mContextStack.back();
|
||||||
context->unget();
|
context->unget();
|
||||||
ASSERT(context->replacements[context->index] == token);
|
assert(context->replacements[context->index] == token);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERT(!mReserveToken.get());
|
assert(!mReserveToken.get());
|
||||||
mReserveToken.reset(new Token(token));
|
mReserveToken.reset(new Token(token));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -187,10 +146,10 @@ bool MacroExpander::isNextTokenLeftParen()
|
||||||
|
|
||||||
bool MacroExpander::pushMacro(const Macro ¯o, const Token &identifier)
|
bool MacroExpander::pushMacro(const Macro ¯o, const Token &identifier)
|
||||||
{
|
{
|
||||||
ASSERT(!macro.disabled);
|
assert(!macro.disabled);
|
||||||
ASSERT(!identifier.expansionDisabled());
|
assert(!identifier.expansionDisabled());
|
||||||
ASSERT(identifier.type == Token::IDENTIFIER);
|
assert(identifier.type == Token::IDENTIFIER);
|
||||||
ASSERT(identifier.text == macro.name);
|
assert(identifier.text == macro.name);
|
||||||
|
|
||||||
std::vector<Token> replacements;
|
std::vector<Token> replacements;
|
||||||
if (!expandMacro(macro, identifier, &replacements))
|
if (!expandMacro(macro, identifier, &replacements))
|
||||||
|
|
@ -203,30 +162,19 @@ bool MacroExpander::pushMacro(const Macro ¯o, const Token &identifier)
|
||||||
context->macro = ¯o;
|
context->macro = ¯o;
|
||||||
context->replacements.swap(replacements);
|
context->replacements.swap(replacements);
|
||||||
mContextStack.push_back(context);
|
mContextStack.push_back(context);
|
||||||
mTotalTokensInContexts += context->replacements.size();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroExpander::popMacro()
|
void MacroExpander::popMacro()
|
||||||
{
|
{
|
||||||
ASSERT(!mContextStack.empty());
|
assert(!mContextStack.empty());
|
||||||
|
|
||||||
MacroContext *context = mContextStack.back();
|
MacroContext *context = mContextStack.back();
|
||||||
mContextStack.pop_back();
|
mContextStack.pop_back();
|
||||||
|
|
||||||
ASSERT(context->empty());
|
assert(context->empty());
|
||||||
ASSERT(context->macro->disabled);
|
assert(context->macro->disabled);
|
||||||
ASSERT(context->macro->expansionCount > 0);
|
context->macro->disabled = false;
|
||||||
if (mDeferReenablingMacros)
|
|
||||||
{
|
|
||||||
mMacrosToReenable.push_back(context->macro);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
context->macro->disabled = false;
|
|
||||||
}
|
|
||||||
context->macro->expansionCount--;
|
|
||||||
mTotalTokensInContexts -= context->replacements.size();
|
|
||||||
delete context;
|
delete context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,21 +199,25 @@ bool MacroExpander::expandMacro(const Macro ¯o,
|
||||||
const char kLine[] = "__LINE__";
|
const char kLine[] = "__LINE__";
|
||||||
const char kFile[] = "__FILE__";
|
const char kFile[] = "__FILE__";
|
||||||
|
|
||||||
ASSERT(replacements->size() == 1);
|
assert(replacements->size() == 1);
|
||||||
Token& repl = replacements->front();
|
Token& repl = replacements->front();
|
||||||
if (macro.name == kLine)
|
if (macro.name == kLine)
|
||||||
{
|
{
|
||||||
repl.text = ToString(identifier.location.line);
|
std::ostringstream stream;
|
||||||
|
stream << identifier.location.line;
|
||||||
|
repl.text = stream.str();
|
||||||
}
|
}
|
||||||
else if (macro.name == kFile)
|
else if (macro.name == kFile)
|
||||||
{
|
{
|
||||||
repl.text = ToString(identifier.location.file);
|
std::ostringstream stream;
|
||||||
|
stream << identifier.location.file;
|
||||||
|
repl.text = stream.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERT(macro.type == Macro::kTypeFunc);
|
assert(macro.type == Macro::kTypeFunc);
|
||||||
std::vector<MacroArg> args;
|
std::vector<MacroArg> args;
|
||||||
args.reserve(macro.parameters.size());
|
args.reserve(macro.parameters.size());
|
||||||
if (!collectMacroArgs(macro, identifier, &args, &replacementLocation))
|
if (!collectMacroArgs(macro, identifier, &args, &replacementLocation))
|
||||||
|
|
@ -296,17 +248,10 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o,
|
||||||
{
|
{
|
||||||
Token token;
|
Token token;
|
||||||
getToken(&token);
|
getToken(&token);
|
||||||
ASSERT(token.type == '(');
|
assert(token.type == '(');
|
||||||
|
|
||||||
args->push_back(MacroArg());
|
args->push_back(MacroArg());
|
||||||
|
for (int openParens = 1; openParens != 0; )
|
||||||
// Defer reenabling macros until args collection is finished to avoid the possibility of
|
|
||||||
// infinite recursion. Otherwise infinite recursion might happen when expanding the args after
|
|
||||||
// macros have been popped from the context stack when parsing the args.
|
|
||||||
ScopedMacroReenabler deferReenablingMacros(this);
|
|
||||||
|
|
||||||
int openParens = 1;
|
|
||||||
while (openParens != 0)
|
|
||||||
{
|
{
|
||||||
getToken(&token);
|
getToken(&token);
|
||||||
|
|
||||||
|
|
@ -372,9 +317,9 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o,
|
||||||
// Pre-expand each argument before substitution.
|
// Pre-expand each argument before substitution.
|
||||||
// This step expands each argument individually before they are
|
// This step expands each argument individually before they are
|
||||||
// inserted into the macro body.
|
// inserted into the macro body.
|
||||||
size_t numTokens = 0;
|
for (std::size_t i = 0; i < args->size(); ++i)
|
||||||
for (auto &arg : *args)
|
|
||||||
{
|
{
|
||||||
|
MacroArg &arg = args->at(i);
|
||||||
TokenLexer lexer(&arg);
|
TokenLexer lexer(&arg);
|
||||||
MacroExpander expander(&lexer, mMacroSet, mDiagnostics);
|
MacroExpander expander(&lexer, mMacroSet, mDiagnostics);
|
||||||
|
|
||||||
|
|
@ -384,12 +329,6 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o,
|
||||||
{
|
{
|
||||||
arg.push_back(token);
|
arg.push_back(token);
|
||||||
expander.lex(&token);
|
expander.lex(&token);
|
||||||
numTokens++;
|
|
||||||
if (numTokens + mTotalTokensInContexts > kMaxContextTokens)
|
|
||||||
{
|
|
||||||
mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -401,14 +340,6 @@ void MacroExpander::replaceMacroParams(const Macro ¯o,
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < macro.replacements.size(); ++i)
|
for (std::size_t i = 0; i < macro.replacements.size(); ++i)
|
||||||
{
|
{
|
||||||
if (!replacements->empty() &&
|
|
||||||
replacements->size() + mTotalTokensInContexts > kMaxContextTokens)
|
|
||||||
{
|
|
||||||
const Token &token = replacements->back();
|
|
||||||
mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Token &repl = macro.replacements[i];
|
const Token &repl = macro.replacements[i];
|
||||||
if (repl.type != Token::IDENTIFIER)
|
if (repl.type != Token::IDENTIFIER)
|
||||||
{
|
{
|
||||||
|
|
@ -441,25 +372,5 @@ void MacroExpander::replaceMacroParams(const Macro ¯o,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MacroExpander::MacroContext::MacroContext() : macro(0), index(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroExpander::MacroContext::empty() const
|
|
||||||
{
|
|
||||||
return index == replacements.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Token &MacroExpander::MacroContext::get()
|
|
||||||
{
|
|
||||||
return replacements[index++];
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroExpander::MacroContext::unget()
|
|
||||||
{
|
|
||||||
ASSERT(index > 0);
|
|
||||||
--index;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace pp
|
} // namespace pp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,13 @@
|
||||||
#ifndef COMPILER_PREPROCESSOR_MACROEXPANDER_H_
|
#ifndef COMPILER_PREPROCESSOR_MACROEXPANDER_H_
|
||||||
#define COMPILER_PREPROCESSOR_MACROEXPANDER_H_
|
#define COMPILER_PREPROCESSOR_MACROEXPANDER_H_
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "compiler/preprocessor/Lexer.h"
|
#include "Lexer.h"
|
||||||
#include "compiler/preprocessor/Macro.h"
|
#include "Macro.h"
|
||||||
|
#include "pp_utils.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
@ -28,6 +30,8 @@ class MacroExpander : public Lexer
|
||||||
void lex(Token *token) override;
|
void lex(Token *token) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander);
|
||||||
|
|
||||||
void getToken(Token *token);
|
void getToken(Token *token);
|
||||||
void ungetToken(const Token &token);
|
void ungetToken(const Token &token);
|
||||||
bool isNextTokenLeftParen();
|
bool isNextTokenLeftParen();
|
||||||
|
|
@ -50,14 +54,28 @@ class MacroExpander : public Lexer
|
||||||
|
|
||||||
struct MacroContext
|
struct MacroContext
|
||||||
{
|
{
|
||||||
MacroContext();
|
|
||||||
bool empty() const;
|
|
||||||
const Token &get();
|
|
||||||
void unget();
|
|
||||||
|
|
||||||
const Macro *macro;
|
const Macro *macro;
|
||||||
std::size_t index;
|
std::size_t index;
|
||||||
std::vector<Token> replacements;
|
std::vector<Token> replacements;
|
||||||
|
|
||||||
|
MacroContext()
|
||||||
|
: macro(0),
|
||||||
|
index(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return index == replacements.size();
|
||||||
|
}
|
||||||
|
const Token &get()
|
||||||
|
{
|
||||||
|
return replacements[index++];
|
||||||
|
}
|
||||||
|
void unget()
|
||||||
|
{
|
||||||
|
assert(index > 0);
|
||||||
|
--index;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Lexer *mLexer;
|
Lexer *mLexer;
|
||||||
|
|
@ -66,12 +84,6 @@ class MacroExpander : public Lexer
|
||||||
|
|
||||||
std::unique_ptr<Token> mReserveToken;
|
std::unique_ptr<Token> mReserveToken;
|
||||||
std::vector<MacroContext *> mContextStack;
|
std::vector<MacroContext *> mContextStack;
|
||||||
size_t mTotalTokensInContexts;
|
|
||||||
|
|
||||||
bool mDeferReenablingMacros;
|
|
||||||
std::vector<const Macro *> mMacrosToReenable;
|
|
||||||
|
|
||||||
class ScopedMacroReenabler;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pp
|
} // namespace pp
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,16 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "compiler/preprocessor/Preprocessor.h"
|
#include "Preprocessor.h"
|
||||||
|
|
||||||
#include "common/debug.h"
|
#include <cassert>
|
||||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
|
||||||
#include "compiler/preprocessor/DirectiveParser.h"
|
#include "DiagnosticsBase.h"
|
||||||
#include "compiler/preprocessor/Macro.h"
|
#include "DirectiveParser.h"
|
||||||
#include "compiler/preprocessor/MacroExpander.h"
|
#include "Macro.h"
|
||||||
#include "compiler/preprocessor/Token.h"
|
#include "MacroExpander.h"
|
||||||
#include "compiler/preprocessor/Tokenizer.h"
|
#include "Token.h"
|
||||||
|
#include "Tokenizer.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
@ -77,8 +78,8 @@ void Preprocessor::lex(Token *token)
|
||||||
// Convert preprocessing tokens to compiler tokens or report
|
// Convert preprocessing tokens to compiler tokens or report
|
||||||
// diagnostics.
|
// diagnostics.
|
||||||
case Token::PP_HASH:
|
case Token::PP_HASH:
|
||||||
UNREACHABLE();
|
assert(false);
|
||||||
break;
|
break;
|
||||||
case Token::PP_NUMBER:
|
case Token::PP_NUMBER:
|
||||||
mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER,
|
mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER,
|
||||||
token->location, token->text);
|
token->location, token->text);
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@
|
||||||
#ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_
|
#ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_
|
||||||
#define COMPILER_PREPROCESSOR_PREPROCESSOR_H_
|
#define COMPILER_PREPROCESSOR_PREPROCESSOR_H_
|
||||||
|
|
||||||
#include <cstddef>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "common/angleutils.h"
|
#include "pp_utils.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
@ -19,7 +19,7 @@ class DirectiveHandler;
|
||||||
struct PreprocessorImpl;
|
struct PreprocessorImpl;
|
||||||
struct Token;
|
struct Token;
|
||||||
|
|
||||||
class Preprocessor : angle::NonCopyable
|
class Preprocessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Preprocessor(Diagnostics *diagnostics, DirectiveHandler *directiveHandler);
|
Preprocessor(Diagnostics *diagnostics, DirectiveHandler *directiveHandler);
|
||||||
|
|
@ -44,6 +44,8 @@ class Preprocessor : angle::NonCopyable
|
||||||
void setMaxTokenSize(size_t maxTokenSize);
|
void setMaxTokenSize(size_t maxTokenSize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor);
|
||||||
|
|
||||||
PreprocessorImpl *mImpl;
|
PreprocessorImpl *mImpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,11 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "compiler/preprocessor/Token.h"
|
#include "Token.h"
|
||||||
|
|
||||||
#include "common/debug.h"
|
#include <cassert>
|
||||||
#include "compiler/preprocessor/numeric_lex.h"
|
|
||||||
|
#include "numeric_lex.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
@ -54,19 +55,19 @@ void Token::setExpansionDisabled(bool disable)
|
||||||
|
|
||||||
bool Token::iValue(int *value) const
|
bool Token::iValue(int *value) const
|
||||||
{
|
{
|
||||||
ASSERT(type == CONST_INT);
|
assert(type == CONST_INT);
|
||||||
return numeric_lex_int(text, value);
|
return numeric_lex_int(text, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Token::uValue(unsigned int *value) const
|
bool Token::uValue(unsigned int *value) const
|
||||||
{
|
{
|
||||||
ASSERT(type == CONST_INT);
|
assert(type == CONST_INT);
|
||||||
return numeric_lex_int(text, value);
|
return numeric_lex_int(text, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Token::fValue(float *value) const
|
bool Token::fValue(float *value) const
|
||||||
{
|
{
|
||||||
ASSERT(type == CONST_FLOAT);
|
assert(type == CONST_FLOAT);
|
||||||
return numeric_lex_float(text, value);
|
return numeric_lex_float(text, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "compiler/preprocessor/SourceLocation.h"
|
#include "SourceLocation.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
@ -113,7 +113,7 @@ inline bool operator!=(const Token &lhs, const Token &rhs)
|
||||||
return !lhs.equals(rhs);
|
return !lhs.equals(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const Token &token);
|
extern std::ostream &operator<<(std::ostream &out, const Token &token);
|
||||||
|
|
||||||
} // namepsace pp
|
} // namepsace pp
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -7,9 +7,9 @@
|
||||||
#ifndef COMPILER_PREPROCESSOR_TOKENIZER_H_
|
#ifndef COMPILER_PREPROCESSOR_TOKENIZER_H_
|
||||||
#define COMPILER_PREPROCESSOR_TOKENIZER_H_
|
#define COMPILER_PREPROCESSOR_TOKENIZER_H_
|
||||||
|
|
||||||
#include "common/angleutils.h"
|
#include "Input.h"
|
||||||
#include "compiler/preprocessor/Input.h"
|
#include "Lexer.h"
|
||||||
#include "compiler/preprocessor/Lexer.h"
|
#include "pp_utils.h"
|
||||||
|
|
||||||
namespace pp
|
namespace pp
|
||||||
{
|
{
|
||||||
|
|
@ -45,6 +45,7 @@ class Tokenizer : public Lexer
|
||||||
void lex(Token *token) override;
|
void lex(Token *token) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer);
|
||||||
bool initScanner();
|
bool initScanner();
|
||||||
void destroyScanner();
|
void destroyScanner();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
|
||||||
#pragma warning(disable: 4005)
|
#pragma warning(disable: 4005)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "compiler/preprocessor/Tokenizer.h"
|
#include "Tokenizer.h"
|
||||||
|
|
||||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
#include "DiagnosticsBase.h"
|
||||||
#include "compiler/preprocessor/Token.h"
|
#include "Token.h"
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
// Triggered by the auto-generated yy_fatal_error function.
|
// Triggered by the auto-generated yy_fatal_error function.
|
||||||
|
|
@ -280,7 +280,9 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
|
||||||
|
|
||||||
namespace pp {
|
namespace pp {
|
||||||
|
|
||||||
Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(256)
|
Tokenizer::Tokenizer(Diagnostics *diagnostics)
|
||||||
|
: mHandle(0),
|
||||||
|
mMaxTokenSize(256)
|
||||||
{
|
{
|
||||||
mContext.diagnostics = diagnostics;
|
mContext.diagnostics = diagnostics;
|
||||||
}
|
}
|
||||||
|
|
@ -337,7 +339,7 @@ void Tokenizer::lex(Token *token)
|
||||||
|
|
||||||
bool Tokenizer::initScanner()
|
bool Tokenizer::initScanner()
|
||||||
{
|
{
|
||||||
if ((mHandle == nullptr) && yylex_init_extra(&mContext, &mHandle))
|
if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
yyrestart(0, mHandle);
|
yyrestart(0, mHandle);
|
||||||
|
|
@ -346,11 +348,11 @@ bool Tokenizer::initScanner()
|
||||||
|
|
||||||
void Tokenizer::destroyScanner()
|
void Tokenizer::destroyScanner()
|
||||||
{
|
{
|
||||||
if (mHandle == nullptr)
|
if (mHandle == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
yylex_destroy(mHandle);
|
yylex_destroy(mHandle);
|
||||||
mHandle = nullptr;
|
mHandle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pp
|
} // namespace pp
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
#ifndef COMPILER_PREPROCESSOR_NUMERICLEX_H_
|
#ifndef COMPILER_PREPROCESSOR_NUMERICLEX_H_
|
||||||
#define COMPILER_PREPROCESSOR_NUMERICLEX_H_
|
#define COMPILER_PREPROCESSOR_NUMERICLEX_H_
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace pp {
|
namespace pp {
|
||||||
|
|
@ -64,7 +63,7 @@ bool numeric_lex_float(const std::string &str, FloatType *value)
|
||||||
stream.imbue(std::locale::classic());
|
stream.imbue(std::locale::classic());
|
||||||
|
|
||||||
stream >> (*value);
|
stream >> (*value);
|
||||||
return !stream.fail() && std::isfinite(*value);
|
return !stream.fail();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
18
gfx/angle/src/compiler/preprocessor/pp_utils.h
Normal file
18
gfx/angle/src/compiler/preprocessor/pp_utils.h
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
//
|
||||||
|
|
||||||
|
// pp_utils.h: Common preprocessor utilities
|
||||||
|
|
||||||
|
#ifndef COMPILER_PREPROCESSOR_PPUTILS_H_
|
||||||
|
#define COMPILER_PREPROCESSOR_PPUTILS_H_
|
||||||
|
|
||||||
|
// A macro to disallow the copy constructor and operator= functions
|
||||||
|
// This must be used in the private: declarations for a class.
|
||||||
|
#define PP_DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||||
|
TypeName(const TypeName &); \
|
||||||
|
void operator=(const TypeName &)
|
||||||
|
|
||||||
|
#endif // COMPILER_PREPROCESSOR_PPUTILS_H_
|
||||||
|
|
@ -1,13 +1,6 @@
|
||||||
diff --git a/src/compiler/translator/glslang_lex.cpp b/src/compiler/translator/glslang_lex.cpp
|
--- a/src/compiler/glslang_lex.cpp
|
||||||
index 1ba63df..2a206ab 100644
|
+++ b/src/compiler/glslang_lex.cpp
|
||||||
--- a/src/compiler/translator/glslang_lex.cpp
|
@@ -68,6 +68,7 @@ typedef int16_t flex_int16_t;
|
||||||
+++ b/src/compiler/translator/glslang_lex.cpp
|
|
||||||
@@ -1,4 +1,3 @@
|
|
||||||
-#line 17 "./glslang.l"
|
|
||||||
//
|
|
||||||
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
@@ -149,6 +148,7 @@ typedef int16_t flex_int16_t;
|
|
||||||
typedef uint16_t flex_uint16_t;
|
typedef uint16_t flex_uint16_t;
|
||||||
typedef int32_t flex_int32_t;
|
typedef int32_t flex_int32_t;
|
||||||
typedef uint32_t flex_uint32_t;
|
typedef uint32_t flex_uint32_t;
|
||||||
|
|
@ -15,10 +8,10 @@ index 1ba63df..2a206ab 100644
|
||||||
#else
|
#else
|
||||||
typedef signed char flex_int8_t;
|
typedef signed char flex_int8_t;
|
||||||
typedef short int flex_int16_t;
|
typedef short int flex_int16_t;
|
||||||
@@ -335,6 +335,11 @@ typedef size_t yy_size_t;
|
@@ -191,6 +192,11 @@ typedef void* yyscan_t;
|
||||||
|
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||||
|
#endif
|
||||||
|
|
||||||
+#ifndef YY_TYPEDEF_YY_SIZE_T
|
+#ifndef YY_TYPEDEF_YY_SIZE_T
|
||||||
+#define YY_TYPEDEF_YY_SIZE_T
|
+#define YY_TYPEDEF_YY_SIZE_T
|
||||||
+typedef size_t yy_size_t;
|
+typedef size_t yy_size_t;
|
||||||
|
|
@ -27,96 +20,21 @@ index 1ba63df..2a206ab 100644
|
||||||
#define EOB_ACT_CONTINUE_SCAN 0
|
#define EOB_ACT_CONTINUE_SCAN 0
|
||||||
#define EOB_ACT_END_OF_FILE 1
|
#define EOB_ACT_END_OF_FILE 1
|
||||||
#define EOB_ACT_LAST_MATCH 2
|
#define EOB_ACT_LAST_MATCH 2
|
||||||
@@ -351,8 +356,8 @@ typedef size_t yy_size_t;
|
@@ -204,7 +210,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||||
*/
|
*/
|
||||||
#define YY_LESS_LINENO(n) \
|
#define YY_LESS_LINENO(n) \
|
||||||
do { \
|
do { \
|
||||||
- int yyl;\
|
- int yyl;\
|
||||||
- for ( yyl = n; yyl < yyleng; ++yyl )\
|
|
||||||
+ yy_size_t yyl;\
|
+ yy_size_t yyl;\
|
||||||
+ for ( yyl = n; yyl < static_cast<yy_site_t>(yyleng); ++yyl )\
|
for ( yyl = n; yyl < yyleng; ++yyl )\
|
||||||
if ( yytext[yyl] == '\n' )\
|
if ( yytext[yyl] == '\n' )\
|
||||||
--yylineno;\
|
--yylineno;\
|
||||||
}while(0)
|
@@ -378,7 +379,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
|
||||||
@@ -1692,7 +1697,7 @@ yy_find_action:
|
*/
|
||||||
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
|
#define YY_DO_BEFORE_ACTION \
|
||||||
{
|
yyg->yytext_ptr = yy_bp; \
|
||||||
yy_size_t yyl;
|
- yyleng = (size_t) (yy_cp - yy_bp); \
|
||||||
- for ( yyl = 0; yyl < yyleng; ++yyl )
|
+ yyleng = (yy_size_t) (yy_cp - yy_bp); \
|
||||||
+ for ( yyl = 0; yyl < static_cast<yy_size_t>(yyleng); ++yyl )
|
yyg->yy_hold_char = *yy_cp; \
|
||||||
if ( yytext[yyl] == '\n' )
|
*yy_cp = '\0'; \
|
||||||
|
yyg->yy_c_buf_p = yy_cp;
|
||||||
do{ yylineno++;
|
|
||||||
@@ -2655,7 +2660,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int num_to_read =
|
|
||||||
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
|
|
||||||
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - static_cast<int>(number_to_move) - 1;
|
|
||||||
|
|
||||||
while ( num_to_read <= 0 )
|
|
||||||
{ /* Not enough room in the buffer - grow it. */
|
|
||||||
@@ -2690,7 +2695,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
|
||||||
yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
|
|
||||||
|
|
||||||
num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
|
|
||||||
- number_to_move - 1;
|
|
||||||
+ static_cast<int>(number_to_move) - 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2698,8 +2703,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
|
||||||
num_to_read = YY_READ_BUF_SIZE;
|
|
||||||
|
|
||||||
/* Read in more data. */
|
|
||||||
+ size_t result = 0;
|
|
||||||
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
|
|
||||||
- yyg->yy_n_chars, num_to_read );
|
|
||||||
+ result, num_to_read );
|
|
||||||
+ yyg->yy_n_chars = static_cast<int>(result);
|
|
||||||
|
|
||||||
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
|
|
||||||
}
|
|
||||||
@@ -2725,13 +2732,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
|
||||||
|
|
||||||
if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
|
|
||||||
/* Extend the array by 50%, plus the number we really need. */
|
|
||||||
- int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
|
|
||||||
+ int new_size = yyg->yy_n_chars + static_cast<int>(number_to_move) + (yyg->yy_n_chars >> 1);
|
|
||||||
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
|
|
||||||
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
|
|
||||||
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
|
|
||||||
}
|
|
||||||
|
|
||||||
- yyg->yy_n_chars += number_to_move;
|
|
||||||
+ yyg->yy_n_chars += static_cast<int>(number_to_move);
|
|
||||||
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
|
|
||||||
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
|
|
||||||
|
|
||||||
@@ -3158,7 +3165,7 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
|
|
||||||
/* Increase the buffer to prepare for a possible push. */
|
|
||||||
yy_size_t grow_size = 8 /* arbitrary grow size */;
|
|
||||||
|
|
||||||
- num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
|
|
||||||
+ num_to_alloc = static_cast<int>(yyg->yy_buffer_stack_max + grow_size);
|
|
||||||
yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
|
|
||||||
(yyg->yy_buffer_stack,
|
|
||||||
num_to_alloc * sizeof(struct yy_buffer_state*)
|
|
||||||
@@ -3196,7 +3203,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann
|
|
||||||
if ( ! b )
|
|
||||||
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
|
|
||||||
|
|
||||||
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
|
|
||||||
+ b->yy_buf_size = static_cast<int>(size) - 2; /* "- 2" to take care of EOB's */
|
|
||||||
b->yy_buf_pos = b->yy_ch_buf = base;
|
|
||||||
b->yy_is_our_buffer = 0;
|
|
||||||
b->yy_input_file = NULL;
|
|
||||||
@@ -3251,7 +3258,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yysc
|
|
||||||
if ( ! buf )
|
|
||||||
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
|
|
||||||
|
|
||||||
- for ( i = 0; i < _yybytes_len; ++i )
|
|
||||||
+ for ( i = 0; i < static_cast<yy_size_t>(_yybytes_len); ++i )
|
|
||||||
buf[i] = yybytes[i];
|
|
||||||
|
|
||||||
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,6 @@
|
||||||
#include "compiler/translator/CallDAG.h"
|
#include "compiler/translator/CallDAG.h"
|
||||||
#include "compiler/translator/SymbolTable.h"
|
#include "compiler/translator/SymbolTable.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -34,7 +31,7 @@ class PullGradient : public TIntermTraverser
|
||||||
ASSERT(index < metadataList->size());
|
ASSERT(index < metadataList->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void traverse(TIntermFunctionDefinition *node)
|
void traverse(TIntermAggregate *node)
|
||||||
{
|
{
|
||||||
node->traverse(this);
|
node->traverse(this);
|
||||||
ASSERT(mParents.empty());
|
ASSERT(mParents.empty());
|
||||||
|
|
@ -75,9 +72,9 @@ class PullGradient : public TIntermTraverser
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool visitIfElse(Visit visit, TIntermIfElse *ifElse) override
|
bool visitSelection(Visit visit, TIntermSelection *selection) override
|
||||||
{
|
{
|
||||||
visitControlFlow(visit, ifElse);
|
visitControlFlow(visit, selection);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,8 +103,9 @@ class PullGradient : public TIntermTraverser
|
||||||
{
|
{
|
||||||
if (node->isUserDefined())
|
if (node->isUserDefined())
|
||||||
{
|
{
|
||||||
size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
|
size_t calleeIndex = mDag.findIndex(node);
|
||||||
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
|
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
|
||||||
|
UNUSED_ASSERTION_VARIABLE(mIndex);
|
||||||
|
|
||||||
if ((*mMetadataList)[calleeIndex].mUsesGradient) {
|
if ((*mMetadataList)[calleeIndex].mUsesGradient) {
|
||||||
onGradient();
|
onGradient();
|
||||||
|
|
@ -115,8 +113,7 @@ class PullGradient : public TIntermTraverser
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TString name =
|
TString name = TFunction::unmangleName(node->getName());
|
||||||
TFunction::unmangleName(node->getFunctionSymbolInfo()->getName());
|
|
||||||
|
|
||||||
if (name == "texture2D" ||
|
if (name == "texture2D" ||
|
||||||
name == "texture2DProj" ||
|
name == "texture2DProj" ||
|
||||||
|
|
@ -160,7 +157,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void traverse(TIntermFunctionDefinition *node)
|
void traverse(TIntermAggregate *node)
|
||||||
{
|
{
|
||||||
node->traverse(this);
|
node->traverse(this);
|
||||||
ASSERT(mLoopsAndSwitches.empty());
|
ASSERT(mLoopsAndSwitches.empty());
|
||||||
|
|
@ -199,7 +196,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool visitIfElse(Visit visit, TIntermIfElse *node) override
|
bool visitSelection(Visit visit, TIntermSelection *node) override
|
||||||
{
|
{
|
||||||
if (visit == PreVisit)
|
if (visit == PreVisit)
|
||||||
{
|
{
|
||||||
|
|
@ -278,8 +275,9 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
|
||||||
{
|
{
|
||||||
if (node->isUserDefined())
|
if (node->isUserDefined())
|
||||||
{
|
{
|
||||||
size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
|
size_t calleeIndex = mDag.findIndex(node);
|
||||||
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
|
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
|
||||||
|
UNUSED_ASSERTION_VARIABLE(mIndex);
|
||||||
|
|
||||||
if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
|
if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
|
||||||
{
|
{
|
||||||
|
|
@ -312,7 +310,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
|
||||||
const CallDAG &mDag;
|
const CallDAG &mDag;
|
||||||
|
|
||||||
std::vector<TIntermNode*> mLoopsAndSwitches;
|
std::vector<TIntermNode*> mLoopsAndSwitches;
|
||||||
std::vector<TIntermIfElse *> mIfs;
|
std::vector<TIntermSelection*> mIfs;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tags all the functions called in a discontinuous loop
|
// Tags all the functions called in a discontinuous loop
|
||||||
|
|
@ -329,7 +327,7 @@ class PushDiscontinuousLoops : public TIntermTraverser
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void traverse(TIntermFunctionDefinition *node)
|
void traverse(TIntermAggregate *node)
|
||||||
{
|
{
|
||||||
node->traverse(this);
|
node->traverse(this);
|
||||||
ASSERT(mNestedDiscont == (mMetadata->mCalledInDiscontinuousLoop ? 1 : 0));
|
ASSERT(mNestedDiscont == (mMetadata->mCalledInDiscontinuousLoop ? 1 : 0));
|
||||||
|
|
@ -358,8 +356,9 @@ class PushDiscontinuousLoops : public TIntermTraverser
|
||||||
case EOpFunctionCall:
|
case EOpFunctionCall:
|
||||||
if (visit == PreVisit && node->isUserDefined() && mNestedDiscont > 0)
|
if (visit == PreVisit && node->isUserDefined() && mNestedDiscont > 0)
|
||||||
{
|
{
|
||||||
size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
|
size_t calleeIndex = mDag.findIndex(node);
|
||||||
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
|
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
|
||||||
|
UNUSED_ASSERTION_VARIABLE(mIndex);
|
||||||
|
|
||||||
(*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true;
|
(*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true;
|
||||||
}
|
}
|
||||||
|
|
@ -386,7 +385,7 @@ bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node)
|
||||||
return mControlFlowsContainingGradient.count(node) > 0;
|
return mControlFlowsContainingGradient.count(node) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTMetadataHLSL::hasGradientLoop(TIntermIfElse *node)
|
bool ASTMetadataHLSL::hasGradientLoop(TIntermSelection *node)
|
||||||
{
|
{
|
||||||
return mIfsContainingGradientLoop.count(node) > 0;
|
return mIfsContainingGradientLoop.count(node) > 0;
|
||||||
}
|
}
|
||||||
|
|
@ -450,5 +449,3 @@ MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag)
|
||||||
|
|
||||||
return metadataList;
|
return metadataList;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,9 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
class CallDAG;
|
class CallDAG;
|
||||||
class TIntermNode;
|
class TIntermNode;
|
||||||
class TIntermIfElse;
|
class TIntermSelection;
|
||||||
class TIntermLoop;
|
class TIntermLoop;
|
||||||
|
|
||||||
struct ASTMetadataHLSL
|
struct ASTMetadataHLSL
|
||||||
|
|
@ -33,7 +30,7 @@ struct ASTMetadataHLSL
|
||||||
// Here "something uses a gradient" means here that it either contains a
|
// Here "something uses a gradient" means here that it either contains a
|
||||||
// gradient operation, or a call to a function that uses a gradient.
|
// gradient operation, or a call to a function that uses a gradient.
|
||||||
bool hasGradientInCallGraph(TIntermLoop *node);
|
bool hasGradientInCallGraph(TIntermLoop *node);
|
||||||
bool hasGradientLoop(TIntermIfElse *node);
|
bool hasGradientLoop(TIntermSelection *node);
|
||||||
|
|
||||||
// Does the function use a gradient.
|
// Does the function use a gradient.
|
||||||
bool mUsesGradient;
|
bool mUsesGradient;
|
||||||
|
|
@ -47,7 +44,7 @@ struct ASTMetadataHLSL
|
||||||
bool mCalledInDiscontinuousLoop;
|
bool mCalledInDiscontinuousLoop;
|
||||||
bool mHasGradientLoopInCallGraph;
|
bool mHasGradientLoopInCallGraph;
|
||||||
std::set<TIntermLoop*> mDiscontinuousLoops;
|
std::set<TIntermLoop*> mDiscontinuousLoops;
|
||||||
std::set<TIntermIfElse *> mIfsContainingGradientLoop;
|
std::set<TIntermSelection *> mIfsContainingGradientLoop;
|
||||||
|
|
||||||
// Will we need to generate a Lod0 version of the function.
|
// Will we need to generate a Lod0 version of the function.
|
||||||
bool mNeedsLod0;
|
bool mNeedsLod0;
|
||||||
|
|
@ -58,6 +55,4 @@ typedef std::vector<ASTMetadataHLSL> MetadataList;
|
||||||
// Return the AST analysis result, in the order defined by the call DAG
|
// Return the AST analysis result, in the order defined by the call DAG
|
||||||
MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag);
|
MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag);
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
|
#endif // COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
|
||||||
|
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "compiler/translator/AddAndTrueToLoopCondition.h"
|
|
||||||
|
|
||||||
#include "compiler/translator/IntermNode.h"
|
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
// An AST traverser that rewrites for and while loops by replacing "condition" with
|
|
||||||
// "condition && true" to work around condition bug on Intel Mac.
|
|
||||||
class AddAndTrueToLoopConditionTraverser : public TIntermTraverser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AddAndTrueToLoopConditionTraverser() : TIntermTraverser(true, false, false) {}
|
|
||||||
|
|
||||||
bool visitLoop(Visit, TIntermLoop *loop) override
|
|
||||||
{
|
|
||||||
// do-while loop doesn't have this bug.
|
|
||||||
if (loop->getType() != ELoopFor && loop->getType() != ELoopWhile)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For loop may not have a condition.
|
|
||||||
if (loop->getCondition() == nullptr)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constant true.
|
|
||||||
TConstantUnion *trueConstant = new TConstantUnion();
|
|
||||||
trueConstant->setBConst(true);
|
|
||||||
TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, TType(EbtBool));
|
|
||||||
|
|
||||||
// CONDITION && true.
|
|
||||||
TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue);
|
|
||||||
loop->setCondition(andOp);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
void AddAndTrueToLoopCondition(TIntermNode *root)
|
|
||||||
{
|
|
||||||
AddAndTrueToLoopConditionTraverser traverser;
|
|
||||||
root->traverse(&traverser);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2016 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.
|
|
||||||
//
|
|
||||||
|
|
||||||
// Rewrite condition in for and while loops to work around driver bug on Intel Mac.
|
|
||||||
|
|
||||||
#ifndef COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
|
|
||||||
#define COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
|
|
||||||
|
|
||||||
class TIntermNode;
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
void AddAndTrueToLoopCondition(TIntermNode *root);
|
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
|
|
||||||
|
|
@ -31,16 +31,21 @@ class AddDefaultReturnStatementsTraverser : private TIntermTraverser
|
||||||
private:
|
private:
|
||||||
AddDefaultReturnStatementsTraverser() : TIntermTraverser(true, false, false) {}
|
AddDefaultReturnStatementsTraverser() : TIntermTraverser(true, false, false) {}
|
||||||
|
|
||||||
static bool IsFunctionWithoutReturnStatement(TIntermFunctionDefinition *node, TType *returnType)
|
static bool IsFunctionWithoutReturnStatement(TIntermAggregate *node, TType *returnType)
|
||||||
{
|
{
|
||||||
*returnType = node->getType();
|
*returnType = node->getType();
|
||||||
if (node->getType().getBasicType() == EbtVoid)
|
if (node->getOp() != EOpFunction || node->getType().getBasicType() == EbtVoid)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIntermBlock *bodyNode = node->getBody();
|
TIntermAggregate *lastNode = node->getSequence()->back()->getAsAggregate();
|
||||||
TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode();
|
if (lastNode == nullptr)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TIntermBranch *returnNode = lastNode->getSequence()->front()->getAsBranchNode();
|
||||||
if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
|
if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -49,16 +54,51 @@ class AddDefaultReturnStatementsTraverser : private TIntermTraverser
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool visitFunctionDefinition(Visit, TIntermFunctionDefinition *node) override
|
static TIntermTyped *GenerateTypeConstructor(const TType &returnType)
|
||||||
|
{
|
||||||
|
// Base case, constructing a single element
|
||||||
|
if (!returnType.isArray())
|
||||||
|
{
|
||||||
|
size_t objectSize = returnType.getObjectSize();
|
||||||
|
TConstantUnion *constantUnion = new TConstantUnion[objectSize];
|
||||||
|
for (size_t constantIdx = 0; constantIdx < objectSize; constantIdx++)
|
||||||
|
{
|
||||||
|
constantUnion[constantIdx].setFConst(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TIntermConstantUnion *intermConstantUnion =
|
||||||
|
new TIntermConstantUnion(constantUnion, returnType);
|
||||||
|
return intermConstantUnion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursive case, construct an array of single elements
|
||||||
|
TIntermAggregate *constructorAggrigate =
|
||||||
|
new TIntermAggregate(TypeToConstructorOperator(returnType));
|
||||||
|
constructorAggrigate->setType(returnType);
|
||||||
|
|
||||||
|
size_t arraySize = returnType.getArraySize();
|
||||||
|
for (size_t arrayIdx = 0; arrayIdx < arraySize; arrayIdx++)
|
||||||
|
{
|
||||||
|
TType arrayElementType(returnType);
|
||||||
|
arrayElementType.clearArrayness();
|
||||||
|
|
||||||
|
constructorAggrigate->getSequence()->push_back(
|
||||||
|
GenerateTypeConstructor(arrayElementType));
|
||||||
|
}
|
||||||
|
|
||||||
|
return constructorAggrigate;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool visitAggregate(Visit, TIntermAggregate *node) override
|
||||||
{
|
{
|
||||||
TType returnType;
|
TType returnType;
|
||||||
if (IsFunctionWithoutReturnStatement(node, &returnType))
|
if (IsFunctionWithoutReturnStatement(node, &returnType))
|
||||||
{
|
{
|
||||||
TIntermBranch *branch =
|
TIntermBranch *branch =
|
||||||
new TIntermBranch(EOpReturn, TIntermTyped::CreateZero(returnType));
|
new TIntermBranch(EOpReturn, GenerateTypeConstructor(returnType));
|
||||||
|
|
||||||
TIntermBlock *bodyNode = node->getBody();
|
TIntermAggregate *lastNode = node->getSequence()->back()->getAsAggregate();
|
||||||
bodyNode->getSequence()->push_back(branch);
|
lastNode->getSequence()->push_back(branch);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,6 @@
|
||||||
|
|
||||||
#include "compiler/translator/IntermNode.h"
|
#include "compiler/translator/IntermNode.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -44,7 +41,8 @@ TIntermAggregate *CreateReplacementCall(TIntermAggregate *originalCall, TIntermT
|
||||||
TIntermAggregate *replacementCall = new TIntermAggregate(EOpFunctionCall);
|
TIntermAggregate *replacementCall = new TIntermAggregate(EOpFunctionCall);
|
||||||
replacementCall->setType(TType(EbtVoid));
|
replacementCall->setType(TType(EbtVoid));
|
||||||
replacementCall->setUserDefined();
|
replacementCall->setUserDefined();
|
||||||
*replacementCall->getFunctionSymbolInfo() = *originalCall->getFunctionSymbolInfo();
|
replacementCall->setNameObj(originalCall->getNameObj());
|
||||||
|
replacementCall->setFunctionId(originalCall->getFunctionId());
|
||||||
replacementCall->setLine(originalCall->getLine());
|
replacementCall->setLine(originalCall->getLine());
|
||||||
TIntermSequence *replacementParameters = replacementCall->getSequence();
|
TIntermSequence *replacementParameters = replacementCall->getSequence();
|
||||||
TIntermSequence *originalParameters = originalCall->getSequence();
|
TIntermSequence *originalParameters = originalCall->getSequence();
|
||||||
|
|
@ -63,7 +61,6 @@ class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser
|
||||||
private:
|
private:
|
||||||
ArrayReturnValueToOutParameterTraverser();
|
ArrayReturnValueToOutParameterTraverser();
|
||||||
|
|
||||||
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
|
|
||||||
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
|
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
|
||||||
bool visitBranch(Visit visit, TIntermBranch *node) override;
|
bool visitBranch(Visit visit, TIntermBranch *node) override;
|
||||||
bool visitBinary(Visit visit, TIntermBinary *node) override;
|
bool visitBinary(Visit visit, TIntermBinary *node) override;
|
||||||
|
|
@ -85,47 +82,35 @@ ArrayReturnValueToOutParameterTraverser::ArrayReturnValueToOutParameterTraverser
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArrayReturnValueToOutParameterTraverser::visitFunctionDefinition(
|
|
||||||
Visit visit,
|
|
||||||
TIntermFunctionDefinition *node)
|
|
||||||
{
|
|
||||||
if (node->isArray() && visit == PreVisit)
|
|
||||||
{
|
|
||||||
// Replace the parameters child node of the function definition with another node
|
|
||||||
// that has the out parameter added.
|
|
||||||
// Also set the function to return void.
|
|
||||||
|
|
||||||
TIntermAggregate *params = node->getFunctionParameters();
|
|
||||||
ASSERT(params != nullptr && params->getOp() == EOpParameters);
|
|
||||||
|
|
||||||
TIntermAggregate *replacementParams = new TIntermAggregate;
|
|
||||||
replacementParams->setOp(EOpParameters);
|
|
||||||
CopyAggregateChildren(params, replacementParams);
|
|
||||||
replacementParams->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
|
|
||||||
replacementParams->setLine(params->getLine());
|
|
||||||
|
|
||||||
queueReplacementWithParent(node, params, replacementParams, OriginalNode::IS_DROPPED);
|
|
||||||
|
|
||||||
node->setType(TType(EbtVoid));
|
|
||||||
|
|
||||||
mInFunctionWithArrayReturnValue = true;
|
|
||||||
}
|
|
||||||
if (visit == PostVisit)
|
|
||||||
{
|
|
||||||
// This isn't conditional on node->isArray() since the type has already been changed on
|
|
||||||
// PreVisit.
|
|
||||||
mInFunctionWithArrayReturnValue = false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||||
{
|
{
|
||||||
if (visit == PreVisit)
|
if (visit == PreVisit)
|
||||||
{
|
{
|
||||||
if (node->isArray())
|
if (node->isArray())
|
||||||
{
|
{
|
||||||
if (node->getOp() == EOpPrototype)
|
if (node->getOp() == EOpFunction)
|
||||||
|
{
|
||||||
|
// Replace the parameters child node of the function definition with another node
|
||||||
|
// that has the out parameter added.
|
||||||
|
// Also set the function to return void.
|
||||||
|
|
||||||
|
TIntermAggregate *params = node->getSequence()->front()->getAsAggregate();
|
||||||
|
ASSERT(params != nullptr && params->getOp() == EOpParameters);
|
||||||
|
|
||||||
|
TIntermAggregate *replacementParams = new TIntermAggregate;
|
||||||
|
replacementParams->setOp(EOpParameters);
|
||||||
|
CopyAggregateChildren(params, replacementParams);
|
||||||
|
replacementParams->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
|
||||||
|
replacementParams->setLine(params->getLine());
|
||||||
|
|
||||||
|
queueReplacementWithParent(node, params, replacementParams,
|
||||||
|
OriginalNode::IS_DROPPED);
|
||||||
|
|
||||||
|
node->setType(TType(EbtVoid));
|
||||||
|
|
||||||
|
mInFunctionWithArrayReturnValue = true;
|
||||||
|
}
|
||||||
|
else if (node->getOp() == EOpPrototype)
|
||||||
{
|
{
|
||||||
// Replace the whole prototype node with another node that has the out parameter added.
|
// Replace the whole prototype node with another node that has the out parameter added.
|
||||||
TIntermAggregate *replacement = new TIntermAggregate;
|
TIntermAggregate *replacement = new TIntermAggregate;
|
||||||
|
|
@ -133,7 +118,8 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter
|
||||||
CopyAggregateChildren(node, replacement);
|
CopyAggregateChildren(node, replacement);
|
||||||
replacement->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
|
replacement->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
|
||||||
replacement->setUserDefined();
|
replacement->setUserDefined();
|
||||||
*replacement->getFunctionSymbolInfo() = *node->getFunctionSymbolInfo();
|
replacement->setNameObj(node->getNameObj());
|
||||||
|
replacement->setFunctionId(node->getFunctionId());
|
||||||
replacement->setLine(node->getLine());
|
replacement->setLine(node->getLine());
|
||||||
replacement->setType(TType(EbtVoid));
|
replacement->setType(TType(EbtVoid));
|
||||||
|
|
||||||
|
|
@ -150,21 +136,27 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter
|
||||||
// Cases 2 to 4 are already converted to simpler cases by SeparateExpressionsReturningArrays, so we
|
// Cases 2 to 4 are already converted to simpler cases by SeparateExpressionsReturningArrays, so we
|
||||||
// only need to worry about the case where a function call returning an array forms an expression by
|
// only need to worry about the case where a function call returning an array forms an expression by
|
||||||
// itself.
|
// itself.
|
||||||
TIntermBlock *parentBlock = getParentNode()->getAsBlock();
|
TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
|
||||||
if (parentBlock)
|
if (parentAgg != nullptr && parentAgg->getOp() == EOpSequence)
|
||||||
{
|
{
|
||||||
nextTemporaryIndex();
|
nextTemporaryIndex();
|
||||||
TIntermSequence replacements;
|
TIntermSequence replacements;
|
||||||
replacements.push_back(createTempDeclaration(node->getType()));
|
replacements.push_back(createTempDeclaration(node->getType()));
|
||||||
TIntermSymbol *returnSymbol = createTempSymbol(node->getType());
|
TIntermSymbol *returnSymbol = createTempSymbol(node->getType());
|
||||||
replacements.push_back(CreateReplacementCall(node, returnSymbol));
|
replacements.push_back(CreateReplacementCall(node, returnSymbol));
|
||||||
mMultiReplacements.push_back(
|
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacements));
|
||||||
NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (visit == PostVisit)
|
||||||
|
{
|
||||||
|
if (node->getOp() == EOpFunction)
|
||||||
|
{
|
||||||
|
mInFunctionWithArrayReturnValue = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,11 +167,12 @@ bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBr
|
||||||
// Instead of returning a value, assign to the out parameter and then return.
|
// Instead of returning a value, assign to the out parameter and then return.
|
||||||
TIntermSequence replacements;
|
TIntermSequence replacements;
|
||||||
|
|
||||||
|
TIntermBinary *replacementAssignment = new TIntermBinary(EOpAssign);
|
||||||
TIntermTyped *expression = node->getExpression();
|
TIntermTyped *expression = node->getExpression();
|
||||||
ASSERT(expression != nullptr);
|
ASSERT(expression != nullptr);
|
||||||
TIntermSymbol *returnValueSymbol = CreateReturnValueSymbol(expression->getType());
|
replacementAssignment->setLeft(CreateReturnValueSymbol(expression->getType()));
|
||||||
TIntermBinary *replacementAssignment =
|
replacementAssignment->setRight(node->getExpression());
|
||||||
new TIntermBinary(EOpAssign, returnValueSymbol, expression);
|
replacementAssignment->setType(expression->getType());
|
||||||
replacementAssignment->setLine(expression->getLine());
|
replacementAssignment->setLine(expression->getLine());
|
||||||
replacements.push_back(replacementAssignment);
|
replacements.push_back(replacementAssignment);
|
||||||
|
|
||||||
|
|
@ -187,8 +180,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBr
|
||||||
replacementBranch->setLine(node->getLine());
|
replacementBranch->setLine(node->getLine());
|
||||||
replacements.push_back(replacementBranch);
|
replacements.push_back(replacementBranch);
|
||||||
|
|
||||||
mMultiReplacements.push_back(
|
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsAggregate(), node, replacements));
|
||||||
NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, replacements));
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -213,5 +205,3 @@ void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIn
|
||||||
{
|
{
|
||||||
ArrayReturnValueToOutParameterTraverser::apply(root, temporaryIndex);
|
ArrayReturnValueToOutParameterTraverser::apply(root, temporaryIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,8 @@
|
||||||
#ifndef COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
|
#ifndef COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
|
||||||
#define COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
|
#define COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
class TIntermNode;
|
class TIntermNode;
|
||||||
|
|
||||||
void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIndex);
|
void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIndex);
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
|
#endif // COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,6 @@
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "GLSLANG/ShaderLang.h"
|
#include "GLSLANG/ShaderLang.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Precision qualifiers
|
// Precision qualifiers
|
||||||
//
|
//
|
||||||
|
|
@ -35,10 +32,10 @@ inline const char* getPrecisionString(TPrecision p)
|
||||||
{
|
{
|
||||||
switch(p)
|
switch(p)
|
||||||
{
|
{
|
||||||
case EbpHigh: return "highp";
|
case EbpHigh: return "highp"; break;
|
||||||
case EbpMedium: return "mediump";
|
case EbpMedium: return "mediump"; break;
|
||||||
case EbpLow: return "lowp";
|
case EbpLow: return "lowp"; break;
|
||||||
default: return "mediump"; // Safest fallback
|
default: return "mediump"; break; // Safest fallback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,98 +76,19 @@ enum TBasicType
|
||||||
EbtSampler2DShadow,
|
EbtSampler2DShadow,
|
||||||
EbtSamplerCubeShadow,
|
EbtSamplerCubeShadow,
|
||||||
EbtSampler2DArrayShadow,
|
EbtSampler2DArrayShadow,
|
||||||
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
|
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
|
||||||
EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
|
EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
|
||||||
EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
|
EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
|
||||||
EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
|
EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
|
||||||
EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and
|
EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray
|
||||||
// usampler2DArray
|
|
||||||
|
|
||||||
// images
|
|
||||||
EbtGuardImageBegin,
|
|
||||||
EbtImage2D,
|
|
||||||
EbtIImage2D,
|
|
||||||
EbtUImage2D,
|
|
||||||
EbtImage3D,
|
|
||||||
EbtIImage3D,
|
|
||||||
EbtUImage3D,
|
|
||||||
EbtImage2DArray,
|
|
||||||
EbtIImage2DArray,
|
|
||||||
EbtUImage2DArray,
|
|
||||||
EbtImageCube,
|
|
||||||
EbtIImageCube,
|
|
||||||
EbtUImageCube,
|
|
||||||
EbtGuardImageEnd,
|
|
||||||
|
|
||||||
EbtGuardGImageBegin,
|
|
||||||
EbtGImage2D, // non type: represents image2D, uimage2D, iimage2D
|
|
||||||
EbtGImage3D, // non type: represents image3D, uimage3D, iimage3D
|
|
||||||
EbtGImage2DArray, // non type: represents image2DArray, uimage2DArray, iimage2DArray
|
|
||||||
EbtGImageCube, // non type: represents imageCube, uimageCube, iimageCube
|
|
||||||
EbtGuardGImageEnd,
|
|
||||||
|
|
||||||
EbtStruct,
|
EbtStruct,
|
||||||
EbtInterfaceBlock,
|
EbtInterfaceBlock,
|
||||||
EbtAddress, // should be deprecated??
|
EbtAddress, // should be deprecated??
|
||||||
|
|
||||||
// end of list
|
// end of list
|
||||||
EbtLast
|
EbtLast
|
||||||
};
|
};
|
||||||
|
|
||||||
inline TBasicType convertGImageToFloatImage(TBasicType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtGImage2D:
|
|
||||||
return EbtImage2D;
|
|
||||||
case EbtGImage3D:
|
|
||||||
return EbtImage3D;
|
|
||||||
case EbtGImage2DArray:
|
|
||||||
return EbtImage2DArray;
|
|
||||||
case EbtGImageCube:
|
|
||||||
return EbtImageCube;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
return EbtLast;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline TBasicType convertGImageToIntImage(TBasicType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtGImage2D:
|
|
||||||
return EbtIImage2D;
|
|
||||||
case EbtGImage3D:
|
|
||||||
return EbtIImage3D;
|
|
||||||
case EbtGImage2DArray:
|
|
||||||
return EbtIImage2DArray;
|
|
||||||
case EbtGImageCube:
|
|
||||||
return EbtIImageCube;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
return EbtLast;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline TBasicType convertGImageToUnsignedImage(TBasicType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtGImage2D:
|
|
||||||
return EbtUImage2D;
|
|
||||||
case EbtGImage3D:
|
|
||||||
return EbtUImage3D;
|
|
||||||
case EbtGImage2DArray:
|
|
||||||
return EbtUImage2DArray;
|
|
||||||
case EbtGImageCube:
|
|
||||||
return EbtUImageCube;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
return EbtLast;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* getBasicString(TBasicType t);
|
const char* getBasicString(TBasicType t);
|
||||||
|
|
||||||
inline bool IsSampler(TBasicType type)
|
inline bool IsSampler(TBasicType type)
|
||||||
|
|
@ -178,22 +96,6 @@ inline bool IsSampler(TBasicType type)
|
||||||
return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
|
return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsImage(TBasicType type)
|
|
||||||
{
|
|
||||||
return type > EbtGuardImageBegin && type < EbtGuardImageEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsGImage(TBasicType type)
|
|
||||||
{
|
|
||||||
return type > EbtGuardGImageBegin && type < EbtGuardGImageEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsOpaqueType(TBasicType type)
|
|
||||||
{
|
|
||||||
// TODO (mradev): add atomic types as opaque.
|
|
||||||
return IsSampler(type) || IsImage(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsIntegerSampler(TBasicType type)
|
inline bool IsIntegerSampler(TBasicType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
|
@ -224,56 +126,6 @@ inline bool IsIntegerSampler(TBasicType type)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsFloatImage(TBasicType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtImage2D:
|
|
||||||
case EbtImage3D:
|
|
||||||
case EbtImage2DArray:
|
|
||||||
case EbtImageCube:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsIntegerImage(TBasicType type)
|
|
||||||
{
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtIImage2D:
|
|
||||||
case EbtIImage3D:
|
|
||||||
case EbtIImage2DArray:
|
|
||||||
case EbtIImageCube:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsUnsignedImage(TBasicType type)
|
|
||||||
{
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtUImage2D:
|
|
||||||
case EbtUImage3D:
|
|
||||||
case EbtUImage2DArray:
|
|
||||||
case EbtUImageCube:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsSampler2D(TBasicType type)
|
inline bool IsSampler2D(TBasicType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
|
@ -431,7 +283,7 @@ inline bool IsInteger(TBasicType type)
|
||||||
|
|
||||||
inline bool SupportsPrecision(TBasicType type)
|
inline bool SupportsPrecision(TBasicType type)
|
||||||
{
|
{
|
||||||
return type == EbtFloat || type == EbtInt || type == EbtUInt || IsOpaqueType(type);
|
return type == EbtFloat || type == EbtInt || type == EbtUInt || IsSampler(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -489,11 +341,10 @@ enum TQualifier
|
||||||
EvqLastFragData,
|
EvqLastFragData,
|
||||||
|
|
||||||
// GLSL ES 3.0 vertex output and fragment input
|
// GLSL ES 3.0 vertex output and fragment input
|
||||||
EvqSmooth, // Incomplete qualifier, smooth is the default
|
EvqSmooth, // Incomplete qualifier, smooth is the default
|
||||||
EvqFlat, // Incomplete qualifier
|
EvqFlat, // Incomplete qualifier
|
||||||
EvqCentroid, // Incomplete qualifier
|
EvqSmoothOut = EvqSmooth,
|
||||||
EvqSmoothOut,
|
EvqFlatOut = EvqFlat,
|
||||||
EvqFlatOut,
|
|
||||||
EvqCentroidOut, // Implies smooth
|
EvqCentroidOut, // Implies smooth
|
||||||
EvqSmoothIn,
|
EvqSmoothIn,
|
||||||
EvqFlatIn,
|
EvqFlatIn,
|
||||||
|
|
@ -508,40 +359,10 @@ enum TQualifier
|
||||||
EvqGlobalInvocationID,
|
EvqGlobalInvocationID,
|
||||||
EvqLocalInvocationIndex,
|
EvqLocalInvocationIndex,
|
||||||
|
|
||||||
// GLSL ES 3.1 memory qualifiers
|
|
||||||
EvqReadOnly,
|
|
||||||
EvqWriteOnly,
|
|
||||||
EvqCoherent,
|
|
||||||
EvqRestrict,
|
|
||||||
EvqVolatile,
|
|
||||||
|
|
||||||
// end of list
|
// end of list
|
||||||
EvqLast
|
EvqLast
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool IsQualifierUnspecified(TQualifier qualifier)
|
|
||||||
{
|
|
||||||
return (qualifier == EvqTemporary || qualifier == EvqGlobal);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum TLayoutImageInternalFormat
|
|
||||||
{
|
|
||||||
EiifUnspecified,
|
|
||||||
EiifRGBA32F,
|
|
||||||
EiifRGBA16F,
|
|
||||||
EiifR32F,
|
|
||||||
EiifRGBA32UI,
|
|
||||||
EiifRGBA16UI,
|
|
||||||
EiifRGBA8UI,
|
|
||||||
EiifR32UI,
|
|
||||||
EiifRGBA32I,
|
|
||||||
EiifRGBA16I,
|
|
||||||
EiifRGBA8I,
|
|
||||||
EiifR32I,
|
|
||||||
EiifRGBA8,
|
|
||||||
EiifRGBA8_SNORM
|
|
||||||
};
|
|
||||||
|
|
||||||
enum TLayoutMatrixPacking
|
enum TLayoutMatrixPacking
|
||||||
{
|
{
|
||||||
EmpUnspecified,
|
EmpUnspecified,
|
||||||
|
|
@ -560,44 +381,36 @@ enum TLayoutBlockStorage
|
||||||
struct TLayoutQualifier
|
struct TLayoutQualifier
|
||||||
{
|
{
|
||||||
int location;
|
int location;
|
||||||
unsigned int locationsSpecified;
|
|
||||||
TLayoutMatrixPacking matrixPacking;
|
TLayoutMatrixPacking matrixPacking;
|
||||||
TLayoutBlockStorage blockStorage;
|
TLayoutBlockStorage blockStorage;
|
||||||
|
|
||||||
// Compute shader layout qualifiers.
|
// Compute shader layout qualifiers.
|
||||||
sh::WorkGroupSize localSize;
|
sh::WorkGroupSize localSize;
|
||||||
|
|
||||||
// Image format layout qualifier
|
|
||||||
TLayoutImageInternalFormat imageInternalFormat;
|
|
||||||
|
|
||||||
static TLayoutQualifier create()
|
static TLayoutQualifier create()
|
||||||
{
|
{
|
||||||
TLayoutQualifier layoutQualifier;
|
TLayoutQualifier layoutQualifier;
|
||||||
|
|
||||||
layoutQualifier.location = -1;
|
layoutQualifier.location = -1;
|
||||||
layoutQualifier.locationsSpecified = 0;
|
|
||||||
layoutQualifier.matrixPacking = EmpUnspecified;
|
layoutQualifier.matrixPacking = EmpUnspecified;
|
||||||
layoutQualifier.blockStorage = EbsUnspecified;
|
layoutQualifier.blockStorage = EbsUnspecified;
|
||||||
|
|
||||||
layoutQualifier.localSize.fill(-1);
|
layoutQualifier.localSize.fill(-1);
|
||||||
|
|
||||||
layoutQualifier.imageInternalFormat = EiifUnspecified;
|
|
||||||
return layoutQualifier;
|
return layoutQualifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isEmpty() const
|
bool isEmpty() const
|
||||||
{
|
{
|
||||||
return location == -1 && matrixPacking == EmpUnspecified &&
|
return location == -1 && matrixPacking == EmpUnspecified &&
|
||||||
blockStorage == EbsUnspecified && !localSize.isAnyValueSet() &&
|
blockStorage == EbsUnspecified && !localSize.isAnyValueSet();
|
||||||
imageInternalFormat == EiifUnspecified;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isCombinationValid() const
|
bool isCombinationValid() const
|
||||||
{
|
{
|
||||||
bool workSizeSpecified = localSize.isAnyValueSet();
|
bool workSizeSpecified = localSize.isAnyValueSet();
|
||||||
bool otherLayoutQualifiersSpecified =
|
bool otherLayoutQualifiersSpecified =
|
||||||
(location != -1 || matrixPacking != EmpUnspecified || blockStorage != EbsUnspecified ||
|
(location != -1 || matrixPacking != EmpUnspecified || blockStorage != EbsUnspecified);
|
||||||
imageInternalFormat != EiifUnspecified);
|
|
||||||
|
|
||||||
// we can have either the work group size specified, or the other layout qualifiers
|
// we can have either the work group size specified, or the other layout qualifiers
|
||||||
return !(workSizeSpecified && otherLayoutQualifiersSpecified);
|
return !(workSizeSpecified && otherLayoutQualifiersSpecified);
|
||||||
|
|
@ -609,37 +422,6 @@ struct TLayoutQualifier
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TMemoryQualifier
|
|
||||||
{
|
|
||||||
// GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
|
|
||||||
// An image can be qualified as both readonly and writeonly. It still can be can be used with
|
|
||||||
// imageSize().
|
|
||||||
bool readonly;
|
|
||||||
bool writeonly;
|
|
||||||
bool coherent;
|
|
||||||
|
|
||||||
// restrict and volatile are reserved keywords in C/C++
|
|
||||||
bool restrictQualifier;
|
|
||||||
bool volatileQualifier;
|
|
||||||
static TMemoryQualifier create()
|
|
||||||
{
|
|
||||||
TMemoryQualifier memoryQualifier;
|
|
||||||
|
|
||||||
memoryQualifier.readonly = false;
|
|
||||||
memoryQualifier.writeonly = false;
|
|
||||||
memoryQualifier.coherent = false;
|
|
||||||
memoryQualifier.restrictQualifier = false;
|
|
||||||
memoryQualifier.volatileQualifier = false;
|
|
||||||
|
|
||||||
return memoryQualifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isEmpty()
|
|
||||||
{
|
|
||||||
return !readonly && !writeonly && !coherent && !restrictQualifier && !volatileQualifier;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline const char *getWorkGroupSizeString(size_t dimension)
|
inline const char *getWorkGroupSizeString(size_t dimension)
|
||||||
{
|
{
|
||||||
switch (dimension)
|
switch (dimension)
|
||||||
|
|
@ -700,9 +482,6 @@ inline const char* getQualifierString(TQualifier q)
|
||||||
case EvqSmoothIn: return "smooth in";
|
case EvqSmoothIn: return "smooth in";
|
||||||
case EvqFlatIn: return "flat in";
|
case EvqFlatIn: return "flat in";
|
||||||
case EvqCentroidIn: return "smooth centroid in";
|
case EvqCentroidIn: return "smooth centroid in";
|
||||||
case EvqCentroid: return "centroid";
|
|
||||||
case EvqFlat: return "flat";
|
|
||||||
case EvqSmooth: return "smooth";
|
|
||||||
case EvqComputeIn: return "in";
|
case EvqComputeIn: return "in";
|
||||||
case EvqNumWorkGroups: return "NumWorkGroups";
|
case EvqNumWorkGroups: return "NumWorkGroups";
|
||||||
case EvqWorkGroupSize: return "WorkGroupSize";
|
case EvqWorkGroupSize: return "WorkGroupSize";
|
||||||
|
|
@ -710,8 +489,6 @@ inline const char* getQualifierString(TQualifier q)
|
||||||
case EvqLocalInvocationID: return "LocalInvocationID";
|
case EvqLocalInvocationID: return "LocalInvocationID";
|
||||||
case EvqGlobalInvocationID: return "GlobalInvocationID";
|
case EvqGlobalInvocationID: return "GlobalInvocationID";
|
||||||
case EvqLocalInvocationIndex: return "LocalInvocationIndex";
|
case EvqLocalInvocationIndex: return "LocalInvocationIndex";
|
||||||
case EvqReadOnly: return "readonly";
|
|
||||||
case EvqWriteOnly: return "writeonly";
|
|
||||||
default: UNREACHABLE(); return "unknown qualifier";
|
default: UNREACHABLE(); return "unknown qualifier";
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
@ -740,42 +517,18 @@ inline const char* getBlockStorageString(TLayoutBlockStorage bsq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char *getImageInternalFormatString(TLayoutImageInternalFormat iifq)
|
inline const char* getInterpolationString(TQualifier q)
|
||||||
{
|
{
|
||||||
switch (iifq)
|
switch(q)
|
||||||
{
|
{
|
||||||
case EiifRGBA32F:
|
case EvqSmoothOut: return "smooth"; break;
|
||||||
return "rgba32f";
|
case EvqCentroidOut: return "smooth centroid"; break;
|
||||||
case EiifRGBA16F:
|
case EvqFlatOut: return "flat"; break;
|
||||||
return "rgba16f";
|
case EvqSmoothIn: return "smooth"; break;
|
||||||
case EiifR32F:
|
case EvqCentroidIn: return "smooth centroid"; break;
|
||||||
return "r32f";
|
case EvqFlatIn: return "flat"; break;
|
||||||
case EiifRGBA32UI:
|
default: UNREACHABLE(); return "unknown interpolation";
|
||||||
return "rgba32ui";
|
|
||||||
case EiifRGBA16UI:
|
|
||||||
return "rgba16ui";
|
|
||||||
case EiifRGBA8UI:
|
|
||||||
return "rgba8ui";
|
|
||||||
case EiifR32UI:
|
|
||||||
return "r32ui";
|
|
||||||
case EiifRGBA32I:
|
|
||||||
return "rgba32i";
|
|
||||||
case EiifRGBA16I:
|
|
||||||
return "rgba16i";
|
|
||||||
case EiifRGBA8I:
|
|
||||||
return "rgba8i";
|
|
||||||
case EiifR32I:
|
|
||||||
return "r32i";
|
|
||||||
case EiifRGBA8:
|
|
||||||
return "rgba8";
|
|
||||||
case EiifRGBA8_SNORM:
|
|
||||||
return "rgba8_snorm";
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
return "unknown internal image format";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_BASETYPES_H_
|
#endif // COMPILER_TRANSLATOR_BASETYPES_H_
|
||||||
|
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2016 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.
|
|
||||||
//
|
|
||||||
|
|
||||||
// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend
|
|
||||||
// may record a variable as aliasing another. Sometimes the alias information gets garbled
|
|
||||||
// so we work around this issue by breaking the aliasing chain in inner loops.
|
|
||||||
|
|
||||||
#include "BreakVariableAliasingInInnerLoops.h"
|
|
||||||
|
|
||||||
#include "compiler/translator/IntermNode.h"
|
|
||||||
|
|
||||||
// A HLSL compiler developer gave us more details on the root cause and the workaround needed:
|
|
||||||
// The root problem is that if the HLSL compiler is applying aliasing information even on
|
|
||||||
// incomplete simulations (in this case, a single pass). The bug is triggered by an assignment
|
|
||||||
// that comes from a series of assignments, possibly with swizzled or ternary operators with
|
|
||||||
// known conditionals, where the source is before the loop.
|
|
||||||
// So, a workaround is to add a +0 term to variables the first time they are assigned to in
|
|
||||||
// an inner loop (if they are declared in an outside scope, otherwise there is no need).
|
|
||||||
// This will break the aliasing chain.
|
|
||||||
|
|
||||||
// For simplicity here we add a +0 to any assignment that is in at least two nested loops. Because
|
|
||||||
// the bug only shows up with swizzles, and ternary assignment, whole array or whole structure
|
|
||||||
// assignment don't need a workaround.
|
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
class AliasingBreaker : public TIntermTraverser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AliasingBreaker() : TIntermTraverser(true, false, true) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool visitBinary(Visit visit, TIntermBinary *binary)
|
|
||||||
{
|
|
||||||
if (visit != PreVisit)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mLoopLevel < 2 || !binary->isAssignment())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TIntermTyped *B = binary->getRight();
|
|
||||||
TType type = B->getType();
|
|
||||||
|
|
||||||
if (!type.isScalar() && !type.isVector() && !type.isMatrix())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.isArray() || IsSampler(type.getBasicType()))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have a scalar / vector / matrix assignment with loop depth 2.
|
|
||||||
// Transform it from
|
|
||||||
// A = B
|
|
||||||
// to
|
|
||||||
// A = (B + typeof<B>(0));
|
|
||||||
|
|
||||||
TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, TIntermTyped::CreateZero(type));
|
|
||||||
bPlusZero->setLine(B->getLine());
|
|
||||||
|
|
||||||
binary->replaceChildNode(B, bPlusZero);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool visitLoop(Visit visit, TIntermLoop *loop)
|
|
||||||
{
|
|
||||||
if (visit == PreVisit)
|
|
||||||
{
|
|
||||||
mLoopLevel++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ASSERT(mLoopLevel > 0);
|
|
||||||
mLoopLevel--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int mLoopLevel = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
void BreakVariableAliasingInInnerLoops(TIntermNode *root)
|
|
||||||
{
|
|
||||||
AliasingBreaker breaker;
|
|
||||||
root->traverse(&breaker);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright (c) 2016 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.
|
|
||||||
//
|
|
||||||
|
|
||||||
// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend
|
|
||||||
// may record a variable as aliasing another. Sometimes the alias information gets garbled
|
|
||||||
// so we work around this issue by breaking the aliasing chain in inner loops.
|
|
||||||
|
|
||||||
#ifndef COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
|
|
||||||
#define COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
|
|
||||||
|
|
||||||
class TIntermNode;
|
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
void BreakVariableAliasingInInnerLoops(TIntermNode *root);
|
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
|
|
||||||
|
|
@ -9,9 +9,6 @@
|
||||||
#include "compiler/translator/SymbolTable.h"
|
#include "compiler/translator/SymbolTable.h"
|
||||||
#include "compiler/translator/Cache.h"
|
#include "compiler/translator/Cache.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
|
class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -245,5 +242,3 @@ BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::FunctionId::getCopy
|
||||||
{
|
{
|
||||||
return FunctionId(mOp, new TType(*mParam1), new TType(*mParam2), new TType(*mParam3));
|
return FunctionId(mOp, new TType(*mParam1), new TType(*mParam2), new TType(*mParam3));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,6 @@
|
||||||
#include "compiler/translator/InfoSink.h"
|
#include "compiler/translator/InfoSink.h"
|
||||||
#include "compiler/translator/IntermNode.h"
|
#include "compiler/translator/IntermNode.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// This class decides which built-in functions need to be replaced with the
|
// This class decides which built-in functions need to be replaced with the
|
||||||
// emulated ones.
|
// emulated ones.
|
||||||
|
|
@ -85,6 +82,4 @@ class BuiltInFunctionEmulator
|
||||||
std::vector<FunctionId> mFunctions;
|
std::vector<FunctionId> mFunctions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
|
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
|
||||||
|
|
|
||||||
|
|
@ -11,68 +11,32 @@
|
||||||
#include "compiler/translator/SymbolTable.h"
|
#include "compiler/translator/SymbolTable.h"
|
||||||
#include "compiler/translator/VersionGLSL.h"
|
#include "compiler/translator/VersionGLSL.h"
|
||||||
|
|
||||||
namespace sh
|
void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType)
|
||||||
{
|
{
|
||||||
|
// we use macros here instead of function definitions to work around more GLSL
|
||||||
void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
|
// compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are
|
||||||
sh::GLenum shaderType)
|
// problematic because if the argument has side-effects they will be repeatedly
|
||||||
{
|
// evaluated. This is unlikely to show up in real shaders, but is something to
|
||||||
if (shaderType == GL_VERTEX_SHADER)
|
// consider.
|
||||||
{
|
|
||||||
const TType *int1 = TCache::getType(EbtInt);
|
|
||||||
emu->addEmulatedFunction(EOpAbs, int1, "int webgl_abs_emu(int x) { return x * sign(x); }");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
|
|
||||||
int targetGLSLVersion)
|
|
||||||
{
|
|
||||||
// isnan() is supported since GLSL 1.3.
|
|
||||||
if (targetGLSLVersion < GLSL_VERSION_130)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const TType *float1 = TCache::getType(EbtFloat);
|
const TType *float1 = TCache::getType(EbtFloat);
|
||||||
const TType *float2 = TCache::getType(EbtFloat, 2);
|
const TType *float2 = TCache::getType(EbtFloat, 2);
|
||||||
const TType *float3 = TCache::getType(EbtFloat, 3);
|
const TType *float3 = TCache::getType(EbtFloat, 3);
|
||||||
const TType *float4 = TCache::getType(EbtFloat, 4);
|
const TType *float4 = TCache::getType(EbtFloat, 4);
|
||||||
|
|
||||||
// !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false.
|
if (shaderType == GL_FRAGMENT_SHADER)
|
||||||
emu->addEmulatedFunction(
|
{
|
||||||
EOpIsNan, float1,
|
emu->addEmulatedFunction(EOpCos, float1, "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }");
|
||||||
"bool webgl_isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
|
emu->addEmulatedFunction(EOpCos, float2, "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }");
|
||||||
emu->addEmulatedFunction(
|
emu->addEmulatedFunction(EOpCos, float3, "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }");
|
||||||
EOpIsNan, float2,
|
emu->addEmulatedFunction(EOpCos, float4, "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }");
|
||||||
"bvec2 webgl_isnan_emu(vec2 x)\n"
|
}
|
||||||
"{\n"
|
emu->addEmulatedFunction(EOpDistance, float1, float1, "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))");
|
||||||
" bvec2 isnan;\n"
|
emu->addEmulatedFunction(EOpDot, float1, float1, "#define webgl_dot_emu(x, y) ((x) * (y))");
|
||||||
" for (int i = 0; i < 2; i++)\n"
|
emu->addEmulatedFunction(EOpLength, float1, "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))");
|
||||||
" {\n"
|
emu->addEmulatedFunction(EOpNormalize, float1, "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))");
|
||||||
" isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
|
emu->addEmulatedFunction(EOpReflect, float1, float1, "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))");
|
||||||
" }\n"
|
emu->addEmulatedFunction(EOpFaceForward, float1, float1, float1, "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))");
|
||||||
" return isnan;\n"
|
|
||||||
"}\n");
|
|
||||||
emu->addEmulatedFunction(
|
|
||||||
EOpIsNan, float3,
|
|
||||||
"bvec3 webgl_isnan_emu(vec3 x)\n"
|
|
||||||
"{\n"
|
|
||||||
" bvec3 isnan;\n"
|
|
||||||
" for (int i = 0; i < 3; i++)\n"
|
|
||||||
" {\n"
|
|
||||||
" isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
|
|
||||||
" }\n"
|
|
||||||
" return isnan;\n"
|
|
||||||
"}\n");
|
|
||||||
emu->addEmulatedFunction(
|
|
||||||
EOpIsNan, float4,
|
|
||||||
"bvec4 webgl_isnan_emu(vec4 x)\n"
|
|
||||||
"{\n"
|
|
||||||
" bvec4 isnan;\n"
|
|
||||||
" for (int i = 0; i < 4; i++)\n"
|
|
||||||
" {\n"
|
|
||||||
" isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
|
|
||||||
" }\n"
|
|
||||||
" return isnan;\n"
|
|
||||||
"}\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emulate built-in functions missing from GLSL 1.30 and higher
|
// Emulate built-in functions missing from GLSL 1.30 and higher
|
||||||
|
|
@ -217,9 +181,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
|
||||||
" float scale;\n"
|
" float scale;\n"
|
||||||
" if(exponent < 0)\n"
|
" if(exponent < 0)\n"
|
||||||
" {\n"
|
" {\n"
|
||||||
" // The negative unary operator is buggy on OSX.\n"
|
" scale = 1.0 / (1 << -exponent);\n"
|
||||||
" // Work around this by using abs instead.\n"
|
|
||||||
" scale = 1.0 / (1 << abs(exponent));\n"
|
|
||||||
" }\n"
|
" }\n"
|
||||||
" else\n"
|
" else\n"
|
||||||
" {\n"
|
" {\n"
|
||||||
|
|
@ -251,5 +213,3 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -9,27 +9,17 @@
|
||||||
|
|
||||||
#include "GLSLANG/ShaderLang.h"
|
#include "GLSLANG/ShaderLang.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
class BuiltInFunctionEmulator;
|
class BuiltInFunctionEmulator;
|
||||||
|
|
||||||
//
|
//
|
||||||
// This works around bug in Intel Mac drivers.
|
// This is only a workaround for OpenGL driver bugs, and isn't needed in general.
|
||||||
//
|
//
|
||||||
void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
|
void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType);
|
||||||
sh::GLenum shaderType);
|
|
||||||
|
|
||||||
//
|
|
||||||
// This works around isnan() bug in Intel Mac drivers
|
|
||||||
//
|
|
||||||
void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
|
|
||||||
int targetGLSLVersion);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// This function is emulating built-in functions missing from GLSL 1.30 and higher.
|
// This function is emulating built-in functions missing from GLSL 1.30 and higher.
|
||||||
//
|
//
|
||||||
void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType,
|
void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType,
|
||||||
int targetGLSLVersion);
|
int targetGLSLVersion);
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
|
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
|
||||||
|
|
|
||||||
|
|
@ -8,62 +8,6 @@
|
||||||
#include "compiler/translator/BuiltInFunctionEmulator.h"
|
#include "compiler/translator/BuiltInFunctionEmulator.h"
|
||||||
#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
|
#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
|
||||||
#include "compiler/translator/SymbolTable.h"
|
#include "compiler/translator/SymbolTable.h"
|
||||||
#include "compiler/translator/VersionGLSL.h"
|
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
|
|
||||||
int targetGLSLVersion)
|
|
||||||
{
|
|
||||||
if (targetGLSLVersion < GLSL_VERSION_130)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TType *float1 = new TType(EbtFloat);
|
|
||||||
TType *float2 = new TType(EbtFloat, 2);
|
|
||||||
TType *float3 = new TType(EbtFloat, 3);
|
|
||||||
TType *float4 = new TType(EbtFloat, 4);
|
|
||||||
|
|
||||||
emu->addEmulatedFunction(EOpIsNan, float1,
|
|
||||||
"bool webgl_isnan_emu(float x)\n"
|
|
||||||
"{\n"
|
|
||||||
" return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n");
|
|
||||||
|
|
||||||
emu->addEmulatedFunction(EOpIsNan, float2,
|
|
||||||
"bool2 webgl_isnan_emu(float2 x)\n"
|
|
||||||
"{\n"
|
|
||||||
" bool2 isnan;\n"
|
|
||||||
" for (int i = 0; i < 2; i++)\n"
|
|
||||||
" {\n"
|
|
||||||
" isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
|
|
||||||
" }\n"
|
|
||||||
" return isnan;\n"
|
|
||||||
"}\n");
|
|
||||||
|
|
||||||
emu->addEmulatedFunction(EOpIsNan, float3,
|
|
||||||
"bool3 webgl_isnan_emu(float3 x)\n"
|
|
||||||
"{\n"
|
|
||||||
" bool3 isnan;\n"
|
|
||||||
" for (int i = 0; i < 3; i++)\n"
|
|
||||||
" {\n"
|
|
||||||
" isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
|
|
||||||
" }\n"
|
|
||||||
" return isnan;\n"
|
|
||||||
"}\n");
|
|
||||||
|
|
||||||
emu->addEmulatedFunction(EOpIsNan, float4,
|
|
||||||
"bool4 webgl_isnan_emu(float4 x)\n"
|
|
||||||
"{\n"
|
|
||||||
" bool4 isnan;\n"
|
|
||||||
" for (int i = 0; i < 4; i++)\n"
|
|
||||||
" {\n"
|
|
||||||
" isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
|
|
||||||
" }\n"
|
|
||||||
" return isnan;\n"
|
|
||||||
"}\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
|
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
|
||||||
{
|
{
|
||||||
|
|
@ -495,5 +439,3 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
|
||||||
"}\n");
|
"}\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,8 @@
|
||||||
|
|
||||||
#include "GLSLANG/ShaderLang.h"
|
#include "GLSLANG/ShaderLang.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
class BuiltInFunctionEmulator;
|
class BuiltInFunctionEmulator;
|
||||||
|
|
||||||
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu);
|
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu);
|
||||||
|
|
||||||
//
|
|
||||||
// This works around isnan() bug on some Intel drivers.
|
|
||||||
//
|
|
||||||
void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
|
|
||||||
int targetGLSLVersion);
|
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
|
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,6 @@
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "compiler/translator/Cache.h"
|
#include "compiler/translator/Cache.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -47,6 +44,7 @@ TCache::TypeKey::TypeKey(TBasicType basicType,
|
||||||
"TypeKey::value is too small");
|
"TypeKey::value is too small");
|
||||||
|
|
||||||
const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max();
|
const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max();
|
||||||
|
UNUSED_ASSERTION_VARIABLE(MaxEnumValue);
|
||||||
|
|
||||||
// TODO: change to static_assert() once we deprecate MSVC 2013 support
|
// TODO: change to static_assert() once we deprecate MSVC 2013 support
|
||||||
ASSERT(MaxEnumValue >= EbtLast &&
|
ASSERT(MaxEnumValue >= EbtLast &&
|
||||||
|
|
@ -100,5 +98,3 @@ const TType *TCache::getType(TBasicType basicType,
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,6 @@
|
||||||
#include "compiler/translator/Types.h"
|
#include "compiler/translator/Types.h"
|
||||||
#include "compiler/translator/PoolAlloc.h"
|
#include "compiler/translator/PoolAlloc.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
class TCache
|
class TCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -90,6 +87,4 @@ class TCache
|
||||||
static TCache *sCache;
|
static TCache *sCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_CACHE_H_
|
#endif // COMPILER_TRANSLATOR_CACHE_H_
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,6 @@
|
||||||
#include "compiler/translator/CallDAG.h"
|
#include "compiler/translator/CallDAG.h"
|
||||||
#include "compiler/translator/InfoSink.h"
|
#include "compiler/translator/InfoSink.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
// The CallDAGCreator does all the processing required to create the CallDAG
|
// The CallDAGCreator does all the processing required to create the CallDAG
|
||||||
// structure so that the latter contains only the necessary variables.
|
// structure so that the latter contains only the necessary variables.
|
||||||
class CallDAG::CallDAGCreator : public TIntermTraverser
|
class CallDAG::CallDAGCreator : public TIntermTraverser
|
||||||
|
|
@ -47,7 +44,6 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
||||||
skipped++;
|
skipped++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(mFunctions.size() == mCurrentIndex + skipped);
|
ASSERT(mFunctions.size() == mCurrentIndex + skipped);
|
||||||
return INITDAG_SUCCESS;
|
return INITDAG_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -79,8 +75,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
||||||
record.callees.push_back(static_cast<int>(callee->index));
|
record.callees.push_back(static_cast<int>(callee->index));
|
||||||
}
|
}
|
||||||
|
|
||||||
(*idToIndex)[data.node->getFunctionSymbolInfo()->getId()] =
|
(*idToIndex)[data.node->getFunctionId()] = static_cast<int>(data.index);
|
||||||
static_cast<int>(data.index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,39 +92,13 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<CreatorFunctionData*> callees;
|
std::set<CreatorFunctionData*> callees;
|
||||||
TIntermFunctionDefinition *node;
|
TIntermAggregate *node;
|
||||||
TString name;
|
TString name;
|
||||||
size_t index;
|
size_t index;
|
||||||
bool indexAssigned;
|
bool indexAssigned;
|
||||||
bool visiting;
|
bool visiting;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
|
|
||||||
{
|
|
||||||
// Create the record if need be and remember the node.
|
|
||||||
if (visit == PreVisit)
|
|
||||||
{
|
|
||||||
auto it = mFunctions.find(node->getFunctionSymbolInfo()->getName());
|
|
||||||
|
|
||||||
if (it == mFunctions.end())
|
|
||||||
{
|
|
||||||
mCurrentFunction = &mFunctions[node->getFunctionSymbolInfo()->getName()];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mCurrentFunction = &it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
mCurrentFunction->node = node;
|
|
||||||
mCurrentFunction->name = node->getFunctionSymbolInfo()->getName();
|
|
||||||
}
|
|
||||||
else if (visit == PostVisit)
|
|
||||||
{
|
|
||||||
mCurrentFunction = nullptr;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aggregates the AST node for each function as well as the name of the functions called by it
|
// Aggregates the AST node for each function as well as the name of the functions called by it
|
||||||
bool visitAggregate(Visit visit, TIntermAggregate *node) override
|
bool visitAggregate(Visit visit, TIntermAggregate *node) override
|
||||||
{
|
{
|
||||||
|
|
@ -139,10 +108,36 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
||||||
if (visit == PreVisit)
|
if (visit == PreVisit)
|
||||||
{
|
{
|
||||||
// Function declaration, create an empty record.
|
// Function declaration, create an empty record.
|
||||||
auto &record = mFunctions[node->getFunctionSymbolInfo()->getName()];
|
auto& record = mFunctions[node->getName()];
|
||||||
record.name = node->getFunctionSymbolInfo()->getName();
|
record.name = node->getName();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case EOpFunction:
|
||||||
|
{
|
||||||
|
// Function definition, create the record if need be and remember the node.
|
||||||
|
if (visit == PreVisit)
|
||||||
|
{
|
||||||
|
auto it = mFunctions.find(node->getName());
|
||||||
|
|
||||||
|
if (it == mFunctions.end())
|
||||||
|
{
|
||||||
|
mCurrentFunction = &mFunctions[node->getName()];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mCurrentFunction = &it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCurrentFunction->node = node;
|
||||||
|
mCurrentFunction->name = node->getName();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (visit == PostVisit)
|
||||||
|
{
|
||||||
|
mCurrentFunction = nullptr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case EOpFunctionCall:
|
case EOpFunctionCall:
|
||||||
{
|
{
|
||||||
// Function call, add the callees
|
// Function call, add the callees
|
||||||
|
|
@ -151,7 +146,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
||||||
// Do not handle calls to builtin functions
|
// Do not handle calls to builtin functions
|
||||||
if (node->isUserDefined())
|
if (node->isUserDefined())
|
||||||
{
|
{
|
||||||
auto it = mFunctions.find(node->getFunctionSymbolInfo()->getName());
|
auto it = mFunctions.find(node->getName());
|
||||||
ASSERT(it != mFunctions.end());
|
ASSERT(it != mFunctions.end());
|
||||||
|
|
||||||
// We might be in a top-level function call to set a global variable
|
// We might be in a top-level function call to set a global variable
|
||||||
|
|
@ -170,102 +165,52 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively assigns indices to a sub DAG
|
// Recursively assigns indices to a sub DAG
|
||||||
InitResult assignIndicesInternal(CreatorFunctionData *root)
|
InitResult assignIndicesInternal(CreatorFunctionData *function)
|
||||||
{
|
{
|
||||||
// Iterative implementation of the index assignment algorithm. A recursive version
|
ASSERT(function);
|
||||||
// would be prettier but since the CallDAG creation runs before the limiting of the
|
|
||||||
// call depth, we might get stack overflows (computation of the call depth uses the
|
|
||||||
// CallDAG).
|
|
||||||
|
|
||||||
ASSERT(root);
|
if (!function->node)
|
||||||
|
{
|
||||||
|
*mCreationInfo << "Undefined function '" << function->name
|
||||||
|
<< ")' used in the following call chain:";
|
||||||
|
return INITDAG_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
if (root->indexAssigned)
|
if (function->indexAssigned)
|
||||||
{
|
{
|
||||||
return INITDAG_SUCCESS;
|
return INITDAG_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we didn't have to detect recursion, functionsToProcess could be a simple queue
|
if (function->visiting)
|
||||||
// in which we add the function being processed's callees. However in order to detect
|
|
||||||
// recursion we need to know which functions we are currently visiting. For that reason
|
|
||||||
// functionsToProcess will look like a concatenation of segments of the form
|
|
||||||
// [F visiting = true, subset of F callees with visiting = false] and the following
|
|
||||||
// segment (if any) will be start with a callee of F.
|
|
||||||
// This way we can remember when we started visiting a function, to put visiting back
|
|
||||||
// to false.
|
|
||||||
TVector<CreatorFunctionData *> functionsToProcess;
|
|
||||||
functionsToProcess.push_back(root);
|
|
||||||
|
|
||||||
InitResult result = INITDAG_SUCCESS;
|
|
||||||
|
|
||||||
while (!functionsToProcess.empty())
|
|
||||||
{
|
{
|
||||||
CreatorFunctionData *function = functionsToProcess.back();
|
if (mCreationInfo)
|
||||||
|
|
||||||
if (function->visiting)
|
|
||||||
{
|
{
|
||||||
function->visiting = false;
|
*mCreationInfo << "Recursive function call in the following call chain:" << function->name;
|
||||||
function->index = mCurrentIndex++;
|
|
||||||
function->indexAssigned = true;
|
|
||||||
|
|
||||||
functionsToProcess.pop_back();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!function->node)
|
|
||||||
{
|
|
||||||
*mCreationInfo << "Undefined function '" << function->name
|
|
||||||
<< ")' used in the following call chain:";
|
|
||||||
result = INITDAG_UNDEFINED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (function->indexAssigned)
|
|
||||||
{
|
|
||||||
functionsToProcess.pop_back();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
function->visiting = true;
|
|
||||||
|
|
||||||
for (auto callee : function->callees)
|
|
||||||
{
|
|
||||||
functionsToProcess.push_back(callee);
|
|
||||||
|
|
||||||
// Check if the callee is already being visited after pushing it so that it appears
|
|
||||||
// in the chain printed in the info log.
|
|
||||||
if (callee->visiting)
|
|
||||||
{
|
|
||||||
*mCreationInfo << "Recursive function call in the following call chain:";
|
|
||||||
result = INITDAG_RECURSION;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return INITDAG_RECURSION;
|
||||||
|
}
|
||||||
|
function->visiting = true;
|
||||||
|
|
||||||
|
for (auto &callee : function->callees)
|
||||||
|
{
|
||||||
|
InitResult result = assignIndicesInternal(callee);
|
||||||
if (result != INITDAG_SUCCESS)
|
if (result != INITDAG_SUCCESS)
|
||||||
{
|
{
|
||||||
break;
|
// We know that there is an issue with the call chain in the AST,
|
||||||
}
|
// print the link of the chain we were processing.
|
||||||
}
|
if (mCreationInfo)
|
||||||
|
|
||||||
// The call chain is made of the function we were visiting when the error was detected.
|
|
||||||
if (result != INITDAG_SUCCESS)
|
|
||||||
{
|
|
||||||
bool first = true;
|
|
||||||
for (auto function : functionsToProcess)
|
|
||||||
{
|
|
||||||
if (function->visiting)
|
|
||||||
{
|
{
|
||||||
if (!first)
|
*mCreationInfo << " <- " << function->name << ")";
|
||||||
{
|
|
||||||
*mCreationInfo << " -> ";
|
|
||||||
}
|
|
||||||
*mCreationInfo << function->name << ")";
|
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
function->index = mCurrentIndex++;
|
||||||
|
function->indexAssigned = true;
|
||||||
|
|
||||||
|
function->visiting = false;
|
||||||
|
return INITDAG_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
TInfoSinkBase *mCreationInfo;
|
TInfoSinkBase *mCreationInfo;
|
||||||
|
|
@ -287,9 +232,13 @@ CallDAG::~CallDAG()
|
||||||
|
|
||||||
const size_t CallDAG::InvalidIndex = std::numeric_limits<size_t>::max();
|
const size_t CallDAG::InvalidIndex = std::numeric_limits<size_t>::max();
|
||||||
|
|
||||||
size_t CallDAG::findIndex(const TFunctionSymbolInfo *functionInfo) const
|
size_t CallDAG::findIndex(const TIntermAggregate *function) const
|
||||||
{
|
{
|
||||||
auto it = mFunctionIdToIndex.find(functionInfo->getId());
|
TOperator op = function->getOp();
|
||||||
|
ASSERT(op == EOpPrototype || op == EOpFunction || op == EOpFunctionCall);
|
||||||
|
UNUSED_ASSERTION_VARIABLE(op);
|
||||||
|
|
||||||
|
auto it = mFunctionIdToIndex.find(function->getFunctionId());
|
||||||
|
|
||||||
if (it == mFunctionIdToIndex.end())
|
if (it == mFunctionIdToIndex.end())
|
||||||
{
|
{
|
||||||
|
|
@ -309,7 +258,7 @@ const CallDAG::Record &CallDAG::getRecordFromIndex(size_t index) const
|
||||||
|
|
||||||
const CallDAG::Record &CallDAG::getRecord(const TIntermAggregate *function) const
|
const CallDAG::Record &CallDAG::getRecord(const TIntermAggregate *function) const
|
||||||
{
|
{
|
||||||
size_t index = findIndex(function->getFunctionSymbolInfo());
|
size_t index = findIndex(function);
|
||||||
ASSERT(index != InvalidIndex && index < mRecords.size());
|
ASSERT(index != InvalidIndex && index < mRecords.size());
|
||||||
return mRecords[index];
|
return mRecords[index];
|
||||||
}
|
}
|
||||||
|
|
@ -327,8 +276,6 @@ void CallDAG::clear()
|
||||||
|
|
||||||
CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info)
|
CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info)
|
||||||
{
|
{
|
||||||
ASSERT(info);
|
|
||||||
|
|
||||||
CallDAGCreator creator(info);
|
CallDAGCreator creator(info);
|
||||||
|
|
||||||
// Creates the mapping of functions to callees
|
// Creates the mapping of functions to callees
|
||||||
|
|
@ -344,5 +291,3 @@ CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info)
|
||||||
creator.fillDataStructures(&mRecords, &mFunctionIdToIndex);
|
creator.fillDataStructures(&mRecords, &mFunctionIdToIndex);
|
||||||
return INITDAG_SUCCESS;
|
return INITDAG_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@
|
||||||
#include "compiler/translator/IntermNode.h"
|
#include "compiler/translator/IntermNode.h"
|
||||||
#include "compiler/translator/VariableInfo.h"
|
#include "compiler/translator/VariableInfo.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
// The translator needs to analyze the the graph of the function calls
|
// The translator needs to analyze the the graph of the function calls
|
||||||
// to run checks and analyses; since in GLSL recursion is not allowed
|
// to run checks and analyses; since in GLSL recursion is not allowed
|
||||||
|
|
@ -43,7 +41,7 @@ class CallDAG : angle::NonCopyable
|
||||||
struct Record
|
struct Record
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
TIntermFunctionDefinition *node;
|
TIntermAggregate *node;
|
||||||
std::vector<int> callees;
|
std::vector<int> callees;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -59,7 +57,7 @@ class CallDAG : angle::NonCopyable
|
||||||
InitResult init(TIntermNode *root, TInfoSinkBase *info);
|
InitResult init(TIntermNode *root, TInfoSinkBase *info);
|
||||||
|
|
||||||
// Returns InvalidIndex if the function wasn't found
|
// Returns InvalidIndex if the function wasn't found
|
||||||
size_t findIndex(const TFunctionSymbolInfo *functionInfo) const;
|
size_t findIndex(const TIntermAggregate *function) const;
|
||||||
|
|
||||||
const Record &getRecordFromIndex(size_t index) const;
|
const Record &getRecordFromIndex(size_t index) const;
|
||||||
const Record &getRecord(const TIntermAggregate *function) const;
|
const Record &getRecord(const TIntermAggregate *function) const;
|
||||||
|
|
@ -74,6 +72,4 @@ class CallDAG : angle::NonCopyable
|
||||||
class CallDAGCreator;
|
class CallDAGCreator;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_CALLDAG_H_
|
#endif // COMPILER_TRANSLATOR_CALLDAG_H_
|
||||||
|
|
|
||||||
|
|
@ -6,79 +6,71 @@
|
||||||
|
|
||||||
#ifdef ANGLE_ENABLE_ESSL
|
#ifdef ANGLE_ENABLE_ESSL
|
||||||
#include "compiler/translator/TranslatorESSL.h"
|
#include "compiler/translator/TranslatorESSL.h"
|
||||||
#endif // ANGLE_ENABLE_ESSL
|
#endif
|
||||||
|
|
||||||
#ifdef ANGLE_ENABLE_GLSL
|
#ifdef ANGLE_ENABLE_GLSL
|
||||||
#include "compiler/translator/TranslatorGLSL.h"
|
#include "compiler/translator/TranslatorGLSL.h"
|
||||||
#endif // ANGLE_ENABLE_GLSL
|
#endif
|
||||||
|
|
||||||
#ifdef ANGLE_ENABLE_HLSL
|
#ifdef ANGLE_ENABLE_HLSL
|
||||||
#include "compiler/translator/TranslatorHLSL.h"
|
#include "compiler/translator/TranslatorHLSL.h"
|
||||||
#endif // ANGLE_ENABLE_HLSL
|
#endif // ANGLE_ENABLE_HLSL
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// This function must be provided to create the actual
|
// This function must be provided to create the actual
|
||||||
// compile object used by higher level code. It returns
|
// compile object used by higher level code. It returns
|
||||||
// a subclass of TCompiler.
|
// a subclass of TCompiler.
|
||||||
//
|
//
|
||||||
TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
|
TCompiler* ConstructCompiler(
|
||||||
|
sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
|
||||||
{
|
{
|
||||||
switch (output)
|
switch (output) {
|
||||||
{
|
case SH_ESSL_OUTPUT:
|
||||||
case SH_ESSL_OUTPUT:
|
|
||||||
#ifdef ANGLE_ENABLE_ESSL
|
#ifdef ANGLE_ENABLE_ESSL
|
||||||
return new TranslatorESSL(type, spec);
|
return new TranslatorESSL(type, spec);
|
||||||
#else
|
#else
|
||||||
// This compiler is not supported in this configuration. Return NULL per the
|
// This compiler is not supported in this
|
||||||
// sh::ConstructCompiler API.
|
// configuration. Return NULL per the ShConstructCompiler API.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif // ANGLE_ENABLE_ESSL
|
#endif // ANGLE_ENABLE_ESSL
|
||||||
|
case SH_GLSL_130_OUTPUT:
|
||||||
case SH_GLSL_130_OUTPUT:
|
case SH_GLSL_140_OUTPUT:
|
||||||
case SH_GLSL_140_OUTPUT:
|
case SH_GLSL_150_CORE_OUTPUT:
|
||||||
case SH_GLSL_150_CORE_OUTPUT:
|
case SH_GLSL_330_CORE_OUTPUT:
|
||||||
case SH_GLSL_330_CORE_OUTPUT:
|
case SH_GLSL_400_CORE_OUTPUT:
|
||||||
case SH_GLSL_400_CORE_OUTPUT:
|
case SH_GLSL_410_CORE_OUTPUT:
|
||||||
case SH_GLSL_410_CORE_OUTPUT:
|
case SH_GLSL_420_CORE_OUTPUT:
|
||||||
case SH_GLSL_420_CORE_OUTPUT:
|
case SH_GLSL_430_CORE_OUTPUT:
|
||||||
case SH_GLSL_430_CORE_OUTPUT:
|
case SH_GLSL_440_CORE_OUTPUT:
|
||||||
case SH_GLSL_440_CORE_OUTPUT:
|
case SH_GLSL_450_CORE_OUTPUT:
|
||||||
case SH_GLSL_450_CORE_OUTPUT:
|
case SH_GLSL_COMPATIBILITY_OUTPUT:
|
||||||
case SH_GLSL_COMPATIBILITY_OUTPUT:
|
|
||||||
#ifdef ANGLE_ENABLE_GLSL
|
#ifdef ANGLE_ENABLE_GLSL
|
||||||
return new TranslatorGLSL(type, spec, output);
|
return new TranslatorGLSL(type, spec, output);
|
||||||
#else
|
#else
|
||||||
// This compiler is not supported in this configuration. Return NULL per the
|
// This compiler is not supported in this
|
||||||
// sh::ConstructCompiler API.
|
// configuration. Return NULL per the ShConstructCompiler API.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif // ANGLE_ENABLE_GLSL
|
#endif // ANGLE_ENABLE_GLSL
|
||||||
|
case SH_HLSL_3_0_OUTPUT:
|
||||||
case SH_HLSL_3_0_OUTPUT:
|
case SH_HLSL_4_1_OUTPUT:
|
||||||
case SH_HLSL_4_1_OUTPUT:
|
case SH_HLSL_4_0_FL9_3_OUTPUT:
|
||||||
case SH_HLSL_4_0_FL9_3_OUTPUT:
|
|
||||||
#ifdef ANGLE_ENABLE_HLSL
|
#ifdef ANGLE_ENABLE_HLSL
|
||||||
return new TranslatorHLSL(type, spec, output);
|
return new TranslatorHLSL(type, spec, output);
|
||||||
#else
|
#else
|
||||||
// This compiler is not supported in this configuration. Return NULL per the
|
// This compiler is not supported in this
|
||||||
// sh::ConstructCompiler API.
|
// configuration. Return NULL per the ShConstructCompiler API.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif // ANGLE_ENABLE_HLSL
|
#endif // ANGLE_ENABLE_HLSL
|
||||||
|
default:
|
||||||
default:
|
// Unknown format. Return NULL per the ShConstructCompiler API.
|
||||||
// Unknown format. Return NULL per the sh::ConstructCompiler API.
|
return nullptr;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Delete the compiler made by ConstructCompiler
|
// Delete the compiler made by ConstructCompiler
|
||||||
//
|
//
|
||||||
void DeleteCompiler(TCompiler *compiler)
|
void DeleteCompiler(TCompiler* compiler)
|
||||||
{
|
{
|
||||||
SafeDelete(compiler);
|
delete compiler;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,6 @@
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "compiler/translator/PoolAlloc.h"
|
#include "compiler/translator/PoolAlloc.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
struct TSourceLoc {
|
struct TSourceLoc {
|
||||||
int first_file;
|
int first_file;
|
||||||
int first_line;
|
int first_line;
|
||||||
|
|
@ -95,6 +92,4 @@ inline TString str(T i)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_COMMON_H_
|
#endif // COMPILER_TRANSLATOR_COMMON_H_
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,11 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "compiler/translator/Compiler.h"
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "angle_gl.h"
|
|
||||||
#include "common/utilities.h"
|
|
||||||
#include "compiler/translator/AddAndTrueToLoopCondition.h"
|
|
||||||
#include "compiler/translator/Cache.h"
|
#include "compiler/translator/Cache.h"
|
||||||
|
#include "compiler/translator/Compiler.h"
|
||||||
#include "compiler/translator/CallDAG.h"
|
#include "compiler/translator/CallDAG.h"
|
||||||
#include "compiler/translator/DeferGlobalInitializers.h"
|
#include "compiler/translator/DeferGlobalInitializers.h"
|
||||||
#include "compiler/translator/EmulateGLFragColorBroadcast.h"
|
#include "compiler/translator/EmulateGLFragColorBroadcast.h"
|
||||||
#include "compiler/translator/EmulatePrecision.h"
|
|
||||||
#include "compiler/translator/ForLoopUnroll.h"
|
#include "compiler/translator/ForLoopUnroll.h"
|
||||||
#include "compiler/translator/Initialize.h"
|
#include "compiler/translator/Initialize.h"
|
||||||
#include "compiler/translator/InitializeParseContext.h"
|
#include "compiler/translator/InitializeParseContext.h"
|
||||||
|
|
@ -23,100 +16,41 @@
|
||||||
#include "compiler/translator/ParseContext.h"
|
#include "compiler/translator/ParseContext.h"
|
||||||
#include "compiler/translator/PruneEmptyDeclarations.h"
|
#include "compiler/translator/PruneEmptyDeclarations.h"
|
||||||
#include "compiler/translator/RegenerateStructNames.h"
|
#include "compiler/translator/RegenerateStructNames.h"
|
||||||
#include "compiler/translator/RemoveInvariantDeclaration.h"
|
|
||||||
#include "compiler/translator/RemovePow.h"
|
#include "compiler/translator/RemovePow.h"
|
||||||
|
#include "compiler/translator/RenameFunction.h"
|
||||||
#include "compiler/translator/RewriteDoWhile.h"
|
#include "compiler/translator/RewriteDoWhile.h"
|
||||||
#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
|
#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
|
||||||
#include "compiler/translator/UnfoldShortCircuitAST.h"
|
#include "compiler/translator/UnfoldShortCircuitAST.h"
|
||||||
#include "compiler/translator/UseInterfaceBlockFields.h"
|
|
||||||
#include "compiler/translator/ValidateLimitations.h"
|
#include "compiler/translator/ValidateLimitations.h"
|
||||||
#include "compiler/translator/ValidateMaxParameters.h"
|
#include "compiler/translator/ValidateMaxParameters.h"
|
||||||
#include "compiler/translator/ValidateOutputs.h"
|
#include "compiler/translator/ValidateOutputs.h"
|
||||||
#include "compiler/translator/VariablePacker.h"
|
#include "compiler/translator/VariablePacker.h"
|
||||||
|
#include "compiler/translator/depgraph/DependencyGraph.h"
|
||||||
|
#include "compiler/translator/depgraph/DependencyGraphOutput.h"
|
||||||
|
#include "compiler/translator/timing/RestrictFragmentShaderTiming.h"
|
||||||
|
#include "compiler/translator/timing/RestrictVertexShaderTiming.h"
|
||||||
#include "third_party/compiler/ArrayBoundsClamper.h"
|
#include "third_party/compiler/ArrayBoundsClamper.h"
|
||||||
|
#include "angle_gl.h"
|
||||||
namespace sh
|
#include "common/utilities.h"
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
#if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT)
|
|
||||||
void DumpFuzzerCase(char const *const *shaderStrings,
|
|
||||||
size_t numStrings,
|
|
||||||
uint32_t type,
|
|
||||||
uint32_t spec,
|
|
||||||
uint32_t output,
|
|
||||||
uint64_t options)
|
|
||||||
{
|
|
||||||
static int fileIndex = 0;
|
|
||||||
|
|
||||||
std::ostringstream o;
|
|
||||||
o << "corpus/" << fileIndex++ << ".sample";
|
|
||||||
std::string s = o.str();
|
|
||||||
|
|
||||||
// Must match the input format of the fuzzer
|
|
||||||
FILE *f = fopen(s.c_str(), "w");
|
|
||||||
fwrite(&type, sizeof(type), 1, f);
|
|
||||||
fwrite(&spec, sizeof(spec), 1, f);
|
|
||||||
fwrite(&output, sizeof(output), 1, f);
|
|
||||||
fwrite(&options, sizeof(options), 1, f);
|
|
||||||
|
|
||||||
char zero[128 - 20] = {0};
|
|
||||||
fwrite(&zero, 128 - 20, 1, f);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < numStrings; i++)
|
|
||||||
{
|
|
||||||
fwrite(shaderStrings[i], sizeof(char), strlen(shaderStrings[i]), f);
|
|
||||||
}
|
|
||||||
fwrite(&zero, 1, 1, f);
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
#endif // defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT)
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
bool IsWebGLBasedSpec(ShShaderSpec spec)
|
bool IsWebGLBasedSpec(ShShaderSpec spec)
|
||||||
{
|
{
|
||||||
return (spec == SH_WEBGL_SPEC || spec == SH_WEBGL2_SPEC || spec == SH_WEBGL3_SPEC);
|
return (spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC || spec == SH_WEBGL2_SPEC ||
|
||||||
|
spec == SH_WEBGL3_SPEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsGLSL130OrNewer(ShShaderOutput output)
|
bool IsGLSL130OrNewer(ShShaderOutput output)
|
||||||
{
|
{
|
||||||
return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
|
return (output == SH_GLSL_130_OUTPUT ||
|
||||||
output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
|
output == SH_GLSL_140_OUTPUT ||
|
||||||
output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT ||
|
output == SH_GLSL_150_CORE_OUTPUT ||
|
||||||
output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
|
output == SH_GLSL_330_CORE_OUTPUT ||
|
||||||
output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
|
output == SH_GLSL_400_CORE_OUTPUT ||
|
||||||
}
|
output == SH_GLSL_410_CORE_OUTPUT ||
|
||||||
|
output == SH_GLSL_420_CORE_OUTPUT ||
|
||||||
bool IsGLSL420OrNewer(ShShaderOutput output)
|
output == SH_GLSL_430_CORE_OUTPUT ||
|
||||||
{
|
output == SH_GLSL_440_CORE_OUTPUT ||
|
||||||
return (output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
|
output == SH_GLSL_450_CORE_OUTPUT);
|
||||||
output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsGLSL410OrOlder(ShShaderOutput output)
|
|
||||||
{
|
|
||||||
return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
|
|
||||||
output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
|
|
||||||
output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RemoveInvariant(sh::GLenum shaderType,
|
|
||||||
int shaderVersion,
|
|
||||||
ShShaderOutput outputType,
|
|
||||||
ShCompileOptions compileOptions)
|
|
||||||
{
|
|
||||||
if ((compileOptions & SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT) == 0 &&
|
|
||||||
shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if ((compileOptions & SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3) != 0 &&
|
|
||||||
shaderVersion >= 300 && shaderType == GL_VERTEX_SHADER && IsGLSL410OrOlder(outputType))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
|
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
|
||||||
|
|
@ -125,10 +59,11 @@ size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
|
||||||
// size undefined. ES3 defines a max size of 1024 characters.
|
// size undefined. ES3 defines a max size of 1024 characters.
|
||||||
switch (spec)
|
switch (spec)
|
||||||
{
|
{
|
||||||
case SH_WEBGL_SPEC:
|
case SH_WEBGL_SPEC:
|
||||||
return 256;
|
case SH_CSS_SHADERS_SPEC:
|
||||||
default:
|
return 256;
|
||||||
return 1024;
|
default:
|
||||||
|
return 1024;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,18 +109,19 @@ int MapSpecToShaderVersion(ShShaderSpec spec)
|
||||||
{
|
{
|
||||||
switch (spec)
|
switch (spec)
|
||||||
{
|
{
|
||||||
case SH_GLES2_SPEC:
|
case SH_GLES2_SPEC:
|
||||||
case SH_WEBGL_SPEC:
|
case SH_WEBGL_SPEC:
|
||||||
return 100;
|
case SH_CSS_SHADERS_SPEC:
|
||||||
case SH_GLES3_SPEC:
|
return 100;
|
||||||
case SH_WEBGL2_SPEC:
|
case SH_GLES3_SPEC:
|
||||||
return 300;
|
case SH_WEBGL2_SPEC:
|
||||||
case SH_GLES3_1_SPEC:
|
return 300;
|
||||||
case SH_WEBGL3_SPEC:
|
case SH_GLES3_1_SPEC:
|
||||||
return 310;
|
case SH_WEBGL3_SPEC:
|
||||||
default:
|
return 310;
|
||||||
UNREACHABLE();
|
default:
|
||||||
return 0;
|
UNREACHABLE();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,7 +162,7 @@ TCompiler::~TCompiler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCompiler::shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const
|
bool TCompiler::shouldRunLoopAndIndexingValidation(int compileOptions) const
|
||||||
{
|
{
|
||||||
// If compiling an ESSL 1.00 shader for WebGL, or if its been requested through the API,
|
// 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
|
// validate loop and indexing as well (to verify that the shader only uses minimal functionality
|
||||||
|
|
@ -261,16 +197,15 @@ bool TCompiler::Init(const ShBuiltInResources& resources)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIntermBlock *TCompiler::compileTreeForTesting(const char *const shaderStrings[],
|
TIntermNode *TCompiler::compileTreeForTesting(const char* const shaderStrings[],
|
||||||
size_t numStrings,
|
size_t numStrings, int compileOptions)
|
||||||
ShCompileOptions compileOptions)
|
|
||||||
{
|
{
|
||||||
return compileTreeImpl(shaderStrings, numStrings, compileOptions);
|
return compileTreeImpl(shaderStrings, numStrings, compileOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||||
size_t numStrings,
|
size_t numStrings,
|
||||||
const ShCompileOptions compileOptions)
|
const int compileOptions)
|
||||||
{
|
{
|
||||||
clearResults();
|
clearResults();
|
||||||
|
|
||||||
|
|
@ -288,7 +223,8 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||||
++firstSource;
|
++firstSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
TParseContext parseContext(symbolTable, extensionBehavior, shaderType, shaderSpec,
|
TIntermediate intermediate(infoSink);
|
||||||
|
TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec,
|
||||||
compileOptions, true, infoSink, getResources());
|
compileOptions, true, infoSink, getResources());
|
||||||
|
|
||||||
parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh);
|
parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh);
|
||||||
|
|
@ -311,7 +247,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIntermBlock *root = nullptr;
|
TIntermNode *root = nullptr;
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
|
|
@ -322,6 +258,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||||
mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize();
|
mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize();
|
||||||
|
|
||||||
root = parseContext.getTreeRoot();
|
root = parseContext.getTreeRoot();
|
||||||
|
root = intermediate.postProcess(root);
|
||||||
|
|
||||||
// Highp might have been auto-enabled based on shader version
|
// Highp might have been auto-enabled based on shader version
|
||||||
fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
|
fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
|
||||||
|
|
@ -358,17 +295,11 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||||
if (success && shouldRunLoopAndIndexingValidation(compileOptions))
|
if (success && shouldRunLoopAndIndexingValidation(compileOptions))
|
||||||
success = validateLimitations(root);
|
success = validateLimitations(root);
|
||||||
|
|
||||||
// Fail compilation if precision emulation not supported.
|
if (success && (compileOptions & SH_TIMING_RESTRICTIONS))
|
||||||
if (success && getResources().WEBGL_debug_shader_precision &&
|
success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0);
|
||||||
getPragma().debugShaderPrecision)
|
|
||||||
{
|
if (success && shaderSpec == SH_CSS_SHADERS_SPEC)
|
||||||
if (!EmulatePrecision::SupportedInLanguage(outputType))
|
rewriteCSSShader(root);
|
||||||
{
|
|
||||||
infoSink.info.prefix(EPrefixError);
|
|
||||||
infoSink.info << "Precision emulation not supported for this output type.";
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unroll for-loop markup needs to happen after validateLimitations pass.
|
// Unroll for-loop markup needs to happen after validateLimitations pass.
|
||||||
if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
|
if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
|
||||||
|
|
@ -410,16 +341,10 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||||
(outputType == SH_GLSL_COMPATIBILITY_OUTPUT)))
|
(outputType == SH_GLSL_COMPATIBILITY_OUTPUT)))
|
||||||
initializeGLPosition(root);
|
initializeGLPosition(root);
|
||||||
|
|
||||||
if (success && RemoveInvariant(shaderType, shaderVersion, outputType, compileOptions))
|
|
||||||
sh::RemoveInvariantDeclaration(root);
|
|
||||||
|
|
||||||
// This pass might emit short circuits so keep it before the short circuit unfolding
|
// This pass might emit short circuits so keep it before the short circuit unfolding
|
||||||
if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS))
|
if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS))
|
||||||
RewriteDoWhile(root, getTemporaryIndex());
|
RewriteDoWhile(root, getTemporaryIndex());
|
||||||
|
|
||||||
if (success && (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION))
|
|
||||||
sh::AddAndTrueToLoopCondition(root);
|
|
||||||
|
|
||||||
if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT))
|
if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT))
|
||||||
{
|
{
|
||||||
UnfoldShortCircuitAST unfoldShortCircuit;
|
UnfoldShortCircuitAST unfoldShortCircuit;
|
||||||
|
|
@ -435,10 +360,6 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||||
if (success && shouldCollectVariables(compileOptions))
|
if (success && shouldCollectVariables(compileOptions))
|
||||||
{
|
{
|
||||||
collectVariables(root);
|
collectVariables(root);
|
||||||
if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
|
|
||||||
{
|
|
||||||
useAllMembersInUnusedStandardAndSharedBlocks(root);
|
|
||||||
}
|
|
||||||
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
|
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
|
||||||
{
|
{
|
||||||
success = enforcePackingRestrictions();
|
success = enforcePackingRestrictions();
|
||||||
|
|
@ -456,8 +377,9 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||||
|
|
||||||
if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS))
|
if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS))
|
||||||
{
|
{
|
||||||
ScalarizeVecAndMatConstructorArgs(root, shaderType, fragmentPrecisionHigh,
|
ScalarizeVecAndMatConstructorArgs scalarizer(
|
||||||
&mTemporaryIndex);
|
shaderType, fragmentPrecisionHigh);
|
||||||
|
root->traverse(&scalarizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES))
|
if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES))
|
||||||
|
|
@ -486,18 +408,12 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCompiler::compile(const char *const shaderStrings[],
|
bool TCompiler::compile(const char *const shaderStrings[], size_t numStrings, int compileOptionsIn)
|
||||||
size_t numStrings,
|
|
||||||
ShCompileOptions compileOptionsIn)
|
|
||||||
{
|
{
|
||||||
#if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT)
|
|
||||||
DumpFuzzerCase(shaderStrings, numStrings, shaderType, shaderSpec, outputType, compileOptionsIn);
|
|
||||||
#endif // defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT)
|
|
||||||
|
|
||||||
if (numStrings == 0)
|
if (numStrings == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
ShCompileOptions compileOptions = compileOptionsIn;
|
int compileOptions = compileOptionsIn;
|
||||||
|
|
||||||
// Apply key workarounds.
|
// Apply key workarounds.
|
||||||
if (shouldFlattenPragmaStdglInvariantAll())
|
if (shouldFlattenPragmaStdglInvariantAll())
|
||||||
|
|
@ -506,19 +422,8 @@ bool TCompiler::compile(const char *const shaderStrings[],
|
||||||
compileOptions |= SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL;
|
compileOptions |= SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShCompileOptions unrollFlags =
|
|
||||||
SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX | SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
|
|
||||||
if ((compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION) != 0 &&
|
|
||||||
(compileOptions & unrollFlags) != 0)
|
|
||||||
{
|
|
||||||
infoSink.info.prefix(EPrefixError);
|
|
||||||
infoSink.info
|
|
||||||
<< "Unsupported compile flag combination: unroll & ADD_TRUE_TO_LOOP_CONDITION";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TScopedPoolAllocator scopedAlloc(&allocator);
|
TScopedPoolAllocator scopedAlloc(&allocator);
|
||||||
TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
|
TIntermNode *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
|
||||||
|
|
||||||
if (root)
|
if (root)
|
||||||
{
|
{
|
||||||
|
|
@ -547,26 +452,32 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
|
||||||
symbolTable.push(); // ESSL3_1_BUILTINS
|
symbolTable.push(); // ESSL3_1_BUILTINS
|
||||||
|
|
||||||
TPublicType integer;
|
TPublicType integer;
|
||||||
integer.initializeBasicType(EbtInt);
|
integer.type = EbtInt;
|
||||||
|
integer.primarySize = 1;
|
||||||
|
integer.secondarySize = 1;
|
||||||
|
integer.array = false;
|
||||||
|
|
||||||
TPublicType floatingPoint;
|
TPublicType floatingPoint;
|
||||||
floatingPoint.initializeBasicType(EbtFloat);
|
floatingPoint.type = EbtFloat;
|
||||||
|
floatingPoint.primarySize = 1;
|
||||||
|
floatingPoint.secondarySize = 1;
|
||||||
|
floatingPoint.array = false;
|
||||||
|
|
||||||
switch (shaderType)
|
switch(shaderType)
|
||||||
{
|
{
|
||||||
case GL_FRAGMENT_SHADER:
|
case GL_FRAGMENT_SHADER:
|
||||||
symbolTable.setDefaultPrecision(integer, EbpMedium);
|
symbolTable.setDefaultPrecision(integer, EbpMedium);
|
||||||
break;
|
break;
|
||||||
case GL_VERTEX_SHADER:
|
case GL_VERTEX_SHADER:
|
||||||
symbolTable.setDefaultPrecision(integer, EbpHigh);
|
symbolTable.setDefaultPrecision(integer, EbpHigh);
|
||||||
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
|
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
|
||||||
break;
|
break;
|
||||||
case GL_COMPUTE_SHADER:
|
case GL_COMPUTE_SHADER:
|
||||||
symbolTable.setDefaultPrecision(integer, EbpHigh);
|
symbolTable.setDefaultPrecision(integer, EbpHigh);
|
||||||
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
|
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false && "Language not supported");
|
assert(false && "Language not supported");
|
||||||
}
|
}
|
||||||
// Set defaults for sampler types that have default precision, even those that are
|
// Set defaults for sampler types that have default precision, even those that are
|
||||||
// only available if an extension exists.
|
// only available if an extension exists.
|
||||||
|
|
@ -589,7 +500,10 @@ void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType)
|
||||||
{
|
{
|
||||||
ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd);
|
ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd);
|
||||||
TPublicType sampler;
|
TPublicType sampler;
|
||||||
sampler.initializeBasicType(samplerType);
|
sampler.primarySize = 1;
|
||||||
|
sampler.secondarySize = 1;
|
||||||
|
sampler.array = false;
|
||||||
|
sampler.type = samplerType;
|
||||||
symbolTable.setDefaultPrecision(sampler, EbpLow);
|
symbolTable.setDefaultPrecision(sampler, EbpLow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -599,60 +513,60 @@ void TCompiler::setResourceString()
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs
|
strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs
|
||||||
<< ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
|
<< ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
|
||||||
<< ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
|
<< ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
|
||||||
<< ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits
|
<< ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits
|
||||||
<< ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits
|
<< ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits
|
||||||
<< ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits
|
<< ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits
|
||||||
<< ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors
|
<< ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors
|
||||||
<< ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
|
<< ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
|
||||||
<< ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
|
<< ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
|
||||||
<< ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
|
<< ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
|
||||||
<< ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3
|
<< ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3
|
||||||
<< ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external
|
<< ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external
|
||||||
<< ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
|
<< ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
|
||||||
<< ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
|
<< ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
|
||||||
<< ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
|
<< ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
|
||||||
<< ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity
|
<< ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity
|
||||||
<< ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
|
<< ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
|
||||||
<< ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters
|
<< ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters
|
||||||
<< ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended
|
<< ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended
|
||||||
<< ":EXT_frag_depth:" << compileResources.EXT_frag_depth
|
<< ":EXT_frag_depth:" << compileResources.EXT_frag_depth
|
||||||
<< ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
|
<< ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
|
||||||
<< ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
|
<< ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
|
||||||
<< ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
|
<< ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
|
||||||
<< ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
|
<< ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
|
||||||
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
|
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
|
||||||
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
|
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
|
||||||
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
|
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
|
||||||
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
|
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
|
||||||
<< ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
|
<< ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
|
||||||
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers
|
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers
|
||||||
<< ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision
|
<< ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision
|
||||||
<< ":MaxImageUnits:" << compileResources.MaxImageUnits
|
<< ":MaxImageUnits:" << compileResources.MaxImageUnits
|
||||||
<< ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms
|
<< ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms
|
||||||
<< ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms
|
<< ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms
|
||||||
<< ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms
|
<< ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms
|
||||||
<< ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms
|
<< ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms
|
||||||
<< ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources
|
<< ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources
|
||||||
<< ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0]
|
<< ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0]
|
||||||
<< ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1]
|
<< ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1]
|
||||||
<< ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2]
|
<< ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2]
|
||||||
<< ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0]
|
<< ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0]
|
||||||
<< ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1]
|
<< ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1]
|
||||||
<< ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2]
|
<< ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2]
|
||||||
<< ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents
|
<< ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents
|
||||||
<< ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits
|
<< ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits
|
||||||
<< ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters
|
<< ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters
|
||||||
<< ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers
|
<< ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers
|
||||||
<< ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters
|
<< ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters
|
||||||
<< ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters
|
<< ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters
|
||||||
<< ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters
|
<< ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters
|
||||||
<< ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings
|
<< ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings
|
||||||
<< ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers
|
<< ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers
|
||||||
<< ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers
|
<< ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers
|
||||||
<< ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers
|
<< ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers
|
||||||
<< ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize;
|
<< ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
builtInResourcesString = strstream.str();
|
builtInResourcesString = strstream.str();
|
||||||
|
|
@ -687,16 +601,16 @@ bool TCompiler::initCallDag(TIntermNode *root)
|
||||||
|
|
||||||
switch (mCallDag.init(root, &infoSink.info))
|
switch (mCallDag.init(root, &infoSink.info))
|
||||||
{
|
{
|
||||||
case CallDAG::INITDAG_SUCCESS:
|
case CallDAG::INITDAG_SUCCESS:
|
||||||
return true;
|
return true;
|
||||||
case CallDAG::INITDAG_RECURSION:
|
case CallDAG::INITDAG_RECURSION:
|
||||||
infoSink.info.prefix(EPrefixError);
|
infoSink.info.prefix(EPrefixError);
|
||||||
infoSink.info << "Function recursion detected";
|
infoSink.info << "Function recursion detected";
|
||||||
return false;
|
return false;
|
||||||
case CallDAG::INITDAG_UNDEFINED:
|
case CallDAG::INITDAG_UNDEFINED:
|
||||||
infoSink.info.prefix(EPrefixError);
|
infoSink.info.prefix(EPrefixError);
|
||||||
infoSink.info << "Unimplemented function detected";
|
infoSink.info << "Unimplemented function detected";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
|
@ -790,38 +704,30 @@ class TCompiler::UnusedPredicate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UnusedPredicate(const CallDAG *callDag, const std::vector<FunctionMetadata> *metadatas)
|
UnusedPredicate(const CallDAG *callDag, const std::vector<FunctionMetadata> *metadatas)
|
||||||
: mCallDag(callDag), mMetadatas(metadatas)
|
: mCallDag(callDag),
|
||||||
|
mMetadatas(metadatas)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator ()(TIntermNode *node)
|
bool operator ()(TIntermNode *node)
|
||||||
{
|
{
|
||||||
const TIntermAggregate *asAggregate = node->getAsAggregate();
|
const TIntermAggregate *asAggregate = node->getAsAggregate();
|
||||||
const TIntermFunctionDefinition *asFunction = node->getAsFunctionDefinition();
|
|
||||||
|
|
||||||
const TFunctionSymbolInfo *functionInfo = nullptr;
|
if (asAggregate == nullptr)
|
||||||
|
|
||||||
if (asFunction)
|
|
||||||
{
|
|
||||||
functionInfo = asFunction->getFunctionSymbolInfo();
|
|
||||||
}
|
|
||||||
else if (asAggregate)
|
|
||||||
{
|
|
||||||
if (asAggregate->getOp() == EOpPrototype)
|
|
||||||
{
|
|
||||||
functionInfo = asAggregate->getFunctionSymbolInfo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (functionInfo == nullptr)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t callDagIndex = mCallDag->findIndex(functionInfo);
|
if (!(asAggregate->getOp() == EOpFunction || asAggregate->getOp() == EOpPrototype))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t callDagIndex = mCallDag->findIndex(asAggregate);
|
||||||
if (callDagIndex == CallDAG::InvalidIndex)
|
if (callDagIndex == CallDAG::InvalidIndex)
|
||||||
{
|
{
|
||||||
// This happens only for unimplemented prototypes which are thus unused
|
// This happens only for unimplemented prototypes which are thus unused
|
||||||
ASSERT(asAggregate && asAggregate->getOp() == EOpPrototype);
|
ASSERT(asAggregate->getOp() == EOpPrototype);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -834,10 +740,13 @@ class TCompiler::UnusedPredicate
|
||||||
const std::vector<FunctionMetadata> *mMetadatas;
|
const std::vector<FunctionMetadata> *mMetadatas;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TCompiler::pruneUnusedFunctions(TIntermBlock *root)
|
bool TCompiler::pruneUnusedFunctions(TIntermNode *root)
|
||||||
{
|
{
|
||||||
|
TIntermAggregate *rootNode = root->getAsAggregate();
|
||||||
|
ASSERT(rootNode != nullptr);
|
||||||
|
|
||||||
UnusedPredicate isUnused(&mCallDag, &functionMetadata);
|
UnusedPredicate isUnused(&mCallDag, &functionMetadata);
|
||||||
TIntermSequence *sequence = root->getSequence();
|
TIntermSequence *sequence = rootNode->getSequence();
|
||||||
|
|
||||||
if (!sequence->empty())
|
if (!sequence->empty())
|
||||||
{
|
{
|
||||||
|
|
@ -854,6 +763,12 @@ bool TCompiler::validateOutputs(TIntermNode* root)
|
||||||
return (validateOutputs.validateAndCountErrors(infoSink.info) == 0);
|
return (validateOutputs.validateAndCountErrors(infoSink.info) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TCompiler::rewriteCSSShader(TIntermNode* root)
|
||||||
|
{
|
||||||
|
RenameFunction renamer("main(", "css_main(");
|
||||||
|
root->traverse(&renamer);
|
||||||
|
}
|
||||||
|
|
||||||
bool TCompiler::validateLimitations(TIntermNode* root)
|
bool TCompiler::validateLimitations(TIntermNode* root)
|
||||||
{
|
{
|
||||||
ValidateLimitations validate(shaderType, &infoSink.info);
|
ValidateLimitations validate(shaderType, &infoSink.info);
|
||||||
|
|
@ -861,9 +776,39 @@ bool TCompiler::validateLimitations(TIntermNode* root)
|
||||||
return validate.numErrors() == 0;
|
return validate.numErrors() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
|
||||||
|
{
|
||||||
|
if (shaderSpec != SH_WEBGL_SPEC)
|
||||||
|
{
|
||||||
|
infoSink.info << "Timing restrictions must be enforced under the WebGL spec.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shaderType == GL_FRAGMENT_SHADER)
|
||||||
|
{
|
||||||
|
TDependencyGraph graph(root);
|
||||||
|
|
||||||
|
// Output any errors first.
|
||||||
|
bool success = enforceFragmentShaderTimingRestrictions(graph);
|
||||||
|
|
||||||
|
// Then, output the dependency graph.
|
||||||
|
if (outputGraph)
|
||||||
|
{
|
||||||
|
TDependencyGraphOutput output(infoSink.info);
|
||||||
|
output.outputAllSpanningTrees(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return enforceVertexShaderTimingRestrictions(root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool TCompiler::limitExpressionComplexity(TIntermNode* root)
|
bool TCompiler::limitExpressionComplexity(TIntermNode* root)
|
||||||
{
|
{
|
||||||
TMaxDepthTraverser traverser(maxExpressionComplexity + 1);
|
TMaxDepthTraverser traverser(maxExpressionComplexity+1);
|
||||||
root->traverse(&traverser);
|
root->traverse(&traverser);
|
||||||
|
|
||||||
if (traverser.getMaxDepth() > maxExpressionComplexity)
|
if (traverser.getMaxDepth() > maxExpressionComplexity)
|
||||||
|
|
@ -881,13 +826,26 @@ bool TCompiler::limitExpressionComplexity(TIntermNode* root)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
|
||||||
|
{
|
||||||
|
RestrictFragmentShaderTiming restrictor(infoSink.info);
|
||||||
|
restrictor.enforceRestrictions(graph);
|
||||||
|
return restrictor.numErrors() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
|
||||||
|
{
|
||||||
|
RestrictVertexShaderTiming restrictor(infoSink.info);
|
||||||
|
restrictor.enforceRestrictions(root);
|
||||||
|
return restrictor.numErrors() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void TCompiler::collectVariables(TIntermNode* root)
|
void TCompiler::collectVariables(TIntermNode* root)
|
||||||
{
|
{
|
||||||
if (!variablesCollected)
|
if (!variablesCollected)
|
||||||
{
|
{
|
||||||
sh::CollectVariables collect(&attributes, &outputVariables, &uniforms, &varyings,
|
sh::CollectVariables collect(&attributes, &outputVariables, &uniforms, &varyings,
|
||||||
&interfaceBlocks, hashFunction, symbolTable,
|
&interfaceBlocks, hashFunction, symbolTable, extensionBehavior);
|
||||||
extensionBehavior);
|
|
||||||
root->traverse(&collect);
|
root->traverse(&collect);
|
||||||
|
|
||||||
// This is for enforcePackingRestriction().
|
// This is for enforcePackingRestriction().
|
||||||
|
|
@ -896,16 +854,6 @@ void TCompiler::collectVariables(TIntermNode* root)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCompiler::shouldCollectVariables(ShCompileOptions compileOptions)
|
|
||||||
{
|
|
||||||
return (compileOptions & SH_VARIABLES) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TCompiler::wereVariablesCollected() const
|
|
||||||
{
|
|
||||||
return variablesCollected;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TCompiler::enforcePackingRestrictions()
|
bool TCompiler::enforcePackingRestrictions()
|
||||||
{
|
{
|
||||||
VariablePacker packer;
|
VariablePacker packer;
|
||||||
|
|
@ -918,23 +866,7 @@ void TCompiler::initializeGLPosition(TIntermNode* root)
|
||||||
sh::ShaderVariable var(GL_FLOAT_VEC4, 0);
|
sh::ShaderVariable var(GL_FLOAT_VEC4, 0);
|
||||||
var.name = "gl_Position";
|
var.name = "gl_Position";
|
||||||
list.push_back(var);
|
list.push_back(var);
|
||||||
InitializeVariables(root, list, symbolTable);
|
InitializeVariables(root, list);
|
||||||
}
|
|
||||||
|
|
||||||
void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root)
|
|
||||||
{
|
|
||||||
sh::InterfaceBlockList list;
|
|
||||||
|
|
||||||
for (auto block : interfaceBlocks)
|
|
||||||
{
|
|
||||||
if (!block.staticUse &&
|
|
||||||
(block.layout == sh::BLOCKLAYOUT_STANDARD || block.layout == sh::BLOCKLAYOUT_SHARED))
|
|
||||||
{
|
|
||||||
list.push_back(block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sh::UseInterfaceBlockFields(root, list, symbolTable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCompiler::initializeOutputVariables(TIntermNode *root)
|
void TCompiler::initializeOutputVariables(TIntermNode *root)
|
||||||
|
|
@ -955,7 +887,7 @@ void TCompiler::initializeOutputVariables(TIntermNode *root)
|
||||||
list.push_back(var);
|
list.push_back(var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InitializeVariables(root, list, symbolTable);
|
InitializeVariables(root, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TExtensionBehavior& TCompiler::getExtensionBehavior() const
|
const TExtensionBehavior& TCompiler::getExtensionBehavior() const
|
||||||
|
|
@ -988,7 +920,7 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
|
||||||
return builtInFunctionEmulator;
|
return builtInFunctionEmulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCompiler::writePragma(ShCompileOptions compileOptions)
|
void TCompiler::writePragma(int compileOptions)
|
||||||
{
|
{
|
||||||
if (!(compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL))
|
if (!(compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL))
|
||||||
{
|
{
|
||||||
|
|
@ -1011,5 +943,3 @@ bool TCompiler::isVaryingDefined(const char *varyingName)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -24,16 +24,15 @@
|
||||||
#include "compiler/translator/VariableInfo.h"
|
#include "compiler/translator/VariableInfo.h"
|
||||||
#include "third_party/compiler/ArrayBoundsClamper.h"
|
#include "third_party/compiler/ArrayBoundsClamper.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
class TCompiler;
|
class TCompiler;
|
||||||
|
class TDependencyGraph;
|
||||||
#ifdef ANGLE_ENABLE_HLSL
|
#ifdef ANGLE_ENABLE_HLSL
|
||||||
class TranslatorHLSL;
|
class TranslatorHLSL;
|
||||||
#endif // ANGLE_ENABLE_HLSL
|
#endif // ANGLE_ENABLE_HLSL
|
||||||
|
|
||||||
//
|
//
|
||||||
// Helper function to identify specs that are based on the WebGL spec.
|
// Helper function to identify specs that are based on the WebGL spec,
|
||||||
|
// like the CSS Shaders spec.
|
||||||
//
|
//
|
||||||
bool IsWebGLBasedSpec(ShShaderSpec spec);
|
bool IsWebGLBasedSpec(ShShaderSpec spec);
|
||||||
|
|
||||||
|
|
@ -41,16 +40,6 @@ bool IsWebGLBasedSpec(ShShaderSpec spec);
|
||||||
// Helper function to check if the shader type is GLSL.
|
// Helper function to check if the shader type is GLSL.
|
||||||
//
|
//
|
||||||
bool IsGLSL130OrNewer(ShShaderOutput output);
|
bool IsGLSL130OrNewer(ShShaderOutput output);
|
||||||
bool IsGLSL420OrNewer(ShShaderOutput output);
|
|
||||||
bool IsGLSL410OrOlder(ShShaderOutput output);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Helper function to check if the invariant qualifier can be removed.
|
|
||||||
//
|
|
||||||
bool RemoveInvariant(sh::GLenum shaderType,
|
|
||||||
int shaderVersion,
|
|
||||||
ShShaderOutput outputType,
|
|
||||||
ShCompileOptions compileOptions);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// The base class used to back handles returned to the driver.
|
// The base class used to back handles returned to the driver.
|
||||||
|
|
@ -85,14 +74,12 @@ class TCompiler : public TShHandleBase
|
||||||
|
|
||||||
// compileTreeForTesting should be used only when tests require access to
|
// compileTreeForTesting should be used only when tests require access to
|
||||||
// the AST. Users of this function need to manually manage the global pool
|
// the AST. Users of this function need to manually manage the global pool
|
||||||
// allocator. Returns nullptr whenever there are compilation errors.
|
// allocator. Returns NULL whenever there are compilation errors.
|
||||||
TIntermBlock *compileTreeForTesting(const char *const shaderStrings[],
|
TIntermNode *compileTreeForTesting(const char* const shaderStrings[],
|
||||||
size_t numStrings,
|
size_t numStrings, int compileOptions);
|
||||||
ShCompileOptions compileOptions);
|
|
||||||
|
|
||||||
bool compile(const char *const shaderStrings[],
|
bool compile(const char* const shaderStrings[],
|
||||||
size_t numStrings,
|
size_t numStrings, int compileOptions);
|
||||||
ShCompileOptions compileOptions);
|
|
||||||
|
|
||||||
// Get results of the last compilation.
|
// Get results of the last compilation.
|
||||||
int getShaderVersion() const { return shaderVersion; }
|
int getShaderVersion() const { return shaderVersion; }
|
||||||
|
|
@ -117,7 +104,7 @@ class TCompiler : public TShHandleBase
|
||||||
ShShaderOutput getOutputType() const { return outputType; }
|
ShShaderOutput getOutputType() const { return outputType; }
|
||||||
const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
|
const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
|
||||||
|
|
||||||
bool shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const;
|
bool shouldRunLoopAndIndexingValidation(int compileOptions) const;
|
||||||
|
|
||||||
// Get the resources set by InitBuiltInSymbolTable
|
// Get the resources set by InitBuiltInSymbolTable
|
||||||
const ShBuiltInResources& getResources() const;
|
const ShBuiltInResources& getResources() const;
|
||||||
|
|
@ -132,21 +119,20 @@ class TCompiler : public TShHandleBase
|
||||||
bool checkCallDepth();
|
bool checkCallDepth();
|
||||||
// Returns true if a program has no conflicting or missing fragment outputs
|
// Returns true if a program has no conflicting or missing fragment outputs
|
||||||
bool validateOutputs(TIntermNode* root);
|
bool validateOutputs(TIntermNode* root);
|
||||||
|
// Rewrites a shader's intermediate tree according to the CSS Shaders spec.
|
||||||
|
void rewriteCSSShader(TIntermNode* root);
|
||||||
// Returns true if the given shader does not exceed the minimum
|
// Returns true if the given shader does not exceed the minimum
|
||||||
// functionality mandated in GLSL 1.0 spec Appendix A.
|
// functionality mandated in GLSL 1.0 spec Appendix A.
|
||||||
bool validateLimitations(TIntermNode* root);
|
bool validateLimitations(TIntermNode* root);
|
||||||
|
// Collect info for all attribs, uniforms, varyings.
|
||||||
|
void collectVariables(TIntermNode* root);
|
||||||
// Add emulated functions to the built-in function emulator.
|
// Add emulated functions to the built-in function emulator.
|
||||||
virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
|
virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) {};
|
||||||
ShCompileOptions compileOptions){};
|
|
||||||
// Translate to object code.
|
// Translate to object code.
|
||||||
virtual void translate(TIntermNode *root, ShCompileOptions compileOptions) = 0;
|
virtual void translate(TIntermNode *root, int compileOptions) = 0;
|
||||||
// Returns true if, after applying the packing rules in the GLSL 1.017 spec
|
// Returns true if, after applying the packing rules in the GLSL 1.017 spec
|
||||||
// Appendix A, section 7, the shader does not use too many uniforms.
|
// Appendix A, section 7, the shader does not use too many uniforms.
|
||||||
bool enforcePackingRestrictions();
|
bool enforcePackingRestrictions();
|
||||||
// Insert statements to reference all members in unused uniform blocks with standard and shared
|
|
||||||
// layout. This is to work around a Mac driver that treats unused standard/shared
|
|
||||||
// uniform blocks as inactive.
|
|
||||||
void useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root);
|
|
||||||
// Insert statements to initialize output variables in the beginning of main().
|
// Insert statements to initialize output variables in the beginning of main().
|
||||||
// This is to avoid undefined behaviors.
|
// This is to avoid undefined behaviors.
|
||||||
void initializeOutputVariables(TIntermNode *root);
|
void initializeOutputVariables(TIntermNode *root);
|
||||||
|
|
@ -155,13 +141,20 @@ class TCompiler : public TShHandleBase
|
||||||
// while spec says it is allowed.
|
// while spec says it is allowed.
|
||||||
// This function should only be applied to vertex shaders.
|
// This function should only be applied to vertex shaders.
|
||||||
void initializeGLPosition(TIntermNode* root);
|
void initializeGLPosition(TIntermNode* root);
|
||||||
|
// Returns true if the shader passes the restrictions that aim to prevent timing attacks.
|
||||||
|
bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph);
|
||||||
|
// Returns true if the shader does not use samplers.
|
||||||
|
bool enforceVertexShaderTimingRestrictions(TIntermNode* root);
|
||||||
|
// Returns true if the shader does not use sampler dependent values to affect control
|
||||||
|
// flow or in operations whose time can depend on the input values.
|
||||||
|
bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph);
|
||||||
// Return true if the maximum expression complexity is below the limit.
|
// Return true if the maximum expression complexity is below the limit.
|
||||||
bool limitExpressionComplexity(TIntermNode* root);
|
bool limitExpressionComplexity(TIntermNode* root);
|
||||||
// Get built-in extensions with default behavior.
|
// Get built-in extensions with default behavior.
|
||||||
const TExtensionBehavior& getExtensionBehavior() const;
|
const TExtensionBehavior& getExtensionBehavior() const;
|
||||||
const char *getSourcePath() const;
|
const char *getSourcePath() const;
|
||||||
const TPragma& getPragma() const { return mPragma; }
|
const TPragma& getPragma() const { return mPragma; }
|
||||||
void writePragma(ShCompileOptions compileOptions);
|
void writePragma(int compileOptions);
|
||||||
unsigned int *getTemporaryIndex() { return &mTemporaryIndex; }
|
unsigned int *getTemporaryIndex() { return &mTemporaryIndex; }
|
||||||
// Relies on collectVariables having been called.
|
// Relies on collectVariables having been called.
|
||||||
bool isVaryingDefined(const char *varyingName);
|
bool isVaryingDefined(const char *varyingName);
|
||||||
|
|
@ -170,16 +163,20 @@ class TCompiler : public TShHandleBase
|
||||||
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
|
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
|
||||||
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
|
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
|
||||||
|
|
||||||
virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
|
virtual bool shouldCollectVariables(int compileOptions)
|
||||||
virtual bool shouldCollectVariables(ShCompileOptions compileOptions);
|
{
|
||||||
|
return (compileOptions & SH_VARIABLES) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
|
||||||
|
|
||||||
bool wereVariablesCollected() const;
|
|
||||||
std::vector<sh::Attribute> attributes;
|
std::vector<sh::Attribute> attributes;
|
||||||
std::vector<sh::OutputVariable> outputVariables;
|
std::vector<sh::OutputVariable> outputVariables;
|
||||||
std::vector<sh::Uniform> uniforms;
|
std::vector<sh::Uniform> uniforms;
|
||||||
std::vector<sh::ShaderVariable> expandedUniforms;
|
std::vector<sh::ShaderVariable> expandedUniforms;
|
||||||
std::vector<sh::Varying> varyings;
|
std::vector<sh::Varying> varyings;
|
||||||
std::vector<sh::InterfaceBlock> interfaceBlocks;
|
std::vector<sh::InterfaceBlock> interfaceBlocks;
|
||||||
|
bool variablesCollected;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Creates the function call DAG for further analysis, returning false if there is a recursion
|
// Creates the function call DAG for further analysis, returning false if there is a recursion
|
||||||
|
|
@ -190,18 +187,13 @@ class TCompiler : public TShHandleBase
|
||||||
|
|
||||||
void initSamplerDefaultPrecision(TBasicType samplerType);
|
void initSamplerDefaultPrecision(TBasicType samplerType);
|
||||||
|
|
||||||
// Collect info for all attribs, uniforms, varyings.
|
|
||||||
void collectVariables(TIntermNode *root);
|
|
||||||
|
|
||||||
bool variablesCollected;
|
|
||||||
|
|
||||||
// Removes unused function declarations and prototypes from the AST
|
// Removes unused function declarations and prototypes from the AST
|
||||||
class UnusedPredicate;
|
class UnusedPredicate;
|
||||||
bool pruneUnusedFunctions(TIntermBlock *root);
|
bool pruneUnusedFunctions(TIntermNode *root);
|
||||||
|
|
||||||
TIntermBlock *compileTreeImpl(const char *const shaderStrings[],
|
TIntermNode *compileTreeImpl(const char *const shaderStrings[],
|
||||||
size_t numStrings,
|
size_t numStrings,
|
||||||
const ShCompileOptions compileOptions);
|
const int compileOptions);
|
||||||
|
|
||||||
sh::GLenum shaderType;
|
sh::GLenum shaderType;
|
||||||
ShShaderSpec shaderSpec;
|
ShShaderSpec shaderSpec;
|
||||||
|
|
@ -269,6 +261,4 @@ TCompiler* ConstructCompiler(
|
||||||
sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
|
sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
|
||||||
void DeleteCompiler(TCompiler*);
|
void DeleteCompiler(TCompiler*);
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_COMPILER_H_
|
#endif // COMPILER_TRANSLATOR_COMPILER_H_
|
||||||
|
|
|
||||||
|
|
@ -1,642 +0,0 @@
|
||||||
//
|
|
||||||
// Copyright 2016 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.
|
|
||||||
//
|
|
||||||
// ConstantUnion: Constant folding helper class.
|
|
||||||
|
|
||||||
#include "compiler/translator/ConstantUnion.h"
|
|
||||||
|
|
||||||
#include "base/numerics/safe_math.h"
|
|
||||||
#include "common/mathutil.h"
|
|
||||||
#include "compiler/translator/Diagnostics.h"
|
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T CheckedSum(base::CheckedNumeric<T> lhs,
|
|
||||||
base::CheckedNumeric<T> rhs,
|
|
||||||
TDiagnostics *diag,
|
|
||||||
const TSourceLoc &line)
|
|
||||||
{
|
|
||||||
ASSERT(lhs.IsValid() && rhs.IsValid());
|
|
||||||
auto result = lhs + rhs;
|
|
||||||
if (!result.IsValid())
|
|
||||||
{
|
|
||||||
diag->error(line, "Addition out of range", "*", "");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return result.ValueOrDefault(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T CheckedDiff(base::CheckedNumeric<T> lhs,
|
|
||||||
base::CheckedNumeric<T> rhs,
|
|
||||||
TDiagnostics *diag,
|
|
||||||
const TSourceLoc &line)
|
|
||||||
{
|
|
||||||
ASSERT(lhs.IsValid() && rhs.IsValid());
|
|
||||||
auto result = lhs - rhs;
|
|
||||||
if (!result.IsValid())
|
|
||||||
{
|
|
||||||
diag->error(line, "Difference out of range", "*", "");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return result.ValueOrDefault(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T CheckedMul(base::CheckedNumeric<T> lhs,
|
|
||||||
base::CheckedNumeric<T> rhs,
|
|
||||||
TDiagnostics *diag,
|
|
||||||
const TSourceLoc &line)
|
|
||||||
{
|
|
||||||
ASSERT(lhs.IsValid() && rhs.IsValid());
|
|
||||||
auto result = lhs * rhs;
|
|
||||||
if (!result.IsValid())
|
|
||||||
{
|
|
||||||
diag->error(line, "Multiplication out of range", "*", "");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return result.ValueOrDefault(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
TConstantUnion::TConstantUnion()
|
|
||||||
{
|
|
||||||
iConst = 0;
|
|
||||||
type = EbtVoid;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::cast(TBasicType newType, const TConstantUnion &constant)
|
|
||||||
{
|
|
||||||
switch (newType)
|
|
||||||
{
|
|
||||||
case EbtFloat:
|
|
||||||
switch (constant.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
setFConst(static_cast<float>(constant.getIConst()));
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
setFConst(static_cast<float>(constant.getUConst()));
|
|
||||||
break;
|
|
||||||
case EbtBool:
|
|
||||||
setFConst(static_cast<float>(constant.getBConst()));
|
|
||||||
break;
|
|
||||||
case EbtFloat:
|
|
||||||
setFConst(static_cast<float>(constant.getFConst()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EbtInt:
|
|
||||||
switch (constant.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
setIConst(static_cast<int>(constant.getIConst()));
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
setIConst(static_cast<int>(constant.getUConst()));
|
|
||||||
break;
|
|
||||||
case EbtBool:
|
|
||||||
setIConst(static_cast<int>(constant.getBConst()));
|
|
||||||
break;
|
|
||||||
case EbtFloat:
|
|
||||||
setIConst(static_cast<int>(constant.getFConst()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
switch (constant.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
setUConst(static_cast<unsigned int>(constant.getIConst()));
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
setUConst(static_cast<unsigned int>(constant.getUConst()));
|
|
||||||
break;
|
|
||||||
case EbtBool:
|
|
||||||
setUConst(static_cast<unsigned int>(constant.getBConst()));
|
|
||||||
break;
|
|
||||||
case EbtFloat:
|
|
||||||
setUConst(static_cast<unsigned int>(constant.getFConst()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EbtBool:
|
|
||||||
switch (constant.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
setBConst(constant.getIConst() != 0);
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
setBConst(constant.getUConst() != 0);
|
|
||||||
break;
|
|
||||||
case EbtBool:
|
|
||||||
setBConst(constant.getBConst());
|
|
||||||
break;
|
|
||||||
case EbtFloat:
|
|
||||||
setBConst(constant.getFConst() != 0.0f);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EbtStruct: // Struct fields don't get cast
|
|
||||||
switch (constant.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
setIConst(constant.getIConst());
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
setUConst(constant.getUConst());
|
|
||||||
break;
|
|
||||||
case EbtBool:
|
|
||||||
setBConst(constant.getBConst());
|
|
||||||
break;
|
|
||||||
case EbtFloat:
|
|
||||||
setFConst(constant.getFConst());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator==(const int i) const
|
|
||||||
{
|
|
||||||
return i == iConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator==(const unsigned int u) const
|
|
||||||
{
|
|
||||||
return u == uConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator==(const float f) const
|
|
||||||
{
|
|
||||||
return f == fConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator==(const bool b) const
|
|
||||||
{
|
|
||||||
return b == bConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator==(const TConstantUnion &constant) const
|
|
||||||
{
|
|
||||||
if (constant.type != type)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
return constant.iConst == iConst;
|
|
||||||
case EbtUInt:
|
|
||||||
return constant.uConst == uConst;
|
|
||||||
case EbtFloat:
|
|
||||||
return constant.fConst == fConst;
|
|
||||||
case EbtBool:
|
|
||||||
return constant.bConst == bConst;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator!=(const int i) const
|
|
||||||
{
|
|
||||||
return !operator==(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator!=(const unsigned int u) const
|
|
||||||
{
|
|
||||||
return !operator==(u);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator!=(const float f) const
|
|
||||||
{
|
|
||||||
return !operator==(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator!=(const bool b) const
|
|
||||||
{
|
|
||||||
return !operator==(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator!=(const TConstantUnion &constant) const
|
|
||||||
{
|
|
||||||
return !operator==(constant);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator>(const TConstantUnion &constant) const
|
|
||||||
{
|
|
||||||
ASSERT(type == constant.type);
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
return iConst > constant.iConst;
|
|
||||||
case EbtUInt:
|
|
||||||
return uConst > constant.uConst;
|
|
||||||
case EbtFloat:
|
|
||||||
return fConst > constant.fConst;
|
|
||||||
default:
|
|
||||||
return false; // Invalid operation, handled at semantic analysis
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TConstantUnion::operator<(const TConstantUnion &constant) const
|
|
||||||
{
|
|
||||||
ASSERT(type == constant.type);
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
return iConst < constant.iConst;
|
|
||||||
case EbtUInt:
|
|
||||||
return uConst < constant.uConst;
|
|
||||||
case EbtFloat:
|
|
||||||
return fConst < constant.fConst;
|
|
||||||
default:
|
|
||||||
return false; // Invalid operation, handled at semantic analysis
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
TConstantUnion TConstantUnion::add(const TConstantUnion &lhs,
|
|
||||||
const TConstantUnion &rhs,
|
|
||||||
TDiagnostics *diag,
|
|
||||||
const TSourceLoc &line)
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(lhs.type == rhs.type);
|
|
||||||
switch (lhs.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setIConst(gl::WrappingSum<int>(lhs.iConst, rhs.iConst));
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setUConst(gl::WrappingSum<unsigned int>(lhs.uConst, rhs.uConst));
|
|
||||||
break;
|
|
||||||
case EbtFloat:
|
|
||||||
returnValue.setFConst(CheckedSum<float>(lhs.fConst, rhs.fConst, diag, line));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
TConstantUnion TConstantUnion::sub(const TConstantUnion &lhs,
|
|
||||||
const TConstantUnion &rhs,
|
|
||||||
TDiagnostics *diag,
|
|
||||||
const TSourceLoc &line)
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(lhs.type == rhs.type);
|
|
||||||
switch (lhs.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setIConst(gl::WrappingDiff<int>(lhs.iConst, rhs.iConst));
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setUConst(gl::WrappingDiff<unsigned int>(lhs.uConst, rhs.uConst));
|
|
||||||
break;
|
|
||||||
case EbtFloat:
|
|
||||||
returnValue.setFConst(CheckedDiff<float>(lhs.fConst, rhs.fConst, diag, line));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
TConstantUnion TConstantUnion::mul(const TConstantUnion &lhs,
|
|
||||||
const TConstantUnion &rhs,
|
|
||||||
TDiagnostics *diag,
|
|
||||||
const TSourceLoc &line)
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(lhs.type == rhs.type);
|
|
||||||
switch (lhs.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setIConst(gl::WrappingMul(lhs.iConst, rhs.iConst));
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
// Unsigned integer math in C++ is defined to be done in modulo 2^n, so we rely on that
|
|
||||||
// to implement wrapping multiplication.
|
|
||||||
returnValue.setUConst(lhs.uConst * rhs.uConst);
|
|
||||||
break;
|
|
||||||
case EbtFloat:
|
|
||||||
returnValue.setFConst(CheckedMul<float>(lhs.fConst, rhs.fConst, diag, line));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TConstantUnion TConstantUnion::operator%(const TConstantUnion &constant) const
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(type == constant.type);
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setIConst(iConst % constant.iConst);
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setUConst(uConst % constant.uConst);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs,
|
|
||||||
const TConstantUnion &rhs,
|
|
||||||
TDiagnostics *diag,
|
|
||||||
const TSourceLoc &line)
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
|
|
||||||
ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
|
|
||||||
if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) ||
|
|
||||||
(rhs.type == EbtUInt && rhs.uConst > 31u))
|
|
||||||
{
|
|
||||||
diag->error(line, "Undefined shift (operand out of range)", ">>", "");
|
|
||||||
switch (lhs.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setIConst(0);
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setUConst(0u);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (lhs.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
{
|
|
||||||
unsigned int shiftOffset = 0;
|
|
||||||
switch (rhs.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
shiftOffset = static_cast<unsigned int>(rhs.iConst);
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
shiftOffset = rhs.uConst;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
if (shiftOffset > 0)
|
|
||||||
{
|
|
||||||
// ESSL 3.00.6 section 5.9: "If E1 is a signed integer, the right-shift will extend
|
|
||||||
// the sign bit." In C++ shifting negative integers is undefined, so we implement
|
|
||||||
// extending the sign bit manually.
|
|
||||||
int lhsSafe = lhs.iConst;
|
|
||||||
if (lhsSafe == std::numeric_limits<int>::min())
|
|
||||||
{
|
|
||||||
// The min integer needs special treatment because only bit it has set is the
|
|
||||||
// sign bit, which we clear later to implement safe right shift of negative
|
|
||||||
// numbers.
|
|
||||||
lhsSafe = -0x40000000;
|
|
||||||
--shiftOffset;
|
|
||||||
}
|
|
||||||
if (shiftOffset > 0)
|
|
||||||
{
|
|
||||||
bool extendSignBit = false;
|
|
||||||
if (lhsSafe < 0)
|
|
||||||
{
|
|
||||||
extendSignBit = true;
|
|
||||||
// Clear the sign bit so that bitshift right is defined in C++.
|
|
||||||
lhsSafe &= 0x7fffffff;
|
|
||||||
ASSERT(lhsSafe > 0);
|
|
||||||
}
|
|
||||||
returnValue.setIConst(lhsSafe >> shiftOffset);
|
|
||||||
|
|
||||||
// Manually fill in the extended sign bit if necessary.
|
|
||||||
if (extendSignBit)
|
|
||||||
{
|
|
||||||
int extendedSignBit = static_cast<int>(0xffffffffu << (31 - shiftOffset));
|
|
||||||
returnValue.setIConst(returnValue.getIConst() | extendedSignBit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
returnValue.setIConst(lhsSafe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
returnValue.setIConst(lhs.iConst);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EbtUInt:
|
|
||||||
switch (rhs.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setUConst(lhs.uConst >> rhs.iConst);
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setUConst(lhs.uConst >> rhs.uConst);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs,
|
|
||||||
const TConstantUnion &rhs,
|
|
||||||
TDiagnostics *diag,
|
|
||||||
const TSourceLoc &line)
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
|
|
||||||
ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
|
|
||||||
if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) ||
|
|
||||||
(rhs.type == EbtUInt && rhs.uConst > 31u))
|
|
||||||
{
|
|
||||||
diag->error(line, "Undefined shift (operand out of range)", "<<", "");
|
|
||||||
switch (lhs.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setIConst(0);
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setUConst(0u);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (lhs.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
switch (rhs.type)
|
|
||||||
{
|
|
||||||
// Cast to unsigned integer before shifting, since ESSL 3.00.6 section 5.9 says that
|
|
||||||
// lhs is "interpreted as a bit pattern". This also avoids the possibility of signed
|
|
||||||
// integer overflow or undefined shift of a negative integer.
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setIConst(
|
|
||||||
static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.iConst));
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setIConst(
|
|
||||||
static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.uConst));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EbtUInt:
|
|
||||||
switch (rhs.type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setUConst(lhs.uConst << rhs.iConst);
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setUConst(lhs.uConst << rhs.uConst);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TConstantUnion TConstantUnion::operator&(const TConstantUnion &constant) const
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(constant.type == EbtInt || constant.type == EbtUInt);
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setIConst(iConst & constant.iConst);
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setUConst(uConst & constant.uConst);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TConstantUnion TConstantUnion::operator|(const TConstantUnion &constant) const
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(type == constant.type);
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setIConst(iConst | constant.iConst);
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setUConst(uConst | constant.uConst);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TConstantUnion TConstantUnion::operator^(const TConstantUnion &constant) const
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(type == constant.type);
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtInt:
|
|
||||||
returnValue.setIConst(iConst ^ constant.iConst);
|
|
||||||
break;
|
|
||||||
case EbtUInt:
|
|
||||||
returnValue.setUConst(uConst ^ constant.uConst);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TConstantUnion TConstantUnion::operator&&(const TConstantUnion &constant) const
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(type == constant.type);
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtBool:
|
|
||||||
returnValue.setBConst(bConst && constant.bConst);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TConstantUnion TConstantUnion::operator||(const TConstantUnion &constant) const
|
|
||||||
{
|
|
||||||
TConstantUnion returnValue;
|
|
||||||
ASSERT(type == constant.type);
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EbtBool:
|
|
||||||
returnValue.setBConst(bConst || constant.bConst);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
@ -9,21 +9,77 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "compiler/translator/Common.h"
|
|
||||||
#include "compiler/translator/BaseTypes.h"
|
#include "compiler/translator/BaseTypes.h"
|
||||||
|
|
||||||
namespace sh
|
class TConstantUnion {
|
||||||
{
|
public:
|
||||||
|
|
||||||
class TDiagnostics;
|
|
||||||
|
|
||||||
class TConstantUnion
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
POOL_ALLOCATOR_NEW_DELETE();
|
POOL_ALLOCATOR_NEW_DELETE();
|
||||||
TConstantUnion();
|
TConstantUnion()
|
||||||
|
{
|
||||||
|
iConst = 0;
|
||||||
|
type = EbtVoid;
|
||||||
|
}
|
||||||
|
|
||||||
bool cast(TBasicType newType, const TConstantUnion &constant);
|
bool cast(TBasicType newType, const TConstantUnion &constant)
|
||||||
|
{
|
||||||
|
switch (newType)
|
||||||
|
{
|
||||||
|
case EbtFloat:
|
||||||
|
switch (constant.type)
|
||||||
|
{
|
||||||
|
case EbtInt: setFConst(static_cast<float>(constant.getIConst())); break;
|
||||||
|
case EbtUInt: setFConst(static_cast<float>(constant.getUConst())); break;
|
||||||
|
case EbtBool: setFConst(static_cast<float>(constant.getBConst())); break;
|
||||||
|
case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtInt:
|
||||||
|
switch (constant.type)
|
||||||
|
{
|
||||||
|
case EbtInt: setIConst(static_cast<int>(constant.getIConst())); break;
|
||||||
|
case EbtUInt: setIConst(static_cast<int>(constant.getUConst())); break;
|
||||||
|
case EbtBool: setIConst(static_cast<int>(constant.getBConst())); break;
|
||||||
|
case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtUInt:
|
||||||
|
switch (constant.type)
|
||||||
|
{
|
||||||
|
case EbtInt: setUConst(static_cast<unsigned int>(constant.getIConst())); break;
|
||||||
|
case EbtUInt: setUConst(static_cast<unsigned int>(constant.getUConst())); break;
|
||||||
|
case EbtBool: setUConst(static_cast<unsigned int>(constant.getBConst())); break;
|
||||||
|
case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtBool:
|
||||||
|
switch (constant.type)
|
||||||
|
{
|
||||||
|
case EbtInt: setBConst(constant.getIConst() != 0); break;
|
||||||
|
case EbtUInt: setBConst(constant.getUConst() != 0); break;
|
||||||
|
case EbtBool: setBConst(constant.getBConst()); break;
|
||||||
|
case EbtFloat: setBConst(constant.getFConst() != 0.0f); break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtStruct: // Struct fields don't get cast
|
||||||
|
switch (constant.type)
|
||||||
|
{
|
||||||
|
case EbtInt: setIConst(constant.getIConst()); break;
|
||||||
|
case EbtUInt: setUConst(constant.getUConst()); break;
|
||||||
|
case EbtBool: setBConst(constant.getBConst()); break;
|
||||||
|
case EbtFloat: setFConst(constant.getFConst()); break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void setIConst(int i) {iConst = i; type = EbtInt; }
|
void setIConst(int i) {iConst = i; type = EbtInt; }
|
||||||
void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
|
void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
|
||||||
|
|
@ -35,57 +91,258 @@ class TConstantUnion
|
||||||
float getFConst() const { return fConst; }
|
float getFConst() const { return fConst; }
|
||||||
bool getBConst() const { return bConst; }
|
bool getBConst() const { return bConst; }
|
||||||
|
|
||||||
bool operator==(const int i) const;
|
bool operator==(const int i) const
|
||||||
bool operator==(const unsigned int u) const;
|
{
|
||||||
bool operator==(const float f) const;
|
return i == iConst;
|
||||||
bool operator==(const bool b) const;
|
}
|
||||||
bool operator==(const TConstantUnion &constant) const;
|
|
||||||
bool operator!=(const int i) const;
|
bool operator==(const unsigned int u) const
|
||||||
bool operator!=(const unsigned int u) const;
|
{
|
||||||
bool operator!=(const float f) const;
|
return u == uConst;
|
||||||
bool operator!=(const bool b) const;
|
}
|
||||||
bool operator!=(const TConstantUnion &constant) const;
|
|
||||||
bool operator>(const TConstantUnion &constant) const;
|
bool operator==(const float f) const
|
||||||
bool operator<(const TConstantUnion &constant) const;
|
{
|
||||||
static TConstantUnion add(const TConstantUnion &lhs,
|
return f == fConst;
|
||||||
const TConstantUnion &rhs,
|
}
|
||||||
TDiagnostics *diag,
|
|
||||||
const TSourceLoc &line);
|
bool operator==(const bool b) const
|
||||||
static TConstantUnion sub(const TConstantUnion &lhs,
|
{
|
||||||
const TConstantUnion &rhs,
|
return b == bConst;
|
||||||
TDiagnostics *diag,
|
}
|
||||||
const TSourceLoc &line);
|
|
||||||
static TConstantUnion mul(const TConstantUnion &lhs,
|
bool operator==(const TConstantUnion& constant) const
|
||||||
const TConstantUnion &rhs,
|
{
|
||||||
TDiagnostics *diag,
|
if (constant.type != type)
|
||||||
const TSourceLoc &line);
|
return false;
|
||||||
TConstantUnion operator%(const TConstantUnion &constant) const;
|
|
||||||
static TConstantUnion rshift(const TConstantUnion &lhs,
|
switch (type) {
|
||||||
const TConstantUnion &rhs,
|
case EbtInt:
|
||||||
TDiagnostics *diag,
|
return constant.iConst == iConst;
|
||||||
const TSourceLoc &line);
|
case EbtUInt:
|
||||||
static TConstantUnion lshift(const TConstantUnion &lhs,
|
return constant.uConst == uConst;
|
||||||
const TConstantUnion &rhs,
|
case EbtFloat:
|
||||||
TDiagnostics *diag,
|
return constant.fConst == fConst;
|
||||||
const TSourceLoc &line);
|
case EbtBool:
|
||||||
TConstantUnion operator&(const TConstantUnion &constant) const;
|
return constant.bConst == bConst;
|
||||||
TConstantUnion operator|(const TConstantUnion &constant) const;
|
default:
|
||||||
TConstantUnion operator^(const TConstantUnion &constant) const;
|
return false;
|
||||||
TConstantUnion operator&&(const TConstantUnion &constant) const;
|
}
|
||||||
TConstantUnion operator||(const TConstantUnion &constant) const;
|
}
|
||||||
|
|
||||||
|
bool operator!=(const int i) const
|
||||||
|
{
|
||||||
|
return !operator==(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const unsigned int u) const
|
||||||
|
{
|
||||||
|
return !operator==(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const float f) const
|
||||||
|
{
|
||||||
|
return !operator==(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const bool b) const
|
||||||
|
{
|
||||||
|
return !operator==(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
return !operator==(constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator>(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt:
|
||||||
|
return iConst > constant.iConst;
|
||||||
|
case EbtUInt:
|
||||||
|
return uConst > constant.uConst;
|
||||||
|
case EbtFloat:
|
||||||
|
return fConst > constant.fConst;
|
||||||
|
default:
|
||||||
|
return false; // Invalid operation, handled at semantic analysis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt:
|
||||||
|
return iConst < constant.iConst;
|
||||||
|
case EbtUInt:
|
||||||
|
return uConst < constant.uConst;
|
||||||
|
case EbtFloat:
|
||||||
|
return fConst < constant.fConst;
|
||||||
|
default:
|
||||||
|
return false; // Invalid operation, handled at semantic analysis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator+(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
|
||||||
|
case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break;
|
||||||
|
case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator-(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
|
||||||
|
case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break;
|
||||||
|
case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator*(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
|
||||||
|
case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break;
|
||||||
|
case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator%(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
|
||||||
|
case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator>>(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
|
||||||
|
case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator<<(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
// The signedness of the second parameter might be different, but we
|
||||||
|
// don't care, since the result is undefined if the second parameter is
|
||||||
|
// negative, and aliasing should not be a problem with unions.
|
||||||
|
assert(constant.type == EbtInt || constant.type == EbtUInt);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
|
||||||
|
case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator&(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
assert(constant.type == EbtInt || constant.type == EbtUInt);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
|
||||||
|
case EbtUInt: returnValue.setUConst(uConst & constant.uConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator|(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
|
||||||
|
case EbtUInt: returnValue.setUConst(uConst | constant.uConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator^(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
|
||||||
|
case EbtUInt: returnValue.setUConst(uConst ^ constant.uConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator&&(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TConstantUnion operator||(const TConstantUnion& constant) const
|
||||||
|
{
|
||||||
|
TConstantUnion returnValue;
|
||||||
|
assert(type == constant.type);
|
||||||
|
switch (type) {
|
||||||
|
case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
TBasicType getType() const { return type; }
|
TBasicType getType() const { return type; }
|
||||||
private:
|
private:
|
||||||
union {
|
|
||||||
int iConst; // used for ivec, scalar ints
|
union {
|
||||||
unsigned int uConst; // used for uvec, scalar uints
|
int iConst; // used for ivec, scalar ints
|
||||||
bool bConst; // used for bvec, scalar bools
|
unsigned int uConst; // used for uvec, scalar uints
|
||||||
float fConst; // used for vec, mat, scalar floats
|
bool bConst; // used for bvec, scalar bools
|
||||||
};
|
float fConst; // used for vec, mat, scalar floats
|
||||||
|
} ;
|
||||||
|
|
||||||
TBasicType type;
|
TBasicType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_
|
#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_
|
||||||
|
|
|
||||||
|
|
@ -15,43 +15,42 @@
|
||||||
#include "compiler/translator/IntermNode.h"
|
#include "compiler/translator/IntermNode.h"
|
||||||
#include "compiler/translator/SymbolTable.h"
|
#include "compiler/translator/SymbolTable.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
void SetInternalFunctionName(TFunctionSymbolInfo *functionInfo, const char *name)
|
void SetInternalFunctionName(TIntermAggregate *functionNode, const char *name)
|
||||||
{
|
{
|
||||||
TString nameStr(name);
|
TString nameStr(name);
|
||||||
nameStr = TFunction::mangleName(nameStr);
|
nameStr = TFunction::mangleName(nameStr);
|
||||||
TName nameObj(nameStr);
|
TName nameObj(nameStr);
|
||||||
nameObj.setInternal(true);
|
nameObj.setInternal(true);
|
||||||
functionInfo->setNameObj(nameObj);
|
functionNode->setNameObj(nameObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
TIntermAggregate *CreateFunctionPrototypeNode(const char *name, const int functionId)
|
TIntermAggregate *CreateFunctionPrototypeNode(const char *name, const int functionId)
|
||||||
{
|
{
|
||||||
TIntermAggregate *functionNode = new TIntermAggregate(EOpPrototype);
|
TIntermAggregate *functionNode = new TIntermAggregate(EOpPrototype);
|
||||||
|
|
||||||
SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
|
SetInternalFunctionName(functionNode, name);
|
||||||
TType returnType(EbtVoid);
|
TType returnType(EbtVoid);
|
||||||
functionNode->setType(returnType);
|
functionNode->setType(returnType);
|
||||||
functionNode->getFunctionSymbolInfo()->setId(functionId);
|
functionNode->setFunctionId(functionId);
|
||||||
return functionNode;
|
return functionNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIntermFunctionDefinition *CreateFunctionDefinitionNode(const char *name,
|
TIntermAggregate *CreateFunctionDefinitionNode(const char *name,
|
||||||
TIntermBlock *functionBody,
|
TIntermAggregate *functionBody,
|
||||||
const int functionId)
|
const int functionId)
|
||||||
{
|
{
|
||||||
TType returnType(EbtVoid);
|
TIntermAggregate *functionNode = new TIntermAggregate(EOpFunction);
|
||||||
TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters);
|
TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters);
|
||||||
TIntermFunctionDefinition *functionNode =
|
functionNode->getSequence()->push_back(paramsNode);
|
||||||
new TIntermFunctionDefinition(returnType, paramsNode, functionBody);
|
functionNode->getSequence()->push_back(functionBody);
|
||||||
|
|
||||||
SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
|
SetInternalFunctionName(functionNode, name);
|
||||||
functionNode->getFunctionSymbolInfo()->setId(functionId);
|
TType returnType(EbtVoid);
|
||||||
|
functionNode->setType(returnType);
|
||||||
|
functionNode->setFunctionId(functionId);
|
||||||
return functionNode;
|
return functionNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,10 +59,10 @@ TIntermAggregate *CreateFunctionCallNode(const char *name, const int functionId)
|
||||||
TIntermAggregate *functionNode = new TIntermAggregate(EOpFunctionCall);
|
TIntermAggregate *functionNode = new TIntermAggregate(EOpFunctionCall);
|
||||||
|
|
||||||
functionNode->setUserDefined();
|
functionNode->setUserDefined();
|
||||||
SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
|
SetInternalFunctionName(functionNode, name);
|
||||||
TType returnType(EbtVoid);
|
TType returnType(EbtVoid);
|
||||||
functionNode->setType(returnType);
|
functionNode->setType(returnType);
|
||||||
functionNode->getFunctionSymbolInfo()->setId(functionId);
|
functionNode->setFunctionId(functionId);
|
||||||
return functionNode;
|
return functionNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +73,7 @@ class DeferGlobalInitializersTraverser : public TIntermTraverser
|
||||||
|
|
||||||
bool visitBinary(Visit visit, TIntermBinary *node) override;
|
bool visitBinary(Visit visit, TIntermBinary *node) override;
|
||||||
|
|
||||||
void insertInitFunction(TIntermBlock *root);
|
void insertInitFunction(TIntermNode *root);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TIntermSequence mDeferredInitializers;
|
TIntermSequence mDeferredInitializers;
|
||||||
|
|
@ -102,8 +101,10 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n
|
||||||
// Deferral is done also in any cases where the variable has not been constant folded,
|
// Deferral is done also in any cases where the variable has not been constant folded,
|
||||||
// since otherwise there's a chance that HLSL output will generate extra statements
|
// since otherwise there's a chance that HLSL output will generate extra statements
|
||||||
// from the initializer expression.
|
// from the initializer expression.
|
||||||
TIntermBinary *deferredInit =
|
TIntermBinary *deferredInit = new TIntermBinary(EOpAssign);
|
||||||
new TIntermBinary(EOpAssign, symbolNode->deepCopy(), node->getRight());
|
deferredInit->setLeft(symbolNode->deepCopy());
|
||||||
|
deferredInit->setRight(node->getRight());
|
||||||
|
deferredInit->setType(node->getType());
|
||||||
mDeferredInitializers.push_back(deferredInit);
|
mDeferredInitializers.push_back(deferredInit);
|
||||||
|
|
||||||
// Change const global to a regular global if its initialization is deferred.
|
// Change const global to a regular global if its initialization is deferred.
|
||||||
|
|
@ -114,7 +115,7 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n
|
||||||
if (symbolNode->getQualifier() == EvqConst)
|
if (symbolNode->getQualifier() == EvqConst)
|
||||||
{
|
{
|
||||||
// All of the siblings in the same declaration need to have consistent qualifiers.
|
// All of the siblings in the same declaration need to have consistent qualifiers.
|
||||||
auto *siblings = getParentNode()->getAsDeclarationNode()->getSequence();
|
auto *siblings = getParentNode()->getAsAggregate()->getSequence();
|
||||||
for (TIntermNode *siblingNode : *siblings)
|
for (TIntermNode *siblingNode : *siblings)
|
||||||
{
|
{
|
||||||
TIntermBinary *siblingBinary = siblingNode->getAsBinaryNode();
|
TIntermBinary *siblingBinary = siblingNode->getAsBinaryNode();
|
||||||
|
|
@ -135,51 +136,56 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeferGlobalInitializersTraverser::insertInitFunction(TIntermBlock *root)
|
void DeferGlobalInitializersTraverser::insertInitFunction(TIntermNode *root)
|
||||||
{
|
{
|
||||||
if (mDeferredInitializers.empty())
|
if (mDeferredInitializers.empty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const int initFunctionId = TSymbolTable::nextUniqueId();
|
const int initFunctionId = TSymbolTable::nextUniqueId();
|
||||||
|
TIntermAggregate *rootAgg = root->getAsAggregate();
|
||||||
|
ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence);
|
||||||
|
|
||||||
const char *functionName = "initializeDeferredGlobals";
|
const char *functionName = "initializeDeferredGlobals";
|
||||||
|
|
||||||
// Add function prototype to the beginning of the shader
|
// Add function prototype to the beginning of the shader
|
||||||
TIntermAggregate *functionPrototypeNode =
|
TIntermAggregate *functionPrototypeNode =
|
||||||
CreateFunctionPrototypeNode(functionName, initFunctionId);
|
CreateFunctionPrototypeNode(functionName, initFunctionId);
|
||||||
root->getSequence()->insert(root->getSequence()->begin(), functionPrototypeNode);
|
rootAgg->getSequence()->insert(rootAgg->getSequence()->begin(), functionPrototypeNode);
|
||||||
|
|
||||||
// Add function definition to the end of the shader
|
// Add function definition to the end of the shader
|
||||||
TIntermBlock *functionBodyNode = new TIntermBlock();
|
TIntermAggregate *functionBodyNode = new TIntermAggregate(EOpSequence);
|
||||||
TIntermSequence *functionBody = functionBodyNode->getSequence();
|
TIntermSequence *functionBody = functionBodyNode->getSequence();
|
||||||
for (const auto &deferredInit : mDeferredInitializers)
|
for (const auto &deferredInit : mDeferredInitializers)
|
||||||
{
|
{
|
||||||
functionBody->push_back(deferredInit);
|
functionBody->push_back(deferredInit);
|
||||||
}
|
}
|
||||||
TIntermFunctionDefinition *functionDefinition =
|
TIntermAggregate *functionDefinition =
|
||||||
CreateFunctionDefinitionNode(functionName, functionBodyNode, initFunctionId);
|
CreateFunctionDefinitionNode(functionName, functionBodyNode, initFunctionId);
|
||||||
root->getSequence()->push_back(functionDefinition);
|
rootAgg->getSequence()->push_back(functionDefinition);
|
||||||
|
|
||||||
// Insert call into main function
|
// Insert call into main function
|
||||||
for (TIntermNode *node : *root->getSequence())
|
for (TIntermNode *node : *rootAgg->getSequence())
|
||||||
{
|
{
|
||||||
TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
|
TIntermAggregate *nodeAgg = node->getAsAggregate();
|
||||||
if (nodeFunction != nullptr && nodeFunction->getFunctionSymbolInfo()->isMain())
|
if (nodeAgg != nullptr && nodeAgg->getOp() == EOpFunction &&
|
||||||
|
TFunction::unmangleName(nodeAgg->getName()) == "main")
|
||||||
{
|
{
|
||||||
TIntermAggregate *functionCallNode =
|
TIntermAggregate *functionCallNode =
|
||||||
CreateFunctionCallNode(functionName, initFunctionId);
|
CreateFunctionCallNode(functionName, initFunctionId);
|
||||||
|
|
||||||
TIntermBlock *mainBody = nodeFunction->getBody();
|
TIntermNode *mainBody = nodeAgg->getSequence()->back();
|
||||||
ASSERT(mainBody != nullptr);
|
TIntermAggregate *mainBodyAgg = mainBody->getAsAggregate();
|
||||||
mainBody->getSequence()->insert(mainBody->getSequence()->begin(), functionCallNode);
|
ASSERT(mainBodyAgg != nullptr && mainBodyAgg->getOp() == EOpSequence);
|
||||||
|
mainBodyAgg->getSequence()->insert(mainBodyAgg->getSequence()->begin(),
|
||||||
|
functionCallNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void DeferGlobalInitializers(TIntermBlock *root)
|
void DeferGlobalInitializers(TIntermNode *root)
|
||||||
{
|
{
|
||||||
DeferGlobalInitializersTraverser traverser;
|
DeferGlobalInitializersTraverser traverser;
|
||||||
root->traverse(&traverser);
|
root->traverse(&traverser);
|
||||||
|
|
@ -190,5 +196,3 @@ void DeferGlobalInitializers(TIntermBlock *root)
|
||||||
// Add the function with initialization and the call to that.
|
// Add the function with initialization and the call to that.
|
||||||
traverser.insertInitFunction(root);
|
traverser.insertInitFunction(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,8 @@
|
||||||
#ifndef COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
|
#ifndef COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
|
||||||
#define COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
|
#define COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
|
||||||
|
|
||||||
class TIntermBlock;
|
class TIntermNode;
|
||||||
|
|
||||||
namespace sh
|
void DeferGlobalInitializers(TIntermNode *root);
|
||||||
{
|
|
||||||
void DeferGlobalInitializers(TIntermBlock *root);
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
|
#endif // COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,6 @@
|
||||||
#include "compiler/translator/Common.h"
|
#include "compiler/translator/Common.h"
|
||||||
#include "compiler/translator/InfoSink.h"
|
#include "compiler/translator/InfoSink.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
TDiagnostics::TDiagnostics(TInfoSink& infoSink) :
|
TDiagnostics::TDiagnostics(TInfoSink& infoSink) :
|
||||||
mInfoSink(infoSink),
|
mInfoSink(infoSink),
|
||||||
mNumErrors(0),
|
mNumErrors(0),
|
||||||
|
|
@ -82,5 +79,3 @@ void TDiagnostics::print(ID id,
|
||||||
{
|
{
|
||||||
writeInfo(severity(id), loc, message(id), text, "");
|
writeInfo(severity(id), loc, message(id), text, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,6 @@
|
||||||
#include "common/angleutils.h"
|
#include "common/angleutils.h"
|
||||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
class TInfoSink;
|
class TInfoSink;
|
||||||
struct TSourceLoc;
|
struct TSourceLoc;
|
||||||
|
|
||||||
|
|
@ -48,6 +45,4 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable
|
||||||
int mNumWarnings;
|
int mNumWarnings;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_
|
#endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,6 @@
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "compiler/translator/Diagnostics.h"
|
#include "compiler/translator/Diagnostics.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
static TBehavior getBehavior(const std::string& str)
|
static TBehavior getBehavior(const std::string& str)
|
||||||
{
|
{
|
||||||
const char kRequire[] = "require";
|
const char kRequire[] = "require";
|
||||||
|
|
@ -198,5 +195,3 @@ void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
|
||||||
"version number", str, "not supported");
|
"version number", str, "not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,6 @@
|
||||||
#include "compiler/preprocessor/DirectiveHandlerBase.h"
|
#include "compiler/preprocessor/DirectiveHandlerBase.h"
|
||||||
#include "GLSLANG/ShaderLang.h"
|
#include "GLSLANG/ShaderLang.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
class TDiagnostics;
|
class TDiagnostics;
|
||||||
|
|
||||||
class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
|
class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
|
||||||
|
|
@ -52,6 +50,4 @@ class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
|
||||||
bool mDebugShaderPrecisionSupported;
|
bool mDebugShaderPrecisionSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
|
#endif // COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
|
||||||
|
|
|
||||||
|
|
@ -14,60 +14,59 @@
|
||||||
#include "compiler/translator/EmulateGLFragColorBroadcast.h"
|
#include "compiler/translator/EmulateGLFragColorBroadcast.h"
|
||||||
#include "compiler/translator/IntermNode.h"
|
#include "compiler/translator/IntermNode.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
TIntermConstantUnion *constructIndexNode(int index)
|
||||||
|
{
|
||||||
|
TConstantUnion *u = new TConstantUnion[1];
|
||||||
|
u[0].setIConst(index);
|
||||||
|
|
||||||
|
TType type(EbtInt, EbpUndefined, EvqConst, 1);
|
||||||
|
TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
TIntermBinary *constructGLFragDataNode(int index)
|
||||||
|
{
|
||||||
|
TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
|
||||||
|
TIntermSymbol *symbol = new TIntermSymbol(0, "gl_FragData", TType(EbtFloat, 4));
|
||||||
|
indexDirect->setLeft(symbol);
|
||||||
|
TIntermConstantUnion *indexNode = constructIndexNode(index);
|
||||||
|
indexDirect->setRight(indexNode);
|
||||||
|
return indexDirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
TIntermBinary *constructGLFragDataAssignNode(int index)
|
||||||
|
{
|
||||||
|
TIntermBinary *assign = new TIntermBinary(EOpAssign);
|
||||||
|
assign->setLeft(constructGLFragDataNode(index));
|
||||||
|
assign->setRight(constructGLFragDataNode(0));
|
||||||
|
assign->setType(TType(EbtFloat, 4));
|
||||||
|
return assign;
|
||||||
|
}
|
||||||
|
|
||||||
class GLFragColorBroadcastTraverser : public TIntermTraverser
|
class GLFragColorBroadcastTraverser : public TIntermTraverser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GLFragColorBroadcastTraverser(int maxDrawBuffers)
|
GLFragColorBroadcastTraverser()
|
||||||
: TIntermTraverser(true, false, false),
|
: TIntermTraverser(true, false, false), mMainSequence(nullptr), mGLFragColorUsed(false)
|
||||||
mMainSequence(nullptr),
|
|
||||||
mGLFragColorUsed(false),
|
|
||||||
mMaxDrawBuffers(maxDrawBuffers)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadcastGLFragColor();
|
void broadcastGLFragColor(int maxDrawBuffers);
|
||||||
|
|
||||||
bool isGLFragColorUsed() const { return mGLFragColorUsed; }
|
bool isGLFragColorUsed() const { return mGLFragColorUsed; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void visitSymbol(TIntermSymbol *node) override;
|
void visitSymbol(TIntermSymbol *node) override;
|
||||||
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
|
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
|
||||||
|
|
||||||
TIntermBinary *constructGLFragDataNode(int index) const;
|
|
||||||
TIntermBinary *constructGLFragDataAssignNode(int index) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TIntermSequence *mMainSequence;
|
TIntermSequence *mMainSequence;
|
||||||
bool mGLFragColorUsed;
|
bool mGLFragColorUsed;
|
||||||
int mMaxDrawBuffers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const
|
|
||||||
{
|
|
||||||
TType gl_FragDataType = TType(EbtFloat, EbpMedium, EvqFragData, 4);
|
|
||||||
gl_FragDataType.setArraySize(mMaxDrawBuffers);
|
|
||||||
|
|
||||||
TIntermSymbol *symbol = new TIntermSymbol(0, "gl_FragData", gl_FragDataType);
|
|
||||||
TIntermTyped *indexNode = TIntermTyped::CreateIndexNode(index);
|
|
||||||
|
|
||||||
TIntermBinary *binary = new TIntermBinary(EOpIndexDirect, symbol, indexNode);
|
|
||||||
return binary;
|
|
||||||
}
|
|
||||||
|
|
||||||
TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataAssignNode(int index) const
|
|
||||||
{
|
|
||||||
TIntermTyped *fragDataIndex = constructGLFragDataNode(index);
|
|
||||||
TIntermTyped *fragDataZero = constructGLFragDataNode(0);
|
|
||||||
|
|
||||||
return new TIntermBinary(EOpAssign, fragDataIndex, fragDataZero);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
|
void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
|
||||||
{
|
{
|
||||||
if (node->getSymbol() == "gl_FragColor")
|
if (node->getSymbol() == "gl_FragColor")
|
||||||
|
|
@ -77,22 +76,34 @@ void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLFragColorBroadcastTraverser::visitFunctionDefinition(Visit visit,
|
bool GLFragColorBroadcastTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||||
TIntermFunctionDefinition *node)
|
|
||||||
{
|
{
|
||||||
ASSERT(visit == PreVisit);
|
switch (node->getOp())
|
||||||
if (node->getFunctionSymbolInfo()->isMain())
|
|
||||||
{
|
{
|
||||||
TIntermBlock *body = node->getBody();
|
case EOpFunction:
|
||||||
ASSERT(body);
|
// Function definition.
|
||||||
mMainSequence = body->getSequence();
|
ASSERT(visit == PreVisit);
|
||||||
|
if (node->getName() == "main(")
|
||||||
|
{
|
||||||
|
TIntermSequence *sequence = node->getSequence();
|
||||||
|
ASSERT((sequence->size() == 1) || (sequence->size() == 2));
|
||||||
|
if (sequence->size() == 2)
|
||||||
|
{
|
||||||
|
TIntermAggregate *body = (*sequence)[1]->getAsAggregate();
|
||||||
|
ASSERT(body);
|
||||||
|
mMainSequence = body->getSequence();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLFragColorBroadcastTraverser::broadcastGLFragColor()
|
void GLFragColorBroadcastTraverser::broadcastGLFragColor(int maxDrawBuffers)
|
||||||
{
|
{
|
||||||
ASSERT(mMaxDrawBuffers > 1);
|
ASSERT(maxDrawBuffers > 1);
|
||||||
if (!mGLFragColorUsed)
|
if (!mGLFragColorUsed)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -102,7 +113,7 @@ void GLFragColorBroadcastTraverser::broadcastGLFragColor()
|
||||||
// gl_FragData[1] = gl_FragData[0];
|
// gl_FragData[1] = gl_FragData[0];
|
||||||
// ...
|
// ...
|
||||||
// gl_FragData[maxDrawBuffers - 1] = gl_FragData[0];
|
// gl_FragData[maxDrawBuffers - 1] = gl_FragData[0];
|
||||||
for (int colorIndex = 1; colorIndex < mMaxDrawBuffers; ++colorIndex)
|
for (int colorIndex = 1; colorIndex < maxDrawBuffers; ++colorIndex)
|
||||||
{
|
{
|
||||||
mMainSequence->insert(mMainSequence->end(), constructGLFragDataAssignNode(colorIndex));
|
mMainSequence->insert(mMainSequence->end(), constructGLFragDataAssignNode(colorIndex));
|
||||||
}
|
}
|
||||||
|
|
@ -115,12 +126,12 @@ void EmulateGLFragColorBroadcast(TIntermNode *root,
|
||||||
std::vector<sh::OutputVariable> *outputVariables)
|
std::vector<sh::OutputVariable> *outputVariables)
|
||||||
{
|
{
|
||||||
ASSERT(maxDrawBuffers > 1);
|
ASSERT(maxDrawBuffers > 1);
|
||||||
GLFragColorBroadcastTraverser traverser(maxDrawBuffers);
|
GLFragColorBroadcastTraverser traverser;
|
||||||
root->traverse(&traverser);
|
root->traverse(&traverser);
|
||||||
if (traverser.isGLFragColorUsed())
|
if (traverser.isGLFragColorUsed())
|
||||||
{
|
{
|
||||||
traverser.updateTree();
|
traverser.updateTree();
|
||||||
traverser.broadcastGLFragColor();
|
traverser.broadcastGLFragColor(maxDrawBuffers);
|
||||||
for (auto &var : *outputVariables)
|
for (auto &var : *outputVariables)
|
||||||
{
|
{
|
||||||
if (var.name == "gl_FragColor")
|
if (var.name == "gl_FragColor")
|
||||||
|
|
@ -133,5 +144,3 @@ void EmulateGLFragColorBroadcast(TIntermNode *root,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
namespace sh
|
namespace sh
|
||||||
{
|
{
|
||||||
struct OutputVariable;
|
struct OutputVariable;
|
||||||
|
}
|
||||||
|
|
||||||
class TIntermNode;
|
class TIntermNode;
|
||||||
|
|
||||||
// Replace all gl_FragColor with gl_FragData[0], and in the end of main() function,
|
// Replace all gl_FragColor with gl_FragData[0], and in the end of main() function,
|
||||||
|
|
@ -22,7 +24,6 @@ class TIntermNode;
|
||||||
// If gl_FragColor is in outputVariables, it is replaced by gl_FragData.
|
// If gl_FragColor is in outputVariables, it is replaced by gl_FragData.
|
||||||
void EmulateGLFragColorBroadcast(TIntermNode *root,
|
void EmulateGLFragColorBroadcast(TIntermNode *root,
|
||||||
int maxDrawBuffers,
|
int maxDrawBuffers,
|
||||||
std::vector<OutputVariable> *outputVariables);
|
std::vector<sh::OutputVariable> *outputVariables);
|
||||||
}
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_
|
#endif // COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,6 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -94,7 +91,6 @@ class RoundingHelperWriterHLSL : public RoundingHelperWriter
|
||||||
|
|
||||||
RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage)
|
RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage)
|
||||||
{
|
{
|
||||||
ASSERT(EmulatePrecision::SupportedInLanguage(outputLanguage));
|
|
||||||
switch (outputLanguage)
|
switch (outputLanguage)
|
||||||
{
|
{
|
||||||
case SH_HLSL_4_1_OUTPUT:
|
case SH_HLSL_4_1_OUTPUT:
|
||||||
|
|
@ -102,6 +98,9 @@ RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOut
|
||||||
case SH_ESSL_OUTPUT:
|
case SH_ESSL_OUTPUT:
|
||||||
return new RoundingHelperWriterESSL(outputLanguage);
|
return new RoundingHelperWriterESSL(outputLanguage);
|
||||||
default:
|
default:
|
||||||
|
// Other languages not yet supported
|
||||||
|
ASSERT(outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
|
||||||
|
IsGLSL130OrNewer(outputLanguage));
|
||||||
return new RoundingHelperWriterGLSL(outputLanguage);
|
return new RoundingHelperWriterGLSL(outputLanguage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -433,7 +432,7 @@ TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *chil
|
||||||
callNode->setOp(EOpFunctionCall);
|
callNode->setOp(EOpFunctionCall);
|
||||||
TName nameObj(TFunction::mangleName(name));
|
TName nameObj(TFunction::mangleName(name));
|
||||||
nameObj.setInternal(true);
|
nameObj.setInternal(true);
|
||||||
callNode->getFunctionSymbolInfo()->setNameObj(nameObj);
|
callNode->setNameObj(nameObj);
|
||||||
callNode->getSequence()->push_back(child);
|
callNode->getSequence()->push_back(child);
|
||||||
return callNode;
|
return callNode;
|
||||||
}
|
}
|
||||||
|
|
@ -470,16 +469,15 @@ bool parentUsesResult(TIntermNode* parent, TIntermNode* node)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIntermBlock *blockParent = parent->getAsBlock();
|
TIntermAggregate *aggParent = parent->getAsAggregate();
|
||||||
// If the parent is a block, the result is not assigned anywhere,
|
// If the parent's op is EOpSequence, the result is not assigned anywhere,
|
||||||
// so rounding it is not needed. In particular, this can avoid a lot of
|
// so rounding it is not needed. In particular, this can avoid a lot of
|
||||||
// unnecessary rounding of unused return values of assignment.
|
// unnecessary rounding of unused return values of assignment.
|
||||||
if (blockParent)
|
if (aggParent && aggParent->getOp() == EOpSequence)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TIntermBinary *binaryParent = parent->getAsBinaryNode();
|
if (aggParent && aggParent->getOp() == EOpComma && (aggParent->getSequence()->back() != node))
|
||||||
if (binaryParent && binaryParent->getOp() == EOpComma && (binaryParent->getRight() != node))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -513,7 +511,7 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
|
||||||
if (op == EOpInitialize && visit == InVisit)
|
if (op == EOpInitialize && visit == InVisit)
|
||||||
mDeclaringVariables = false;
|
mDeclaringVariables = false;
|
||||||
|
|
||||||
if ((op == EOpIndexDirectStruct) && visit == InVisit)
|
if ((op == EOpIndexDirectStruct || op == EOpVectorSwizzle) && visit == InVisit)
|
||||||
visitChildren = false;
|
visitChildren = false;
|
||||||
|
|
||||||
if (visit != PreVisit)
|
if (visit != PreVisit)
|
||||||
|
|
@ -601,30 +599,14 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
|
||||||
return visitChildren;
|
return visitChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatePrecision::visitDeclaration(Visit visit, TIntermDeclaration *node)
|
|
||||||
{
|
|
||||||
// Variable or interface block declaration.
|
|
||||||
if (visit == PreVisit)
|
|
||||||
{
|
|
||||||
mDeclaringVariables = true;
|
|
||||||
}
|
|
||||||
else if (visit == InVisit)
|
|
||||||
{
|
|
||||||
mDeclaringVariables = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mDeclaringVariables = false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
|
bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||||
{
|
{
|
||||||
bool visitChildren = true;
|
bool visitChildren = true;
|
||||||
switch (node->getOp())
|
switch (node->getOp())
|
||||||
{
|
{
|
||||||
|
case EOpSequence:
|
||||||
case EOpConstructStruct:
|
case EOpConstructStruct:
|
||||||
|
case EOpFunction:
|
||||||
break;
|
break;
|
||||||
case EOpPrototype:
|
case EOpPrototype:
|
||||||
visitChildren = false;
|
visitChildren = false;
|
||||||
|
|
@ -635,6 +617,21 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||||
case EOpInvariantDeclaration:
|
case EOpInvariantDeclaration:
|
||||||
visitChildren = false;
|
visitChildren = false;
|
||||||
break;
|
break;
|
||||||
|
case EOpDeclaration:
|
||||||
|
// Variable declaration.
|
||||||
|
if (visit == PreVisit)
|
||||||
|
{
|
||||||
|
mDeclaringVariables = true;
|
||||||
|
}
|
||||||
|
else if (visit == InVisit)
|
||||||
|
{
|
||||||
|
mDeclaringVariables = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mDeclaringVariables = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case EOpFunctionCall:
|
case EOpFunctionCall:
|
||||||
{
|
{
|
||||||
// Function call.
|
// Function call.
|
||||||
|
|
@ -708,19 +705,3 @@ void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase &sink,
|
||||||
roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "*", "mul");
|
roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "*", "mul");
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
bool EmulatePrecision::SupportedInLanguage(const ShShaderOutput outputLanguage)
|
|
||||||
{
|
|
||||||
switch (outputLanguage)
|
|
||||||
{
|
|
||||||
case SH_HLSL_4_1_OUTPUT:
|
|
||||||
case SH_ESSL_OUTPUT:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
// Other languages not yet supported
|
|
||||||
return (outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
|
|
||||||
sh::IsGLSL130OrNewer(outputLanguage));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,6 @@
|
||||||
// need to write a huge number of variations of the emulated compound assignment
|
// need to write a huge number of variations of the emulated compound assignment
|
||||||
// to every translated shader with emulation enabled.
|
// to every translated shader with emulation enabled.
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
class EmulatePrecision : public TLValueTrackingTraverser
|
class EmulatePrecision : public TLValueTrackingTraverser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -30,14 +27,11 @@ class EmulatePrecision : public TLValueTrackingTraverser
|
||||||
bool visitBinary(Visit visit, TIntermBinary *node) override;
|
bool visitBinary(Visit visit, TIntermBinary *node) override;
|
||||||
bool visitUnary(Visit visit, TIntermUnary *node) override;
|
bool visitUnary(Visit visit, TIntermUnary *node) override;
|
||||||
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
|
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
|
||||||
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
|
|
||||||
|
|
||||||
void writeEmulationHelpers(TInfoSinkBase &sink,
|
void writeEmulationHelpers(TInfoSinkBase &sink,
|
||||||
const int shaderVersion,
|
const int shaderVersion,
|
||||||
const ShShaderOutput outputLanguage);
|
const ShShaderOutput outputLanguage);
|
||||||
|
|
||||||
static bool SupportedInLanguage(const ShShaderOutput outputLanguage);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TypePair
|
struct TypePair
|
||||||
{
|
{
|
||||||
|
|
@ -67,6 +61,4 @@ class EmulatePrecision : public TLValueTrackingTraverser
|
||||||
bool mDeclaringVariables;
|
bool mDeclaringVariables;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
|
#endif // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||||
TIntermTyped *lhs = sequence->at(0)->getAsTyped();
|
TIntermTyped *lhs = sequence->at(0)->getAsTyped();
|
||||||
ASSERT(lhs);
|
ASSERT(lhs);
|
||||||
|
|
||||||
TIntermDeclaration *init = createTempInitDeclaration(lhs);
|
TIntermAggregate *init = createTempInitDeclaration(lhs);
|
||||||
TIntermTyped *current = createTempSymbol(lhs->getType());
|
TIntermTyped *current = createTempSymbol(lhs->getType());
|
||||||
|
|
||||||
insertStatementInParentBlock(init);
|
insertStatementInParentBlock(init);
|
||||||
|
|
@ -124,7 +124,10 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||||
// Create a chain of n-1 multiples.
|
// Create a chain of n-1 multiples.
|
||||||
for (int i = 1; i < n; ++i)
|
for (int i = 1; i < n; ++i)
|
||||||
{
|
{
|
||||||
TIntermBinary *mul = new TIntermBinary(EOpMul, current, createTempSymbol(lhs->getType()));
|
TIntermBinary *mul = new TIntermBinary(EOpMul);
|
||||||
|
mul->setLeft(current);
|
||||||
|
mul->setRight(createTempSymbol(lhs->getType()));
|
||||||
|
mul->setType(node->getType());
|
||||||
mul->setLine(node->getLine());
|
mul->setLine(node->getLine());
|
||||||
current = mul;
|
current = mul;
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +138,9 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||||
TConstantUnion *oneVal = new TConstantUnion();
|
TConstantUnion *oneVal = new TConstantUnion();
|
||||||
oneVal->setFConst(1.0f);
|
oneVal->setFConst(1.0f);
|
||||||
TIntermConstantUnion *oneNode = new TIntermConstantUnion(oneVal, node->getType());
|
TIntermConstantUnion *oneNode = new TIntermConstantUnion(oneVal, node->getType());
|
||||||
TIntermBinary *div = new TIntermBinary(EOpDiv, oneNode, current);
|
TIntermBinary *div = new TIntermBinary(EOpDiv);
|
||||||
|
div->setLeft(oneNode);
|
||||||
|
div->setRight(current);
|
||||||
current = div;
|
current = div;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,6 @@
|
||||||
|
|
||||||
#include "compiler/translator/VersionGLSL.h"
|
#include "compiler/translator/VersionGLSL.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
TExtensionGLSL::TExtensionGLSL(ShShaderOutput output)
|
TExtensionGLSL::TExtensionGLSL(ShShaderOutput output)
|
||||||
: TIntermTraverser(true, false, false), mTargetVersion(ShaderOutputTypeToGLSLVersion(output))
|
: TIntermTraverser(true, false, false), mTargetVersion(ShaderOutputTypeToGLSLVersion(output))
|
||||||
{
|
{
|
||||||
|
|
@ -101,5 +98,3 @@ void TExtensionGLSL::checkOperator(TIntermOperator *node)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,6 @@
|
||||||
|
|
||||||
#include "compiler/translator/IntermNode.h"
|
#include "compiler/translator/IntermNode.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
// Traverses the intermediate tree to determine which GLSL extensions are required
|
// Traverses the intermediate tree to determine which GLSL extensions are required
|
||||||
// to support the shader.
|
// to support the shader.
|
||||||
class TExtensionGLSL : public TIntermTraverser
|
class TExtensionGLSL : public TIntermTraverser
|
||||||
|
|
@ -39,6 +36,4 @@ class TExtensionGLSL : public TIntermTraverser
|
||||||
std::set<std::string> mRequiredExtensions;
|
std::set<std::string> mRequiredExtensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
|
#endif // COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,6 @@
|
||||||
#include "compiler/translator/ValidateLimitations.h"
|
#include "compiler/translator/ValidateLimitations.h"
|
||||||
#include "angle_gl.h"
|
#include "angle_gl.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node)
|
bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node)
|
||||||
{
|
{
|
||||||
if (mUnrollCondition != kSamplerArrayIndex)
|
if (mUnrollCondition != kSamplerArrayIndex)
|
||||||
|
|
@ -54,7 +51,7 @@ bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node)
|
||||||
// Check if loop index type is integer.
|
// Check if loop index type is integer.
|
||||||
// This is called after ValidateLimitations pass, so the loop has the limited form specified
|
// This is called after ValidateLimitations pass, so the loop has the limited form specified
|
||||||
// in ESSL 1.00 appendix A.
|
// in ESSL 1.00 appendix A.
|
||||||
TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
|
TIntermSequence *declSeq = node->getInit()->getAsAggregate()->getSequence();
|
||||||
TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
|
TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
|
||||||
if (symbol->getBasicType() == EbtInt)
|
if (symbol->getBasicType() == EbtInt)
|
||||||
node->setUnrollFlag(true);
|
node->setUnrollFlag(true);
|
||||||
|
|
@ -98,5 +95,3 @@ void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,6 @@
|
||||||
|
|
||||||
#include "compiler/translator/LoopInfo.h"
|
#include "compiler/translator/LoopInfo.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
// This class detects for-loops that needs to be unrolled.
|
// This class detects for-loops that needs to be unrolled.
|
||||||
// Currently we support two unroll conditions:
|
// Currently we support two unroll conditions:
|
||||||
// 1) kForLoopWithIntegerIndex: unroll if the index type is integer.
|
// 1) kForLoopWithIntegerIndex: unroll if the index type is integer.
|
||||||
|
|
@ -53,6 +50,4 @@ class ForLoopUnrollMarker : public TIntermTraverser
|
||||||
bool mHasRunLoopValidation;
|
bool mHasRunLoopValidation;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
|
#endif // COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,6 @@
|
||||||
|
|
||||||
#include "compiler/translator/InfoSink.h"
|
#include "compiler/translator/InfoSink.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
void TInfoSinkBase::prefix(TPrefixType p) {
|
void TInfoSinkBase::prefix(TPrefixType p) {
|
||||||
switch(p) {
|
switch(p) {
|
||||||
case EPrefixNone:
|
case EPrefixNone:
|
||||||
|
|
@ -55,5 +52,3 @@ void TInfoSinkBase::message(TPrefixType p, const TSourceLoc& loc, const char* m)
|
||||||
sink.append(m);
|
sink.append(m);
|
||||||
sink.append("\n");
|
sink.append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "compiler/translator/Common.h"
|
#include "compiler/translator/Common.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
// Returns the fractional part of the given floating-point number.
|
// Returns the fractional part of the given floating-point number.
|
||||||
inline float fractionalPart(float f) {
|
inline float fractionalPart(float f) {
|
||||||
float intPart = 0.0f;
|
float intPart = 0.0f;
|
||||||
|
|
@ -116,6 +113,4 @@ public:
|
||||||
TInfoSinkBase obj;
|
TInfoSinkBase obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_INFOSINK_H_
|
#endif // COMPILER_TRANSLATOR_INFOSINK_H_
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,8 @@
|
||||||
#include "compiler/translator/IntermNode.h"
|
#include "compiler/translator/IntermNode.h"
|
||||||
#include "angle_gl.h"
|
#include "angle_gl.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable)
|
void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable)
|
||||||
{
|
{
|
||||||
const TType *voidType = TCache::getType(EbtVoid);
|
|
||||||
const TType *float1 = TCache::getType(EbtFloat);
|
const TType *float1 = TCache::getType(EbtFloat);
|
||||||
const TType *float2 = TCache::getType(EbtFloat, 2);
|
const TType *float2 = TCache::getType(EbtFloat, 2);
|
||||||
const TType *float3 = TCache::getType(EbtFloat, 3);
|
const TType *float3 = TCache::getType(EbtFloat, 3);
|
||||||
|
|
@ -473,26 +469,6 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
|
||||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4, float3, float3, int3);
|
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4, float3, float3, int3);
|
||||||
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow, float4, float2, float2, int2);
|
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow, float4, float2, float2, int2);
|
||||||
|
|
||||||
const TType *gimage2D = TCache::getType(EbtGImage2D);
|
|
||||||
const TType *gimage3D = TCache::getType(EbtGImage3D);
|
|
||||||
const TType *gimage2DArray = TCache::getType(EbtGImage2DArray);
|
|
||||||
const TType *gimageCube = TCache::getType(EbtGImageCube);
|
|
||||||
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2D, int2, gvec4);
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage3D, int3, gvec4);
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2DArray, int3, gvec4);
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimageCube, int3, gvec4);
|
|
||||||
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2D, int2);
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage3D, int3);
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2DArray, int3);
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimageCube, int3);
|
|
||||||
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimage2D);
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage3D);
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage2DArray);
|
|
||||||
symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimageCube);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Depth range in window coordinates
|
// Depth range in window coordinates
|
||||||
//
|
//
|
||||||
|
|
@ -535,13 +511,16 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
|
||||||
symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors,
|
symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors,
|
||||||
EbpMedium);
|
EbpMedium);
|
||||||
|
|
||||||
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers,
|
if (spec != SH_CSS_SHADERS_SPEC)
|
||||||
EbpMedium);
|
|
||||||
if (resources.EXT_blend_func_extended)
|
|
||||||
{
|
{
|
||||||
symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended",
|
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers,
|
||||||
"gl_MaxDualSourceDrawBuffersEXT",
|
EbpMedium);
|
||||||
resources.MaxDualSourceDrawBuffers);
|
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",
|
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors",
|
||||||
|
|
@ -611,73 +590,85 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case GL_FRAGMENT_SHADER:
|
case GL_FRAGMENT_SHADER:
|
||||||
{
|
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"),
|
||||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"),
|
TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
|
||||||
TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
|
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"),
|
||||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"),
|
TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
|
||||||
TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
|
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"),
|
||||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"),
|
TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
|
||||||
TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
|
|
||||||
|
|
||||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"),
|
//
|
||||||
TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
|
// In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available.
|
||||||
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
|
// Instead, css_MixColor and css_ColorMatrix are available.
|
||||||
fragData.setArraySize(resources.MaxDrawBuffers);
|
//
|
||||||
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
|
if (spec != SH_CSS_SHADERS_SPEC)
|
||||||
|
{
|
||||||
|
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"),
|
||||||
|
TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
|
||||||
|
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
|
||||||
|
fragData.setArraySize(resources.MaxDrawBuffers);
|
||||||
|
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
|
||||||
|
|
||||||
if (resources.EXT_blend_func_extended)
|
if (resources.EXT_blend_func_extended)
|
||||||
{
|
{
|
||||||
symbolTable.insert(
|
symbolTable.insert(
|
||||||
ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
|
ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
|
||||||
new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"),
|
new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"),
|
||||||
TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4)));
|
TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4)));
|
||||||
TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true);
|
TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true);
|
||||||
secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers);
|
secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers);
|
||||||
symbolTable.insert(
|
symbolTable.insert(
|
||||||
ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
|
ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
|
||||||
new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData));
|
new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resources.EXT_frag_depth)
|
if (resources.EXT_frag_depth)
|
||||||
{
|
{
|
||||||
symbolTable.insert(
|
symbolTable.insert(
|
||||||
ESSL1_BUILTINS, "GL_EXT_frag_depth",
|
ESSL1_BUILTINS, "GL_EXT_frag_depth",
|
||||||
new TVariable(
|
new TVariable(
|
||||||
NewPoolTString("gl_FragDepthEXT"),
|
NewPoolTString("gl_FragDepthEXT"),
|
||||||
TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
|
TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
|
||||||
EvqFragDepthEXT, 1)));
|
EvqFragDepthEXT, 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
symbolTable.insert(ESSL3_BUILTINS,
|
symbolTable.insert(ESSL3_BUILTINS,
|
||||||
new TVariable(NewPoolTString("gl_FragDepth"),
|
new TVariable(NewPoolTString("gl_FragDepth"),
|
||||||
TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
|
TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
|
||||||
|
|
||||||
if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
|
if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
|
||||||
{
|
{
|
||||||
TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true);
|
TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true);
|
||||||
lastFragData.setArraySize(resources.MaxDrawBuffers);
|
lastFragData.setArraySize(resources.MaxDrawBuffers);
|
||||||
|
|
||||||
if (resources.EXT_shader_framebuffer_fetch)
|
if (resources.EXT_shader_framebuffer_fetch)
|
||||||
{
|
{
|
||||||
symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch",
|
symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch",
|
||||||
new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
|
new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
|
||||||
}
|
}
|
||||||
else if (resources.NV_shader_framebuffer_fetch)
|
else if (resources.NV_shader_framebuffer_fetch)
|
||||||
{
|
{
|
||||||
symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
|
symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
|
||||||
new TVariable(NewPoolTString("gl_LastFragColor"),
|
new TVariable(NewPoolTString("gl_LastFragColor"),
|
||||||
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
|
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
|
||||||
symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
|
symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
|
||||||
new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
|
new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (resources.ARM_shader_framebuffer_fetch)
|
else if (resources.ARM_shader_framebuffer_fetch)
|
||||||
{
|
{
|
||||||
symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch",
|
symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch",
|
||||||
new TVariable(NewPoolTString("gl_LastFragColorARM"),
|
new TVariable(NewPoolTString("gl_LastFragColorARM"),
|
||||||
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
|
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"),
|
||||||
|
TType(EbtFloat, EbpMedium, EvqGlobal, 4)));
|
||||||
|
symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"),
|
||||||
|
TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4)));
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -758,5 +749,3 @@ void ResetExtensionBehavior(TExtensionBehavior &extBehavior)
|
||||||
ext_iter->second = EBhUndefined;
|
ext_iter->second = EBhUndefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,6 @@
|
||||||
#include "compiler/translator/Compiler.h"
|
#include "compiler/translator/Compiler.h"
|
||||||
#include "compiler/translator/SymbolTable.h"
|
#include "compiler/translator/SymbolTable.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &table);
|
void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &table);
|
||||||
|
|
||||||
void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
|
void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
|
||||||
|
|
@ -29,6 +26,4 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
|
||||||
// extensions will remain unsupported.
|
// extensions will remain unsupported.
|
||||||
void ResetExtensionBehavior(TExtensionBehavior &extensionBehavior);
|
void ResetExtensionBehavior(TExtensionBehavior &extensionBehavior);
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_INITIALIZE_H_
|
#endif // COMPILER_TRANSLATOR_INITIALIZE_H_
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,6 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
bool InitProcess()
|
bool InitProcess()
|
||||||
{
|
{
|
||||||
if (!InitializePoolIndex()) {
|
if (!InitializePoolIndex()) {
|
||||||
|
|
@ -39,5 +36,3 @@ void DetachProcess()
|
||||||
FreePoolIndex();
|
FreePoolIndex();
|
||||||
TCache::destroy();
|
TCache::destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,8 @@
|
||||||
#ifndef COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
#ifndef COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
||||||
#define COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
#define COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
bool InitProcess();
|
bool InitProcess();
|
||||||
void DetachProcess();
|
void DetachProcess();
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
#endif // COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,6 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
TLSIndex GlobalParseContextIndex = TLS_INVALID_INDEX;
|
TLSIndex GlobalParseContextIndex = TLS_INVALID_INDEX;
|
||||||
|
|
||||||
bool InitializeParseContextIndex()
|
bool InitializeParseContextIndex()
|
||||||
|
|
@ -43,4 +40,3 @@ TParseContext* GetGlobalParseContext()
|
||||||
return static_cast<TParseContext*>(GetTLSValue(GlobalParseContextIndex));
|
return static_cast<TParseContext*>(GetTLSValue(GlobalParseContextIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,11 @@
|
||||||
#ifndef COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
#ifndef COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
||||||
#define COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
#define COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
bool InitializeParseContextIndex();
|
bool InitializeParseContextIndex();
|
||||||
void FreeParseContextIndex();
|
void FreeParseContextIndex();
|
||||||
|
|
||||||
class TParseContext;
|
class TParseContext;
|
||||||
extern void SetGlobalParseContext(TParseContext* context);
|
extern void SetGlobalParseContext(TParseContext* context);
|
||||||
extern TParseContext* GetGlobalParseContext();
|
extern TParseContext* GetGlobalParseContext();
|
||||||
} // namespace sh
|
|
||||||
|
|
||||||
#endif // COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
#endif // COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
||||||
|
|
|
||||||
|
|
@ -9,122 +9,191 @@
|
||||||
#include "angle_gl.h"
|
#include "angle_gl.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "compiler/translator/IntermNode.h"
|
#include "compiler/translator/IntermNode.h"
|
||||||
#include "compiler/translator/SymbolTable.h"
|
|
||||||
#include "compiler/translator/util.h"
|
#include "compiler/translator/util.h"
|
||||||
|
|
||||||
namespace sh
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
TIntermConstantUnion *constructConstUnionNode(const TType &type)
|
||||||
|
{
|
||||||
|
TType myType = type;
|
||||||
|
myType.clearArrayness();
|
||||||
|
myType.setQualifier(EvqConst);
|
||||||
|
size_t size = myType.getObjectSize();
|
||||||
|
TConstantUnion *u = new TConstantUnion[size];
|
||||||
|
for (size_t ii = 0; ii < size; ++ii)
|
||||||
|
{
|
||||||
|
switch (type.getBasicType())
|
||||||
|
{
|
||||||
|
case EbtFloat:
|
||||||
|
u[ii].setFConst(0.0f);
|
||||||
|
break;
|
||||||
|
case EbtInt:
|
||||||
|
u[ii].setIConst(0);
|
||||||
|
break;
|
||||||
|
case EbtUInt:
|
||||||
|
u[ii].setUConst(0u);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TIntermConstantUnion *node = new TIntermConstantUnion(u, myType);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
TIntermConstantUnion *constructIndexNode(int index)
|
||||||
|
{
|
||||||
|
TConstantUnion *u = new TConstantUnion[1];
|
||||||
|
u[0].setIConst(index);
|
||||||
|
|
||||||
|
TType type(EbtInt, EbpUndefined, EvqConst, 1);
|
||||||
|
TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
class VariableInitializer : public TIntermTraverser
|
class VariableInitializer : public TIntermTraverser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VariableInitializer(const InitVariableList &vars, const TSymbolTable &symbolTable)
|
VariableInitializer(const InitVariableList &vars)
|
||||||
: TIntermTraverser(true, false, false),
|
: TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false)
|
||||||
mVariables(vars),
|
|
||||||
mSymbolTable(symbolTable),
|
|
||||||
mCodeInserted(false)
|
|
||||||
{
|
{
|
||||||
ASSERT(mSymbolTable.atGlobalLevel());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool visitBinary(Visit, TIntermBinary *node) override { return false; }
|
bool visitBinary(Visit, TIntermBinary *node) override { return false; }
|
||||||
bool visitUnary(Visit, TIntermUnary *node) override { return false; }
|
bool visitUnary(Visit, TIntermUnary *node) override { return false; }
|
||||||
bool visitIfElse(Visit, TIntermIfElse *node) override { return false; }
|
bool visitSelection(Visit, TIntermSelection *node) override { return false; }
|
||||||
bool visitLoop(Visit, TIntermLoop *node) override { return false; }
|
bool visitLoop(Visit, TIntermLoop *node) override { return false; }
|
||||||
bool visitBranch(Visit, TIntermBranch *node) override { return false; }
|
bool visitBranch(Visit, TIntermBranch *node) override { return false; }
|
||||||
bool visitAggregate(Visit, TIntermAggregate *node) override { return false; }
|
|
||||||
|
|
||||||
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
|
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void insertInitCode(TIntermSequence *sequence);
|
void insertInitCode(TIntermSequence *sequence);
|
||||||
|
|
||||||
const InitVariableList &mVariables;
|
const InitVariableList &mVariables;
|
||||||
const TSymbolTable &mSymbolTable;
|
|
||||||
bool mCodeInserted;
|
bool mCodeInserted;
|
||||||
};
|
};
|
||||||
|
|
||||||
// VariableInitializer implementation.
|
// VariableInitializer implementation.
|
||||||
|
|
||||||
bool VariableInitializer::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
|
bool VariableInitializer::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||||
{
|
{
|
||||||
// Function definition.
|
bool visitChildren = !mCodeInserted;
|
||||||
ASSERT(visit == PreVisit);
|
switch (node->getOp())
|
||||||
if (node->getFunctionSymbolInfo()->isMain())
|
|
||||||
{
|
{
|
||||||
TIntermBlock *body = node->getBody();
|
case EOpSequence:
|
||||||
insertInitCode(body->getSequence());
|
break;
|
||||||
mCodeInserted = true;
|
case EOpFunction:
|
||||||
|
{
|
||||||
|
// Function definition.
|
||||||
|
ASSERT(visit == PreVisit);
|
||||||
|
if (node->getName() == "main(")
|
||||||
|
{
|
||||||
|
TIntermSequence *sequence = node->getSequence();
|
||||||
|
ASSERT((sequence->size() == 1) || (sequence->size() == 2));
|
||||||
|
TIntermAggregate *body = NULL;
|
||||||
|
if (sequence->size() == 1)
|
||||||
|
{
|
||||||
|
body = new TIntermAggregate(EOpSequence);
|
||||||
|
sequence->push_back(body);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
body = (*sequence)[1]->getAsAggregate();
|
||||||
|
}
|
||||||
|
ASSERT(body);
|
||||||
|
insertInitCode(body->getSequence());
|
||||||
|
mCodeInserted = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
visitChildren = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return visitChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VariableInitializer::insertInitCode(TIntermSequence *sequence)
|
void VariableInitializer::insertInitCode(TIntermSequence *sequence)
|
||||||
{
|
{
|
||||||
for (const auto &var : mVariables)
|
for (size_t ii = 0; ii < mVariables.size(); ++ii)
|
||||||
{
|
{
|
||||||
|
const sh::ShaderVariable &var = mVariables[ii];
|
||||||
TString name = TString(var.name.c_str());
|
TString name = TString(var.name.c_str());
|
||||||
|
|
||||||
if (var.isArray())
|
if (var.isArray())
|
||||||
{
|
{
|
||||||
// Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which
|
TType type = sh::ConvertShaderVariableTypeToTType(var.type);
|
||||||
// doesn't have array assignment.
|
|
||||||
size_t pos = name.find_last_of('[');
|
size_t pos = name.find_last_of('[');
|
||||||
if (pos != TString::npos)
|
if (pos != TString::npos)
|
||||||
{
|
|
||||||
name = name.substr(0, pos);
|
name = name.substr(0, pos);
|
||||||
}
|
for (int index = static_cast<int>(var.arraySize) - 1; index >= 0; --index)
|
||||||
TType elementType = sh::GetShaderVariableBasicType(var);
|
|
||||||
TType arrayType = elementType;
|
|
||||||
arrayType.setArraySize(var.elementCount());
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < var.arraySize; ++i)
|
|
||||||
{
|
{
|
||||||
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, arrayType);
|
TIntermBinary *assign = new TIntermBinary(EOpAssign);
|
||||||
TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol,
|
sequence->insert(sequence->begin(), assign);
|
||||||
TIntermTyped::CreateIndexNode(i));
|
|
||||||
|
|
||||||
TIntermTyped *zero = TIntermTyped::CreateZero(elementType);
|
TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
|
||||||
TIntermBinary *assignment = new TIntermBinary(EOpAssign, element, zero);
|
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
|
||||||
|
indexDirect->setLeft(symbol);
|
||||||
|
TIntermConstantUnion *indexNode = constructIndexNode(index);
|
||||||
|
indexDirect->setRight(indexNode);
|
||||||
|
|
||||||
sequence->insert(sequence->begin(), assignment);
|
assign->setLeft(indexDirect);
|
||||||
|
|
||||||
|
TIntermConstantUnion *zeroConst = constructConstUnionNode(type);
|
||||||
|
assign->setRight(zeroConst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (var.isStruct())
|
else if (var.isStruct())
|
||||||
{
|
{
|
||||||
TVariable *structInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
|
TFieldList *fields = new TFieldList;
|
||||||
ASSERT(structInfo);
|
TSourceLoc loc;
|
||||||
|
for (auto field : var.fields)
|
||||||
|
{
|
||||||
|
fields->push_back(new TField(nullptr, new TString(field.name.c_str()), loc));
|
||||||
|
}
|
||||||
|
TStructure *structure = new TStructure(new TString(var.structName.c_str()), fields);
|
||||||
|
TType type;
|
||||||
|
type.setStruct(structure);
|
||||||
|
for (int fieldIndex = 0; fieldIndex < static_cast<int>(var.fields.size()); ++fieldIndex)
|
||||||
|
{
|
||||||
|
TIntermBinary *assign = new TIntermBinary(EOpAssign);
|
||||||
|
sequence->insert(sequence->begin(), assign);
|
||||||
|
|
||||||
TIntermSymbol *symbol = new TIntermSymbol(0, name, structInfo->getType());
|
TIntermBinary *indexDirectStruct = new TIntermBinary(EOpIndexDirectStruct);
|
||||||
TIntermTyped *zero = TIntermTyped::CreateZero(structInfo->getType());
|
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
|
||||||
|
indexDirectStruct->setLeft(symbol);
|
||||||
|
TIntermConstantUnion *indexNode = constructIndexNode(fieldIndex);
|
||||||
|
indexDirectStruct->setRight(indexNode);
|
||||||
|
assign->setLeft(indexDirectStruct);
|
||||||
|
|
||||||
TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
|
const sh::ShaderVariable &field = var.fields[fieldIndex];
|
||||||
sequence->insert(sequence->begin(), assign);
|
TType fieldType = sh::ConvertShaderVariableTypeToTType(field.type);
|
||||||
|
TIntermConstantUnion *zeroConst = constructConstUnionNode(fieldType);
|
||||||
|
assign->setRight(zeroConst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TType type = sh::GetShaderVariableBasicType(var);
|
TType type = sh::ConvertShaderVariableTypeToTType(var.type);
|
||||||
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
|
TIntermBinary *assign = new TIntermBinary(EOpAssign);
|
||||||
TIntermTyped *zero = TIntermTyped::CreateZero(type);
|
|
||||||
|
|
||||||
TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
|
|
||||||
sequence->insert(sequence->begin(), assign);
|
sequence->insert(sequence->begin(), assign);
|
||||||
|
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
|
||||||
|
assign->setLeft(symbol);
|
||||||
|
TIntermConstantUnion *zeroConst = constructConstUnionNode(type);
|
||||||
|
assign->setRight(zeroConst);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace anonymous
|
} // namespace anonymous
|
||||||
|
|
||||||
void InitializeVariables(TIntermNode *root,
|
void InitializeVariables(TIntermNode *root, const InitVariableList &vars)
|
||||||
const InitVariableList &vars,
|
|
||||||
const TSymbolTable &symbolTable)
|
|
||||||
{
|
{
|
||||||
VariableInitializer initializer(vars, symbolTable);
|
VariableInitializer initializer(vars);
|
||||||
root->traverse(&initializer);
|
root->traverse(&initializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sh
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue