mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-04 23:08:39 +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/linux/pkg_config.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//testing/libfuzzer/fuzzer_test.gni")
|
||||
import("//third_party/angle/gni/angle.gni")
|
||||
import("//third_party/angle/build/angle_common.gni")
|
||||
import("//ui/ozone/ozone.gni")
|
||||
|
||||
if (ozone_platform_gbm) {
|
||||
|
|
@ -55,7 +54,6 @@ config("extra_warnings") {
|
|||
cflags = [
|
||||
"/we4244", # Conversion: possible loss of data.
|
||||
"/we4456", # Variable shadowing.
|
||||
"/we4458", # declaration hides class member.
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -73,6 +71,22 @@ if (is_win) {
|
|||
|
||||
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.
|
||||
source_set("includes") {
|
||||
sources = [
|
||||
|
|
@ -96,14 +110,10 @@ static_library("preprocessor") {
|
|||
|
||||
configs -= angle_undefine_configs
|
||||
configs += [ ":internal_config" ]
|
||||
|
||||
public_deps = [
|
||||
":angle_common",
|
||||
]
|
||||
}
|
||||
|
||||
config("translator_disable_pool_alloc") {
|
||||
defines = [ "ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC" ]
|
||||
config("translator_static_config") {
|
||||
defines = [ "ANGLE_TRANSLATOR_STATIC" ]
|
||||
}
|
||||
|
||||
config("debug_annotations_config") {
|
||||
|
|
@ -162,33 +172,33 @@ static_library("angle_image_util") {
|
|||
]
|
||||
}
|
||||
|
||||
static_library("translator") {
|
||||
sources = rebase_path(compiler_gypi.angle_translator_sources, ".", "src")
|
||||
static_library("translator_lib") {
|
||||
sources = rebase_path(compiler_gypi.angle_translator_lib_sources, ".", "src")
|
||||
defines = []
|
||||
|
||||
if (angle_enable_essl || use_libfuzzer) {
|
||||
if (angle_enable_essl) {
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_essl_sources, ".", "src")
|
||||
rebase_path(compiler_gypi.angle_translator_lib_essl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_ESSL" ]
|
||||
}
|
||||
|
||||
if (angle_enable_glsl || use_libfuzzer) {
|
||||
if (angle_enable_glsl) {
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_glsl_sources, ".", "src")
|
||||
rebase_path(compiler_gypi.angle_translator_lib_glsl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_GLSL" ]
|
||||
}
|
||||
|
||||
if (angle_enable_hlsl || use_libfuzzer) {
|
||||
if (angle_enable_hlsl) {
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_hlsl_sources, ".", "src")
|
||||
rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_HLSL" ]
|
||||
}
|
||||
configs -= angle_undefine_configs
|
||||
configs += [ ":internal_config" ]
|
||||
configs += [
|
||||
":internal_config",
|
||||
":translator_static_config",
|
||||
]
|
||||
public_configs = [ ":external_config" ]
|
||||
if (use_libfuzzer) {
|
||||
all_dependent_configs = [ ":translator_disable_pool_alloc" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
":includes",
|
||||
|
|
@ -206,18 +216,22 @@ static_library("translator") {
|
|||
}
|
||||
}
|
||||
|
||||
source_set("translator_fuzzer") {
|
||||
static_library("translator_static") {
|
||||
sources = [
|
||||
"src/compiler/fuzz/translator_fuzzer.cpp",
|
||||
"src/compiler/translator/ShaderLang.cpp",
|
||||
"src/compiler/translator/ShaderVars.cpp",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"include",
|
||||
"src",
|
||||
]
|
||||
if (angle_enable_hlsl) {
|
||||
defines = [ "ANGLE_ENABLE_HLSL" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
":translator",
|
||||
configs -= angle_undefine_configs
|
||||
configs += [ ":internal_config" ]
|
||||
public_configs = [ ":translator_static_config" ]
|
||||
|
||||
public_deps = [
|
||||
":translator_lib",
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -271,13 +285,9 @@ config("libANGLE_config") {
|
|||
if (angle_enable_vulkan) {
|
||||
defines += [ "ANGLE_ENABLE_VULKAN" ]
|
||||
}
|
||||
if (angle_enable_null) {
|
||||
defines += [ "ANGLE_ENABLE_NULL" ]
|
||||
}
|
||||
defines += [
|
||||
"GL_GLEXT_PROTOTYPES",
|
||||
"EGL_EGLEXT_PROTOTYPES",
|
||||
"LIBANGLE_IMPLEMENTATION",
|
||||
]
|
||||
|
||||
if (is_win) {
|
||||
|
|
@ -301,7 +311,7 @@ static_library("libANGLE") {
|
|||
|
||||
include_dirs = []
|
||||
libs = []
|
||||
defines = []
|
||||
defines = [ "LIBANGLE_IMPLEMENTATION" ]
|
||||
public_deps = [
|
||||
":angle_common",
|
||||
]
|
||||
|
|
@ -309,7 +319,7 @@ static_library("libANGLE") {
|
|||
":angle_image_util",
|
||||
":commit_id",
|
||||
":includes",
|
||||
":translator",
|
||||
":translator_static",
|
||||
]
|
||||
|
||||
# Shared D3D sources.
|
||||
|
|
@ -379,10 +389,6 @@ static_library("libANGLE") {
|
|||
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) {
|
||||
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")
|
||||
|
||||
if (is_win) {
|
||||
|
|
@ -508,10 +514,6 @@ shared_library("angle_util") {
|
|||
|
||||
if (is_mac) {
|
||||
sources += rebase_path(util_gypi.util_osx_sources, ".", "util")
|
||||
libs = [
|
||||
"AppKit.framework",
|
||||
"QuartzCore.framework",
|
||||
]
|
||||
}
|
||||
|
||||
if (use_x11) {
|
||||
|
|
@ -536,7 +538,6 @@ shared_library("angle_util") {
|
|||
defines = [
|
||||
"GL_GLEXT_PROTOTYPES",
|
||||
"EGL_EGLEXT_PROTOTYPES",
|
||||
"LIBANGLE_UTIL_IMPLEMENTATION",
|
||||
]
|
||||
|
||||
configs += [
|
||||
|
|
@ -548,13 +549,6 @@ shared_library("angle_util") {
|
|||
":angle_util_config",
|
||||
":internal_config",
|
||||
]
|
||||
if (is_mac && !is_component_build) {
|
||||
ldflags = [
|
||||
"-install_name",
|
||||
"@rpath/lib${target_name}.dylib",
|
||||
]
|
||||
public_configs += [ ":shared_library_public_config" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
":angle_common",
|
||||
|
|
|
|||
|
|
@ -64,18 +64,12 @@ Intel Corporation
|
|||
Andy Chen
|
||||
Josh Triplett
|
||||
Sudarsana Nagineni
|
||||
Jiajia Qin
|
||||
Jiawei Shao
|
||||
Jie Chen
|
||||
Qiankun Miao
|
||||
Bryan Bernhart
|
||||
|
||||
Klarälvdalens Datakonsult AB
|
||||
Milian Wolff
|
||||
|
||||
Mozilla Corp.
|
||||
Ehsan Akhgari
|
||||
Edwin Flores
|
||||
Jeff Gilbert
|
||||
Mike Hommey
|
||||
Benoit Jacob
|
||||
|
|
|
|||
|
|
@ -3,30 +3,32 @@ vars = {
|
|||
}
|
||||
|
||||
deps = {
|
||||
'third_party/gyp':
|
||||
Var('chromium_git') + '/external/gyp' + '@' + '81c2e5ff92af29bab61c982808076ddce3d200a2',
|
||||
"third_party/gyp":
|
||||
Var('chromium_git') + "/external/gyp@81c2e5ff92af29bab61c982808076ddce3d200a2",
|
||||
|
||||
'testing/gtest':
|
||||
Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '6f8a66431cb592dad629028a50b3dd418a408c87',
|
||||
# TODO(kbr): figure out how to better stay in sync with Chromium's
|
||||
# versions of googletest and googlemock.
|
||||
"src/tests/third_party/googletest":
|
||||
Var('chromium_git') + "/external/googletest.git@9855a87157778d39b95eccfb201a9dc90f6d61c6",
|
||||
|
||||
'testing/gmock':
|
||||
Var('chromium_git') + '/external/googlemock.git' + '@' + '0421b6f358139f02e102c9c332ce19a33faf75be', # from svn revision 566
|
||||
"src/tests/third_party/googlemock":
|
||||
Var('chromium_git') + "/external/googlemock.git@b2cb211e49d872101d991201362d7b97d7d69910",
|
||||
|
||||
# Cherry is a dEQP management GUI written in Go. We use it for viewing test results.
|
||||
'third_party/cherry':
|
||||
'https://android.googlesource.com/platform/external/cherry' + '@' + 'd2e26b4d864ec2a6757e7f1174e464949ca5bf73',
|
||||
"third_party/cherry":
|
||||
"https://android.googlesource.com/platform/external/cherry@d2e26b4d864ec2a6757e7f1174e464949ca5bf73",
|
||||
|
||||
'third_party/deqp/src':
|
||||
'https://android.googlesource.com/platform/external/deqp' + '@' + 'f4f3d8079e7a37d7675ab93583e6438d0bca0e58',
|
||||
"third_party/deqp/src":
|
||||
"https://android.googlesource.com/platform/external/deqp@f4f3d8079e7a37d7675ab93583e6438d0bca0e58",
|
||||
|
||||
'third_party/libpng':
|
||||
'https://android.googlesource.com/platform/external/libpng' + '@' + '094e181e79a3d6c23fd005679025058b7df1ad6c',
|
||||
"third_party/libpng":
|
||||
"https://android.googlesource.com/platform/external/libpng@094e181e79a3d6c23fd005679025058b7df1ad6c",
|
||||
|
||||
'third_party/zlib':
|
||||
Var('chromium_git') + '/chromium/src/third_party/zlib' + '@' + 'afd8c4593c010c045902f6c0501718f1823064a3',
|
||||
"third_party/zlib":
|
||||
Var('chromium_git') + "/chromium/src/third_party/zlib@afd8c4593c010c045902f6c0501718f1823064a3",
|
||||
|
||||
'buildtools':
|
||||
Var('chromium_git') + '/chromium/buildtools.git' + '@' + '39b1db2ab4aa4b2ccaa263c29bdf63e7c1ee28aa',
|
||||
"buildtools":
|
||||
Var('chromium_git') + '/chromium/buildtools.git@06e80a0e17319868d4a9b13f9bb6a248dc8d8b20',
|
||||
}
|
||||
|
||||
hooks = [
|
||||
|
|
@ -100,12 +102,7 @@ hooks = [
|
|||
},
|
||||
{
|
||||
# A change to a .gyp, .gypi, or to GYP itself should run the generator.
|
||||
'pattern': '.',
|
||||
'action': ['python', 'gyp/gyp_angle'],
|
||||
"pattern": ".",
|
||||
"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
|
||||
#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
|
||||
#define EGL_ANGLE_query_surface_pointer 1
|
||||
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
|
||||
#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
|
||||
#define EGL_ANGLE_window_fixed_size 1
|
||||
#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
|
||||
#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 PFNEGLSTREAMPOSTD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
|
|
@ -577,16 +567,6 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, E
|
|||
#endif
|
||||
#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
|
||||
#define EGL_ARM_pixmap_multisample_discard 1
|
||||
#define EGL_DISCARD_SAMPLES_ARM 0x3286
|
||||
|
|
|
|||
|
|
@ -821,14 +821,6 @@ GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GL
|
|||
#endif
|
||||
#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
|
||||
#define GL_CHROMIUM_frambuffer_mixed_samples 1
|
||||
#define GL_COVERAGE_MODULATION_CHROMIUM 0x9332
|
||||
|
|
@ -838,11 +830,6 @@ GL_APICALL void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components);
|
|||
#endif
|
||||
#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)
|
||||
// but CHROMIUM_path_rendering only needs MatrixLoadfEXT, MatrixLoadIdentityEXT
|
||||
#ifndef GL_EXT_direct_state_access
|
||||
|
|
@ -1316,14 +1303,6 @@ GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM(GLuint sourceId,
|
|||
#endif
|
||||
#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
|
||||
#define GL_CHROMIUM_sync_query 1
|
||||
#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
|
||||
#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
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,6 +6,23 @@
|
|||
#ifndef 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 "KHR/khrplatform.h"
|
||||
|
|
@ -32,10 +49,9 @@ typedef unsigned int GLenum;
|
|||
|
||||
// Version number for shader translation API.
|
||||
// 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_WEBGL_SPEC,
|
||||
|
||||
|
|
@ -44,9 +60,31 @@ enum ShShaderSpec
|
|||
|
||||
SH_GLES3_1_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.
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
|
|
@ -65,171 +103,166 @@ enum ShShaderOutput
|
|||
SH_GLSL_440_CORE_OUTPUT = 0x8B87,
|
||||
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:
|
||||
SH_HLSL_3_0_OUTPUT = 0x8B48, // D3D 9
|
||||
SH_HLSL_4_1_OUTPUT = 0x8B49, // D3D 11
|
||||
SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A // D3D 11 feature level 9_3
|
||||
};
|
||||
} ShShaderOutput;
|
||||
|
||||
// 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;
|
||||
const ShCompileOptions SH_VALIDATE_LOOP_INDEXING = UINT64_C(1) << 0;
|
||||
const ShCompileOptions SH_INTERMEDIATE_TREE = UINT64_C(1) << 1;
|
||||
const ShCompileOptions SH_OBJECT_CODE = UINT64_C(1) << 2;
|
||||
const ShCompileOptions SH_VARIABLES = UINT64_C(1) << 3;
|
||||
const ShCompileOptions SH_LINE_DIRECTIVES = UINT64_C(1) << 4;
|
||||
const ShCompileOptions SH_SOURCE_PATH = UINT64_C(1) << 5;
|
||||
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 is an experimental flag to enforce restrictions that aim to prevent
|
||||
// timing attacks.
|
||||
// It generates compilation errors for shaders that could expose sensitive
|
||||
// texture information via the timing channel.
|
||||
// To use this flag, you must compile the shader under the WebGL spec
|
||||
// (using the SH_WEBGL_SPEC flag).
|
||||
SH_TIMING_RESTRICTIONS = 0x0200,
|
||||
|
||||
// This flag works around bug in Intel Mac drivers related to abs(i) where
|
||||
// i is an integer.
|
||||
const ShCompileOptions SH_EMULATE_ABS_INT_FUNCTION = UINT64_C(1) << 8;
|
||||
// This flag prints the dependency graph that is used to enforce timing
|
||||
// restrictions on fragment shaders.
|
||||
// This flag only has an effect if all of the following are true:
|
||||
// - The shader spec is SH_WEBGL_SPEC.
|
||||
// - The compile options contain the SH_TIMING_RESTRICTIONS flag.
|
||||
// - The shader type is GL_FRAGMENT_SHADER.
|
||||
SH_DEPENDENCY_GRAPH = 0x0400,
|
||||
|
||||
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
|
||||
// This flag only enforces (and can only enforce) the packing
|
||||
// restrictions for uniform variables in both vertex and fragment
|
||||
// shaders. ShCheckVariablesWithinPackingLimits() lets embedders
|
||||
// enforce the packing restrictions for varying variables during
|
||||
// program link time.
|
||||
const ShCompileOptions SH_ENFORCE_PACKING_RESTRICTIONS = UINT64_C(1) << 9;
|
||||
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
|
||||
// This flag only enforces (and can only enforce) the packing
|
||||
// restrictions for uniform variables in both vertex and fragment
|
||||
// shaders. ShCheckVariablesWithinPackingLimits() lets embedders
|
||||
// enforce the packing restrictions for varying variables during
|
||||
// program link time.
|
||||
SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800,
|
||||
|
||||
// This flag ensures all indirect (expression-based) array indexing
|
||||
// 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
|
||||
// vec234, or mat234 type. The ShArrayIndexClampingStrategy enum,
|
||||
// specified in the ShBuiltInResources when constructing the
|
||||
// compiler, selects the strategy for the clamping implementation.
|
||||
const ShCompileOptions SH_CLAMP_INDIRECT_ARRAY_BOUNDS = UINT64_C(1) << 10;
|
||||
// This flag ensures all indirect (expression-based) array indexing
|
||||
// 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
|
||||
// vec234, or mat234 type. The ShArrayIndexClampingStrategy enum,
|
||||
// specified in the ShBuiltInResources when constructing the
|
||||
// compiler, selects the strategy for the clamping implementation.
|
||||
SH_CLAMP_INDIRECT_ARRAY_BOUNDS = 0x1000,
|
||||
|
||||
// This flag limits the complexity of an expression.
|
||||
const ShCompileOptions SH_LIMIT_EXPRESSION_COMPLEXITY = UINT64_C(1) << 11;
|
||||
// This flag limits the complexity of an expression.
|
||||
SH_LIMIT_EXPRESSION_COMPLEXITY = 0x2000,
|
||||
|
||||
// This flag limits the depth of the call stack.
|
||||
const ShCompileOptions SH_LIMIT_CALL_STACK_DEPTH = UINT64_C(1) << 12;
|
||||
// This flag limits the depth of the call stack.
|
||||
SH_LIMIT_CALL_STACK_DEPTH = 0x4000,
|
||||
|
||||
// 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
|
||||
// fragment shader. It is intended as a workaround for drivers which
|
||||
// incorrectly fail to link programs if gl_Position is not written.
|
||||
const ShCompileOptions SH_INIT_GL_POSITION = UINT64_C(1) << 13;
|
||||
// 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
|
||||
// fragment shader. It is intended as a workaround for drivers which
|
||||
// incorrectly fail to link programs if gl_Position is not written.
|
||||
SH_INIT_GL_POSITION = 0x8000,
|
||||
|
||||
// This flag replaces
|
||||
// "a && b" with "a ? b : false",
|
||||
// "a || b" with "a ? true : b".
|
||||
// This is to work around a MacOSX driver bug that |b| is executed
|
||||
// independent of |a|'s value.
|
||||
const ShCompileOptions SH_UNFOLD_SHORT_CIRCUIT = UINT64_C(1) << 14;
|
||||
// This flag replaces
|
||||
// "a && b" with "a ? b : false",
|
||||
// "a || b" with "a ? true : b".
|
||||
// This is to work around a MacOSX driver bug that |b| is executed
|
||||
// independent of |a|'s value.
|
||||
SH_UNFOLD_SHORT_CIRCUIT = 0x10000,
|
||||
|
||||
// This flag initializes output variables to 0 at the beginning of main().
|
||||
// It is to avoid undefined behaviors.
|
||||
const ShCompileOptions SH_INIT_OUTPUT_VARIABLES = UINT64_C(1) << 15;
|
||||
// This flag initializes output variables to 0 at the beginning of main().
|
||||
// It is to avoid undefined behaviors.
|
||||
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.
|
||||
// It is intended as a workaround for Linux/Mac driver bugs.
|
||||
const ShCompileOptions SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = UINT64_C(1) << 16;
|
||||
// This flag scalarizes vec/ivec/bvec/mat constructor args.
|
||||
// It is intended as a workaround for Linux/Mac driver bugs.
|
||||
SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = 0x40000,
|
||||
|
||||
// This flag overwrites a struct name with a unique prefix.
|
||||
// It is intended as a workaround for drivers that do not handle
|
||||
// struct scopes correctly, including all Mac drivers and Linux AMD.
|
||||
const ShCompileOptions SH_REGENERATE_STRUCT_NAMES = UINT64_C(1) << 17;
|
||||
// This flag overwrites a struct name with a unique prefix.
|
||||
// It is intended as a workaround for drivers that do not handle
|
||||
// struct scopes correctly, including all Mac drivers and Linux AMD.
|
||||
SH_REGENERATE_STRUCT_NAMES = 0x80000,
|
||||
|
||||
// This flag makes the compiler not prune unused function early in the
|
||||
// compilation process. Pruning coupled with SH_LIMIT_CALL_STACK_DEPTH
|
||||
// helps avoid bad shaders causing stack overflows.
|
||||
const ShCompileOptions SH_DONT_PRUNE_UNUSED_FUNCTIONS = UINT64_C(1) << 18;
|
||||
// This flag makes the compiler not prune unused function early in the
|
||||
// compilation process. Pruning coupled with SH_LIMIT_CALL_STACK_DEPTH
|
||||
// helps avoid bad shaders causing stack overflows.
|
||||
SH_DONT_PRUNE_UNUSED_FUNCTIONS = 0x100000,
|
||||
|
||||
// This flag works around a bug in NVIDIA 331 series drivers related
|
||||
// to pow(x, y) where y is a constant vector.
|
||||
const ShCompileOptions SH_REMOVE_POW_WITH_CONSTANT_EXPONENT = UINT64_C(1) << 19;
|
||||
// This flag works around a bug in NVIDIA 331 series drivers related
|
||||
// to pow(x, y) where y is a constant vector.
|
||||
SH_REMOVE_POW_WITH_CONSTANT_EXPONENT = 0x200000,
|
||||
|
||||
// This flag works around bugs in Mac drivers related to do-while by
|
||||
// transforming them into an other construct.
|
||||
const ShCompileOptions SH_REWRITE_DO_WHILE_LOOPS = UINT64_C(1) << 20;
|
||||
// This flag works around bugs in Mac drivers related to do-while by
|
||||
// transforming them into an other construct.
|
||||
SH_REWRITE_DO_WHILE_LOOPS = 0x400000,
|
||||
|
||||
// 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
|
||||
// by expanding the integer pow expressions into a series of multiplies.
|
||||
const ShCompileOptions SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS = UINT64_C(1) << 21;
|
||||
// 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
|
||||
// by expanding the integer pow expressions into a series of multiplies.
|
||||
SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS = 0x800000,
|
||||
|
||||
// Flatten "#pragma STDGL invariant(all)" into the declarations of
|
||||
// varying variables and built-in GLSL variables. This compiler
|
||||
// option is enabled automatically when needed.
|
||||
const ShCompileOptions SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL = UINT64_C(1) << 22;
|
||||
// Flatten "#pragma STDGL invariant(all)" into the declarations of
|
||||
// varying variables and built-in GLSL variables. This compiler
|
||||
// option is enabled automatically when needed.
|
||||
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
|
||||
// HLSL GetDimensions builtin. This flag instructs the compiler to manually add the base level
|
||||
// offsetting.
|
||||
const ShCompileOptions SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL = UINT64_C(1) << 23;
|
||||
// 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
|
||||
// offsetting.
|
||||
SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL = 0x2000000,
|
||||
|
||||
// This flag works around an issue in translating GLSL function texelFetchOffset on
|
||||
// INTEL drivers. It works by translating texelFetchOffset into texelFetch.
|
||||
const ShCompileOptions SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH = UINT64_C(1) << 24;
|
||||
|
||||
// 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;
|
||||
// This flag works around an issue in translating GLSL function texelFetchOffset on
|
||||
// INTEL drivers. It works by translating texelFetchOffset into texelFetch.
|
||||
SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH = 0x4000000,
|
||||
} ShCompileOptions;
|
||||
|
||||
// Defines alternate strategies for implementing array index clamping.
|
||||
enum ShArrayIndexClampingStrategy
|
||||
{
|
||||
// Use the clamp intrinsic for array index clamping.
|
||||
SH_CLAMP_WITH_CLAMP_INTRINSIC = 1,
|
||||
typedef enum {
|
||||
// Use the clamp intrinsic for array index clamping.
|
||||
SH_CLAMP_WITH_CLAMP_INTRINSIC = 1,
|
||||
|
||||
// Use a user-defined function for array index clamping.
|
||||
SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION
|
||||
};
|
||||
// Use a user-defined function for array index clamping.
|
||||
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
|
||||
// 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).
|
||||
// The names for these resources has been obtained by stripping gl_/GL_.
|
||||
//
|
||||
struct ShBuiltInResources
|
||||
typedef struct
|
||||
{
|
||||
// Constants.
|
||||
int MaxVertexAttribs;
|
||||
|
|
@ -361,7 +394,15 @@ struct ShBuiltInResources
|
|||
|
||||
// maximum number of buffer object storage in machine units
|
||||
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,
|
||||
|
|
@ -370,26 +411,7 @@ struct ShBuiltInResources
|
|||
//
|
||||
// If handle creation fails, 0 will be returned.
|
||||
//
|
||||
using ShHandle = void *;
|
||||
|
||||
//
|
||||
// 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);
|
||||
typedef void *ShHandle;
|
||||
|
||||
//
|
||||
// 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.
|
||||
// Parameters:
|
||||
// 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.
|
||||
|
|
@ -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
|
||||
// be supported in some configurations.
|
||||
// resources: Specifies the built-in resources.
|
||||
ShHandle ShConstructCompiler(sh::GLenum type,
|
||||
ShShaderSpec spec,
|
||||
ShShaderOutput output,
|
||||
const ShBuiltInResources *resources);
|
||||
void ShDestruct(ShHandle handle);
|
||||
COMPILER_EXPORT ShHandle ShConstructCompiler(
|
||||
sh::GLenum type,
|
||||
ShShaderSpec spec,
|
||||
ShShaderOutput output,
|
||||
const ShBuiltInResources *resources);
|
||||
COMPILER_EXPORT void ShDestruct(ShHandle handle);
|
||||
|
||||
//
|
||||
// Compiles the given shader source.
|
||||
|
|
@ -436,42 +459,45 @@ void ShDestruct(ShHandle handle);
|
|||
// 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().
|
||||
// Can be queried by calling ShGetInfoLog().
|
||||
// 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.
|
||||
// Can be queried by calling ShGetVariableInfo().
|
||||
//
|
||||
bool ShCompile(const ShHandle handle,
|
||||
const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
ShCompileOptions compileOptions);
|
||||
COMPILER_EXPORT bool ShCompile(
|
||||
const ShHandle handle,
|
||||
const char * const shaderStrings[],
|
||||
size_t numStrings,
|
||||
int compileOptions);
|
||||
|
||||
// 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.
|
||||
int ShGetShaderVersion(const ShHandle handle);
|
||||
COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle);
|
||||
|
||||
// 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.
|
||||
// Parameters:
|
||||
// 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.
|
||||
// Parameters:
|
||||
// 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
|
||||
// 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> *ShGetNameHashingMap(const ShHandle handle);
|
||||
COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
|
||||
const ShHandle handle);
|
||||
|
||||
// Shader variable inspection.
|
||||
// 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.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle);
|
||||
const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle);
|
||||
const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle);
|
||||
const std::vector<sh::OutputVariable> *ShGetOutputVariables(const ShHandle handle);
|
||||
const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle);
|
||||
sh::WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle);
|
||||
COMPILER_EXPORT const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle);
|
||||
COMPILER_EXPORT const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle);
|
||||
COMPILER_EXPORT const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle);
|
||||
COMPILER_EXPORT const std::vector<sh::OutputVariable> *ShGetOutputVariables(const ShHandle handle);
|
||||
COMPILER_EXPORT const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(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
|
||||
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
|
||||
|
|
@ -493,8 +525,9 @@ sh::WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle);
|
|||
// Parameters:
|
||||
// maxVectors: the available rows of registers.
|
||||
// variables: an array of variables.
|
||||
bool ShCheckVariablesWithinPackingLimits(int maxVectors,
|
||||
const std::vector<sh::ShaderVariable> &variables);
|
||||
COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
|
||||
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".
|
||||
|
|
@ -503,155 +536,14 @@ bool ShCheckVariablesWithinPackingLimits(int maxVectors,
|
|||
// handle: Specifies the compiler
|
||||
// interfaceBlockName: Specifies the interface block
|
||||
// indexOut: output variable that stores the assigned register
|
||||
bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
const std::string &interfaceBlockName,
|
||||
unsigned int *indexOut);
|
||||
COMPILER_EXPORT bool ShGetInterfaceBlockRegister(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> *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
|
||||
COMPILER_EXPORT const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(
|
||||
const ShHandle handle);
|
||||
|
||||
#endif // GLSLANG_SHADERLANG_H_
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ enum InterpolationType
|
|||
};
|
||||
|
||||
// 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
|
||||
enum BlockLayoutType
|
||||
|
|
@ -43,7 +43,7 @@ enum BlockLayoutType
|
|||
// Note: we must override the copy constructor and assignment operator so we can
|
||||
// work around excessive GCC binary bloating:
|
||||
// See https://code.google.com/p/angleproject/issues/detail?id=697
|
||||
struct ShaderVariable
|
||||
struct COMPILER_EXPORT ShaderVariable
|
||||
{
|
||||
ShaderVariable();
|
||||
ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
|
||||
|
|
@ -92,7 +92,7 @@ struct ShaderVariable
|
|||
}
|
||||
};
|
||||
|
||||
struct Uniform : public ShaderVariable
|
||||
struct COMPILER_EXPORT Uniform : public ShaderVariable
|
||||
{
|
||||
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
|
||||
// shader execution: either vertex shader inputs or fragment shader outputs. These variables can
|
||||
// have integer locations to pass back to the GL API.
|
||||
struct InterfaceVariable : public ShaderVariable
|
||||
struct COMPILER_EXPORT InterfaceVariable : public ShaderVariable
|
||||
{
|
||||
InterfaceVariable();
|
||||
~InterfaceVariable();
|
||||
|
|
@ -125,7 +125,7 @@ struct InterfaceVariable : public ShaderVariable
|
|||
int location;
|
||||
};
|
||||
|
||||
struct Attribute : public InterfaceVariable
|
||||
struct COMPILER_EXPORT Attribute : public InterfaceVariable
|
||||
{
|
||||
Attribute();
|
||||
~Attribute();
|
||||
|
|
@ -135,7 +135,7 @@ struct Attribute : public InterfaceVariable
|
|||
bool operator!=(const Attribute &other) const { return !operator==(other); }
|
||||
};
|
||||
|
||||
struct OutputVariable : public InterfaceVariable
|
||||
struct COMPILER_EXPORT OutputVariable : public InterfaceVariable
|
||||
{
|
||||
OutputVariable();
|
||||
~OutputVariable();
|
||||
|
|
@ -145,7 +145,7 @@ struct OutputVariable : public InterfaceVariable
|
|||
bool operator!=(const OutputVariable &other) const { return !operator==(other); }
|
||||
};
|
||||
|
||||
struct InterfaceBlockField : public ShaderVariable
|
||||
struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
|
||||
{
|
||||
InterfaceBlockField();
|
||||
~InterfaceBlockField();
|
||||
|
|
@ -167,7 +167,7 @@ struct InterfaceBlockField : public ShaderVariable
|
|||
bool isRowMajorLayout;
|
||||
};
|
||||
|
||||
struct Varying : public ShaderVariable
|
||||
struct COMPILER_EXPORT Varying : public ShaderVariable
|
||||
{
|
||||
Varying();
|
||||
~Varying();
|
||||
|
|
@ -193,7 +193,7 @@ struct Varying : public ShaderVariable
|
|||
bool isInvariant;
|
||||
};
|
||||
|
||||
struct InterfaceBlock
|
||||
struct COMPILER_EXPORT InterfaceBlock
|
||||
{
|
||||
InterfaceBlock();
|
||||
~InterfaceBlock();
|
||||
|
|
@ -216,7 +216,7 @@ struct InterfaceBlock
|
|||
std::vector<InterfaceBlockField> fields;
|
||||
};
|
||||
|
||||
struct WorkGroupSize
|
||||
struct COMPILER_EXPORT WorkGroupSize
|
||||
{
|
||||
void fill(int fillValue);
|
||||
void setLocalSize(int localSizeX, int localSizeY, int localSizeZ);
|
||||
|
|
|
|||
|
|
@ -10,15 +10,13 @@
|
|||
#define LIBGLESV2_EXPORT_H_
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) || \
|
||||
defined(LIBANGLE_UTIL_IMPLEMENTATION)
|
||||
# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION)
|
||||
# define ANGLE_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define ANGLE_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
#if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) || \
|
||||
defined(LIBANGLE_UTIL_IMPLEMENTATION)
|
||||
# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION)
|
||||
# define ANGLE_EXPORT __attribute__((visibility ("default")))
|
||||
# else
|
||||
# define ANGLE_EXPORT
|
||||
|
|
|
|||
|
|
@ -28,13 +28,11 @@ UNIFIED_SOURCES += [
|
|||
'src/compiler/preprocessor/Preprocessor.cpp',
|
||||
'src/compiler/preprocessor/Token.cpp',
|
||||
'src/compiler/preprocessor/Tokenizer.cpp',
|
||||
'src/compiler/translator/AddAndTrueToLoopCondition.cpp',
|
||||
'src/compiler/translator/AddDefaultReturnStatements.cpp',
|
||||
'src/compiler/translator/ArrayReturnValueToOutParameter.cpp',
|
||||
'src/compiler/translator/ASTMetadataHLSL.cpp',
|
||||
'src/compiler/translator/blocklayout.cpp',
|
||||
'src/compiler/translator/blocklayoutHLSL.cpp',
|
||||
'src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp',
|
||||
'src/compiler/translator/BuiltInFunctionEmulator.cpp',
|
||||
'src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
|
||||
'src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp',
|
||||
|
|
@ -42,8 +40,11 @@ UNIFIED_SOURCES += [
|
|||
'src/compiler/translator/CallDAG.cpp',
|
||||
'src/compiler/translator/CodeGen.cpp',
|
||||
'src/compiler/translator/Compiler.cpp',
|
||||
'src/compiler/translator/ConstantUnion.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/DirectiveHandler.cpp',
|
||||
'src/compiler/translator/EmulatePrecision.cpp',
|
||||
|
|
@ -70,27 +71,28 @@ UNIFIED_SOURCES += [
|
|||
'src/compiler/translator/ParseContext.cpp',
|
||||
'src/compiler/translator/PoolAlloc.cpp',
|
||||
'src/compiler/translator/PruneEmptyDeclarations.cpp',
|
||||
'src/compiler/translator/QualifierTypes.cpp',
|
||||
'src/compiler/translator/RecordConstantPrecision.cpp',
|
||||
'src/compiler/translator/RegenerateStructNames.cpp',
|
||||
'src/compiler/translator/RemoveDynamicIndexing.cpp',
|
||||
'src/compiler/translator/RemoveInvariantDeclaration.cpp',
|
||||
'src/compiler/translator/RemovePow.cpp',
|
||||
'src/compiler/translator/RemoveSwitchFallThrough.cpp',
|
||||
'src/compiler/translator/RewriteDoWhile.cpp',
|
||||
'src/compiler/translator/RewriteElseBlocks.cpp',
|
||||
'src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
|
||||
'src/compiler/translator/RewriteTexelFetchOffset.cpp',
|
||||
'src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
|
||||
'src/compiler/translator/SearchSymbol.cpp',
|
||||
'src/compiler/translator/SeparateArrayInitialization.cpp',
|
||||
'src/compiler/translator/SeparateDeclarations.cpp',
|
||||
'src/compiler/translator/SeparateExpressionsReturningArrays.cpp',
|
||||
'src/compiler/translator/ShaderLang.cpp',
|
||||
'src/compiler/translator/ShaderVars.cpp',
|
||||
'src/compiler/translator/SimplifyLoopConditions.cpp',
|
||||
'src/compiler/translator/SplitSequenceOperator.cpp',
|
||||
'src/compiler/translator/StructureHLSL.cpp',
|
||||
'src/compiler/translator/SymbolTable.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/TranslatorGLSL.cpp',
|
||||
'src/compiler/translator/TranslatorHLSL.cpp',
|
||||
|
|
@ -98,7 +100,6 @@ UNIFIED_SOURCES += [
|
|||
'src/compiler/translator/UnfoldShortCircuitAST.cpp',
|
||||
'src/compiler/translator/UnfoldShortCircuitToIf.cpp',
|
||||
'src/compiler/translator/UniformHLSL.cpp',
|
||||
'src/compiler/translator/UseInterfaceBlockFields.cpp',
|
||||
'src/compiler/translator/util.cpp',
|
||||
'src/compiler/translator/UtilsHLSL.cpp',
|
||||
'src/compiler/translator/ValidateGlobalInitializer.cpp',
|
||||
|
|
@ -115,8 +116,6 @@ SOURCES += [
|
|||
'src/compiler/translator/EmulateGLFragColorBroadcast.cpp',
|
||||
'src/compiler/translator/glslang_lex.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_null%': 1, # Available on all platforms
|
||||
},
|
||||
'includes':
|
||||
[
|
||||
|
|
@ -59,7 +58,7 @@
|
|||
{
|
||||
'target_name': 'angle_common',
|
||||
'type': 'static_library',
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'includes': [ '../build/common_defines.gypi', ],
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_common_sources)',
|
||||
|
|
@ -146,7 +145,7 @@
|
|||
{
|
||||
'target_name': 'angle_image_util',
|
||||
'type': 'static_library',
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'includes': [ '../build/common_defines.gypi', ],
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_image_util_sources)',
|
||||
|
|
@ -173,7 +172,7 @@
|
|||
{
|
||||
'target_name': 'copy_scripts',
|
||||
'type': 'none',
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'includes': [ '../build/common_defines.gypi', ],
|
||||
'hard_dependency': 1,
|
||||
'copies':
|
||||
[
|
||||
|
|
@ -200,7 +199,7 @@
|
|||
{
|
||||
'target_name': 'commit_id',
|
||||
'type': 'none',
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'includes': [ '../build/common_defines.gypi', ],
|
||||
'dependencies': [ 'copy_scripts', ],
|
||||
'hard_dependency': 1,
|
||||
'actions':
|
||||
|
|
@ -242,7 +241,7 @@
|
|||
'target_name': 'commit_id',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'includes': [ '../build/common_defines.gypi', ],
|
||||
'copies':
|
||||
[
|
||||
{
|
||||
|
|
@ -275,7 +274,7 @@
|
|||
'target_name': 'copy_compiler_dll',
|
||||
'type': 'none',
|
||||
'dependencies': [ 'copy_scripts', ],
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'includes': [ '../build/common_defines.gypi', ],
|
||||
'conditions':
|
||||
[
|
||||
['angle_build_winrt==0',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#define ANGLE_COMMIT_HASH "2a250c8a0e15"
|
||||
#define ANGLE_COMMIT_HASH_SIZE 12
|
||||
#define ANGLE_COMMIT_DATE "2016-11-23 17:58:16 +0800"
|
||||
#define ANGLE_COMMIT_HASH ""
|
||||
#define ANGLE_COMMIT_HASH_SIZE 12
|
||||
#define ANGLE_COMMIT_DATE ""
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ inline unsigned long ScanForward(unsigned long bits)
|
|||
unsigned long firstBitIndex = 0ul;
|
||||
unsigned char ret = _BitScanForward(&firstBitIndex, bits);
|
||||
ASSERT(ret != 0);
|
||||
UNUSED_ASSERTION_VARIABLE(ret);
|
||||
return firstBitIndex;
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
return static_cast<unsigned long>(__builtin_ctzl(bits));
|
||||
|
|
|
|||
|
|
@ -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, ...);
|
||||
|
||||
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
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#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();
|
||||
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)
|
||||
#define ANGLE_TRACE_ENABLED
|
||||
|
|
@ -117,58 +104,61 @@ std::ostream &DummyStream();
|
|||
#undef ANGLE_TRACE_ENABLED
|
||||
#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)
|
||||
#define ANGLE_ASSERT_IMPL(expression) assert(expression)
|
||||
#else
|
||||
// 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)
|
||||
|
||||
// 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
|
||||
#if ANGLE_ASSERTS_ON
|
||||
#define ASSERT(expression) \
|
||||
(expression ? static_cast<void>(0) \
|
||||
: (ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression), \
|
||||
ANGLE_ASSERT_IMPL(expression)))
|
||||
#if defined(ANGLE_ENABLE_ASSERTS)
|
||||
#define ASSERT(expression) \
|
||||
{ \
|
||||
if (!(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
|
||||
#define ASSERT(condition) \
|
||||
ANGLE_LAZY_STREAM(::gl::DummyStream(), ANGLE_ASSERTS_ON ? !(condition) : false) \
|
||||
<< "Check failed: " #condition ". "
|
||||
#endif // ANGLE_ASSERTS_ON
|
||||
#define ASSERT(expression) (void(0))
|
||||
#define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
|
||||
#endif
|
||||
|
||||
#define UNUSED_VARIABLE(variable) ((void)variable)
|
||||
|
||||
// A macro to indicate unimplemented functionality
|
||||
#ifndef NOASSERT_UNIMPLEMENTED
|
||||
|
||||
#if defined (ANGLE_TEST_CONFIG)
|
||||
#define NOASSERT_UNIMPLEMENTED 1
|
||||
#endif
|
||||
|
||||
#define UNIMPLEMENTED() \
|
||||
{ \
|
||||
ERR("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \
|
||||
ASSERT(NOASSERT_UNIMPLEMENTED); \
|
||||
} \
|
||||
ANGLE_EMPTY_STATEMENT
|
||||
// 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
|
||||
#ifndef NOASSERT_UNIMPLEMENTED
|
||||
#define NOASSERT_UNIMPLEMENTED 0
|
||||
#endif
|
||||
|
||||
#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
|
||||
#define UNREACHABLE() \
|
||||
(ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__), ASSERT(false))
|
||||
#if !defined(NDEBUG)
|
||||
#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_
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@
|
|||
namespace gl
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct RGB9E5Data
|
||||
{
|
||||
unsigned int R : 9;
|
||||
|
|
@ -26,20 +23,17 @@ struct RGB9E5Data
|
|||
};
|
||||
|
||||
// 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)
|
||||
constexpr int g_sharedexp_mantissabits = 9;
|
||||
static const int g_sharedexp_mantissabits = 9;
|
||||
|
||||
// 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_cast<float>(1 << g_sharedexp_mantissabits) - 1) /
|
||||
static_cast<float>(1 << g_sharedexp_mantissabits)) *
|
||||
static_cast<float>(1 << (g_sharedexp_maxexponent - g_sharedexp_bias));
|
||||
|
||||
} // anonymous namespace
|
||||
static const float g_sharedexp_max = ((pow(2.0f, g_sharedexp_mantissabits) - 1) /
|
||||
pow(2.0f, g_sharedexp_mantissabits)) *
|
||||
pow(2.0f, g_sharedexp_maxexponent - g_sharedexp_bias);
|
||||
|
||||
unsigned int convertRGBFloatsTo999E5(float red, float green, float blue)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,15 +44,6 @@ struct Vector4
|
|||
float w;
|
||||
};
|
||||
|
||||
struct Vector2
|
||||
{
|
||||
Vector2() {}
|
||||
Vector2(float x, float y) : x(x), y(y) {}
|
||||
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
inline bool isPow2(int x)
|
||||
{
|
||||
return (x & (x - 1)) == 0 && (x != 0);
|
||||
|
|
@ -765,40 +756,6 @@ constexpr unsigned int iSquareRoot()
|
|||
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 rx
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
// Unfortunately ANGLE relies on ASSERT being an empty statement, which these libs don't respect.
|
||||
#ifndef NOTREACHED
|
||||
#define NOTREACHED() UNREACHABLE()
|
||||
#define NOTREACHED() 0
|
||||
#endif
|
||||
|
||||
#endif // BASE_LOGGING_H_
|
||||
#endif // BASE_LOGGING_H_
|
||||
|
|
@ -92,7 +92,7 @@ struct StaticDstRangeRelationToSrcRange<Dst,
|
|||
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_UNDERFLOW = 0x1, // Value would overflow.
|
||||
|
|
|
|||
|
|
@ -247,19 +247,7 @@ int VariableRowCount(GLenum type)
|
|||
case GL_SAMPLER_2D_SHADOW:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
case GL_IMAGE_2D:
|
||||
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;
|
||||
return 1;
|
||||
case GL_FLOAT_MAT2:
|
||||
case GL_FLOAT_MAT3x2:
|
||||
case GL_FLOAT_MAT4x2:
|
||||
|
|
@ -656,29 +644,6 @@ std::string ParseUniformName(const std::string &name, size_t *outSubscript)
|
|||
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 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 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);
|
||||
|
||||
} // namespace gl
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
'variables':
|
||||
{
|
||||
# These file lists are shared with the GN build.
|
||||
'angle_translator_sources':
|
||||
'angle_translator_lib_sources':
|
||||
[
|
||||
'../include/EGL/egl.h',
|
||||
'../include/EGL/eglext.h',
|
||||
|
|
@ -22,13 +22,9 @@
|
|||
'../include/GLSLANG/ShaderVars.h',
|
||||
'../include/KHR/khrplatform.h',
|
||||
'../include/angle_gl.h',
|
||||
'compiler/translator/AddAndTrueToLoopCondition.cpp',
|
||||
'compiler/translator/AddAndTrueToLoopCondition.h',
|
||||
'compiler/translator/BaseTypes.h',
|
||||
'compiler/translator/BuiltInFunctionEmulator.cpp',
|
||||
'compiler/translator/BuiltInFunctionEmulator.h',
|
||||
'compiler/translator/BreakVariableAliasingInInnerLoops.cpp',
|
||||
'compiler/translator/BreakVariableAliasingInInnerLoops.h',
|
||||
'compiler/translator/Cache.cpp',
|
||||
'compiler/translator/Cache.h',
|
||||
'compiler/translator/CallDAG.cpp',
|
||||
|
|
@ -37,7 +33,6 @@
|
|||
'compiler/translator/Common.h',
|
||||
'compiler/translator/Compiler.cpp',
|
||||
'compiler/translator/Compiler.h',
|
||||
'compiler/translator/ConstantUnion.cpp',
|
||||
'compiler/translator/ConstantUnion.h',
|
||||
'compiler/translator/DeferGlobalInitializers.cpp',
|
||||
'compiler/translator/DeferGlobalInitializers.h',
|
||||
|
|
@ -86,36 +81,27 @@
|
|||
'compiler/translator/Pragma.h',
|
||||
'compiler/translator/PruneEmptyDeclarations.cpp',
|
||||
'compiler/translator/PruneEmptyDeclarations.h',
|
||||
'compiler/translator/QualifierTypes.h',
|
||||
'compiler/translator/QualifierTypes.cpp',
|
||||
'compiler/translator/RecordConstantPrecision.cpp',
|
||||
'compiler/translator/RecordConstantPrecision.h',
|
||||
'compiler/translator/RegenerateStructNames.cpp',
|
||||
'compiler/translator/RegenerateStructNames.h',
|
||||
'compiler/translator/RemoveInvariantDeclaration.cpp',
|
||||
'compiler/translator/RemoveInvariantDeclaration.h',
|
||||
'compiler/translator/RemovePow.cpp',
|
||||
'compiler/translator/RemovePow.h',
|
||||
'compiler/translator/RewriteDoWhile.cpp',
|
||||
'compiler/translator/RewriteDoWhile.h',
|
||||
'compiler/translator/RewriteTexelFetchOffset.cpp',
|
||||
'compiler/translator/RewriteTexelFetchOffset.h',
|
||||
'compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
|
||||
'compiler/translator/RewriteUnaryMinusOperatorInt.h',
|
||||
'compiler/translator/RenameFunction.h',
|
||||
'compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
|
||||
'compiler/translator/ScalarizeVecAndMatConstructorArgs.h',
|
||||
'compiler/translator/SearchSymbol.cpp',
|
||||
'compiler/translator/SearchSymbol.h',
|
||||
'compiler/translator/ShaderLang.cpp',
|
||||
'compiler/translator/ShaderVars.cpp',
|
||||
'compiler/translator/SymbolTable.cpp',
|
||||
'compiler/translator/SymbolTable.h',
|
||||
'compiler/translator/Types.cpp',
|
||||
'compiler/translator/Types.h',
|
||||
'compiler/translator/UnfoldShortCircuitAST.cpp',
|
||||
'compiler/translator/UnfoldShortCircuitAST.h',
|
||||
'compiler/translator/UseInterfaceBlockFields.cpp',
|
||||
'compiler/translator/UseInterfaceBlockFields.h',
|
||||
'compiler/translator/ValidateGlobalInitializer.cpp',
|
||||
'compiler/translator/ValidateGlobalInitializer.h',
|
||||
'compiler/translator/ValidateLimitations.cpp',
|
||||
|
|
@ -132,6 +118,13 @@
|
|||
'compiler/translator/VariablePacker.h',
|
||||
'compiler/translator/blocklayout.cpp',
|
||||
'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.l',
|
||||
'compiler/translator/glslang.y',
|
||||
|
|
@ -140,19 +133,23 @@
|
|||
'compiler/translator/glslang_tab.h',
|
||||
'compiler/translator/intermOut.cpp',
|
||||
'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.h',
|
||||
'third_party/compiler/ArrayBoundsClamper.cpp',
|
||||
'third_party/compiler/ArrayBoundsClamper.h',
|
||||
],
|
||||
'angle_translator_essl_sources':
|
||||
'angle_translator_lib_essl_sources':
|
||||
[
|
||||
'compiler/translator/OutputESSL.cpp',
|
||||
'compiler/translator/OutputESSL.h',
|
||||
'compiler/translator/TranslatorESSL.cpp',
|
||||
'compiler/translator/TranslatorESSL.h',
|
||||
],
|
||||
'angle_translator_glsl_sources':
|
||||
'angle_translator_lib_glsl_sources':
|
||||
[
|
||||
'compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
|
||||
'compiler/translator/BuiltInFunctionEmulatorGLSL.h',
|
||||
|
|
@ -167,7 +164,7 @@
|
|||
'compiler/translator/VersionGLSL.cpp',
|
||||
'compiler/translator/VersionGLSL.h',
|
||||
],
|
||||
'angle_translator_hlsl_sources':
|
||||
'angle_translator_lib_hlsl_sources':
|
||||
[
|
||||
'compiler/translator/AddDefaultReturnStatements.cpp',
|
||||
'compiler/translator/AddDefaultReturnStatements.h',
|
||||
|
|
@ -240,6 +237,7 @@
|
|||
'compiler/preprocessor/Tokenizer.h',
|
||||
'compiler/preprocessor/Tokenizer.l',
|
||||
'compiler/preprocessor/numeric_lex.h',
|
||||
'compiler/preprocessor/pp_utils.h',
|
||||
],
|
||||
},
|
||||
# Everything below this is duplicated in the GN build. If you change
|
||||
|
|
@ -249,23 +247,28 @@
|
|||
{
|
||||
'target_name': 'preprocessor',
|
||||
'type': 'static_library',
|
||||
'dependencies': [ 'angle_common' ],
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'includes': [ '../build/common_defines.gypi', ],
|
||||
'sources': [ '<@(angle_preprocessor_sources)', ],
|
||||
},
|
||||
{
|
||||
'target_name': 'translator',
|
||||
'target_name': 'translator_lib',
|
||||
'type': 'static_library',
|
||||
'dependencies': [ 'preprocessor', 'angle_common' ],
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'includes': [ '../build/common_defines.gypi', ],
|
||||
'include_dirs':
|
||||
[
|
||||
'.',
|
||||
'../include',
|
||||
],
|
||||
'defines':
|
||||
[
|
||||
# define the static translator to indicate exported
|
||||
# classes are (in fact) locally defined
|
||||
'ANGLE_TRANSLATOR_STATIC',
|
||||
],
|
||||
'sources':
|
||||
[
|
||||
'<@(angle_translator_sources)',
|
||||
'<@(angle_translator_lib_sources)',
|
||||
],
|
||||
'msvs_settings':
|
||||
{
|
||||
|
|
@ -291,7 +294,7 @@
|
|||
},
|
||||
'sources':
|
||||
[
|
||||
'<@(angle_translator_essl_sources)',
|
||||
'<@(angle_translator_lib_essl_sources)',
|
||||
],
|
||||
}],
|
||||
['angle_enable_glsl==1',
|
||||
|
|
@ -309,7 +312,7 @@
|
|||
},
|
||||
'sources':
|
||||
[
|
||||
'<@(angle_translator_glsl_sources)',
|
||||
'<@(angle_translator_lib_glsl_sources)',
|
||||
],
|
||||
}],
|
||||
['angle_enable_hlsl==1',
|
||||
|
|
@ -327,10 +330,59 @@
|
|||
},
|
||||
'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
|
||||
+++ b/src/compiler/preprocessor/Tokenizer.cpp
|
||||
@@ -1703,7 +1703,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;
|
||||
+ static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1);
|
||||
|
||||
while ( num_to_read <= 0 )
|
||||
{ /* Not enough room in the buffer - grow it. */
|
||||
@@ -1737,8 +1737,8 @@ 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;
|
||||
+ num_to_read = static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
|
||||
+ number_to_move - 1);
|
||||
|
||||
}
|
||||
|
||||
@@ -1746,8 +1746,10 @@ static int yy_get_next_buffer (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)
|
||||
@@ -56,6 +56,7 @@ typedef int16_t flex_int16_t;
|
||||
typedef uint16_t flex_uint16_t;
|
||||
typedef int32_t flex_int32_t;
|
||||
typedef uint32_t flex_uint32_t;
|
||||
+typedef uint64_t flex_uint64_t;
|
||||
#else
|
||||
typedef signed char flex_int8_t;
|
||||
typedef short int flex_int16_t;
|
||||
@@ -179,6 +180,11 @@ typedef void* yyscan_t;
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
#endif
|
||||
|
||||
+#ifndef YY_TYPEDEF_YY_SIZE_T
|
||||
+#define YY_TYPEDEF_YY_SIZE_T
|
||||
+typedef size_t yy_size_t;
|
||||
+#endif
|
||||
+
|
||||
#define EOB_ACT_CONTINUE_SCAN 0
|
||||
#define EOB_ACT_END_OF_FILE 1
|
||||
#define EOB_ACT_LAST_MATCH 2
|
||||
@@ -353,7 +354,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
|
||||
*/
|
||||
static void ppensure_buffer_stack (yyscan_t yyscanner)
|
||||
{
|
||||
- int num_to_alloc;
|
||||
+ yy_size_t num_to_alloc;
|
||||
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
|
||||
|
||||
if (!yyg->yy_buffer_stack) {
|
||||
@@ -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;
|
||||
#define YY_DO_BEFORE_ACTION \
|
||||
yyg->yytext_ptr = yy_bp; \
|
||||
- yyleng = (size_t) (yy_cp - yy_bp); \
|
||||
+ yyleng = (yy_size_t) (yy_cp - yy_bp); \
|
||||
yyg->yy_hold_char = *yy_cp; \
|
||||
*yy_cp = '\0'; \
|
||||
yyg->yy_c_buf_p = yy_cp;
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||
#include "DiagnosticsBase.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
@ -31,7 +31,7 @@ Diagnostics::Severity Diagnostics::severity(ID id)
|
|||
if ((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END))
|
||||
return PP_WARNING;
|
||||
|
||||
UNREACHABLE();
|
||||
assert(false);
|
||||
return PP_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -74,8 +74,6 @@ std::string Diagnostics::message(ID id)
|
|||
return "predefined macro undefined";
|
||||
case PP_MACRO_UNTERMINATED_INVOCATION:
|
||||
return "unterminated macro invocation";
|
||||
case PP_MACRO_UNDEFINED_WHILE_INVOKED:
|
||||
return "macro undefined while being invoked";
|
||||
case PP_MACRO_TOO_FEW_ARGS:
|
||||
return "Not enough arguments for macro";
|
||||
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";
|
||||
// Warnings end.
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return "";
|
||||
assert(false);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ class Diagnostics
|
|||
PP_MACRO_PREDEFINED_REDEFINED,
|
||||
PP_MACRO_PREDEFINED_UNDEFINED,
|
||||
PP_MACRO_UNTERMINATED_INVOCATION,
|
||||
PP_MACRO_UNDEFINED_WHILE_INVOKED,
|
||||
PP_MACRO_TOO_FEW_ARGS,
|
||||
PP_MACRO_TOO_MANY_ARGS,
|
||||
PP_MACRO_DUPLICATE_PARAMETER_NAMES,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/preprocessor/DirectiveHandlerBase.h"
|
||||
#include "DirectiveHandlerBase.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,19 +4,19 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/preprocessor/DirectiveParser.h"
|
||||
#include "DirectiveParser.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||
#include "compiler/preprocessor/DirectiveHandlerBase.h"
|
||||
#include "compiler/preprocessor/ExpressionParser.h"
|
||||
#include "compiler/preprocessor/MacroExpander.h"
|
||||
#include "compiler/preprocessor/Token.h"
|
||||
#include "compiler/preprocessor/Tokenizer.h"
|
||||
#include "DiagnosticsBase.h"
|
||||
#include "DirectiveHandlerBase.h"
|
||||
#include "ExpressionParser.h"
|
||||
#include "MacroExpander.h"
|
||||
#include "Token.h"
|
||||
#include "Tokenizer.h"
|
||||
|
||||
namespace {
|
||||
enum DirectiveType
|
||||
|
|
@ -248,7 +248,7 @@ void DirectiveParser::lex(Token *token)
|
|||
|
||||
void DirectiveParser::parseDirective(Token *token)
|
||||
{
|
||||
ASSERT(token->type == Token::PP_HASH);
|
||||
assert(token->type == Token::PP_HASH);
|
||||
|
||||
mTokenizer->lex(token);
|
||||
if (isEOD(token))
|
||||
|
|
@ -314,8 +314,8 @@ void DirectiveParser::parseDirective(Token *token)
|
|||
parseLine(token);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
|
|
@ -328,7 +328,7 @@ void DirectiveParser::parseDirective(Token *token)
|
|||
|
||||
void DirectiveParser::parseDefine(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_DEFINE);
|
||||
assert(getDirective(token) == DIRECTIVE_DEFINE);
|
||||
|
||||
mTokenizer->lex(token);
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
|
|
@ -428,7 +428,7 @@ void DirectiveParser::parseDefine(Token *token)
|
|||
|
||||
void DirectiveParser::parseUndef(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_UNDEF);
|
||||
assert(getDirective(token) == DIRECTIVE_UNDEF);
|
||||
|
||||
mTokenizer->lex(token);
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
|
|
@ -445,13 +445,6 @@ void DirectiveParser::parseUndef(Token *token)
|
|||
{
|
||||
mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,
|
||||
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
|
||||
{
|
||||
|
|
@ -470,25 +463,25 @@ void DirectiveParser::parseUndef(Token *token)
|
|||
|
||||
void DirectiveParser::parseIf(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_IF);
|
||||
assert(getDirective(token) == DIRECTIVE_IF);
|
||||
parseConditionalIf(token);
|
||||
}
|
||||
|
||||
void DirectiveParser::parseIfdef(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_IFDEF);
|
||||
assert(getDirective(token) == DIRECTIVE_IFDEF);
|
||||
parseConditionalIf(token);
|
||||
}
|
||||
|
||||
void DirectiveParser::parseIfndef(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_IFNDEF);
|
||||
assert(getDirective(token) == DIRECTIVE_IFNDEF);
|
||||
parseConditionalIf(token);
|
||||
}
|
||||
|
||||
void DirectiveParser::parseElse(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_ELSE);
|
||||
assert(getDirective(token) == DIRECTIVE_ELSE);
|
||||
|
||||
if (mConditionalStack.empty())
|
||||
{
|
||||
|
|
@ -529,7 +522,7 @@ void DirectiveParser::parseElse(Token *token)
|
|||
|
||||
void DirectiveParser::parseElif(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_ELIF);
|
||||
assert(getDirective(token) == DIRECTIVE_ELIF);
|
||||
|
||||
if (mConditionalStack.empty())
|
||||
{
|
||||
|
|
@ -569,7 +562,7 @@ void DirectiveParser::parseElif(Token *token)
|
|||
|
||||
void DirectiveParser::parseEndif(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_ENDIF);
|
||||
assert(getDirective(token) == DIRECTIVE_ENDIF);
|
||||
|
||||
if (mConditionalStack.empty())
|
||||
{
|
||||
|
|
@ -593,7 +586,7 @@ void DirectiveParser::parseEndif(Token *token)
|
|||
|
||||
void DirectiveParser::parseError(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_ERROR);
|
||||
assert(getDirective(token) == DIRECTIVE_ERROR);
|
||||
|
||||
std::ostringstream stream;
|
||||
mTokenizer->lex(token);
|
||||
|
|
@ -608,7 +601,7 @@ void DirectiveParser::parseError(Token *token)
|
|||
// Parses pragma of form: #pragma name[(value)].
|
||||
void DirectiveParser::parsePragma(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_PRAGMA);
|
||||
assert(getDirective(token) == DIRECTIVE_PRAGMA);
|
||||
|
||||
enum State
|
||||
{
|
||||
|
|
@ -669,7 +662,7 @@ void DirectiveParser::parsePragma(Token *token)
|
|||
|
||||
void DirectiveParser::parseExtension(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_EXTENSION);
|
||||
assert(getDirective(token) == DIRECTIVE_EXTENSION);
|
||||
|
||||
enum State
|
||||
{
|
||||
|
|
@ -750,7 +743,7 @@ void DirectiveParser::parseExtension(Token *token)
|
|||
|
||||
void DirectiveParser::parseVersion(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_VERSION);
|
||||
assert(getDirective(token) == DIRECTIVE_VERSION);
|
||||
|
||||
if (mPastFirstStatement)
|
||||
{
|
||||
|
|
@ -837,7 +830,7 @@ void DirectiveParser::parseVersion(Token *token)
|
|||
|
||||
void DirectiveParser::parseLine(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_LINE);
|
||||
assert(getDirective(token) == DIRECTIVE_LINE);
|
||||
|
||||
bool valid = true;
|
||||
bool parsedFileNumber = false;
|
||||
|
|
@ -938,8 +931,8 @@ void DirectiveParser::parseConditionalIf(Token *token)
|
|||
expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
block.skipGroup = expression == 0;
|
||||
block.foundValidGroup = expression != 0;
|
||||
|
|
@ -949,7 +942,8 @@ void DirectiveParser::parseConditionalIf(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);
|
||||
MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics);
|
||||
|
|
@ -976,7 +970,8 @@ int DirectiveParser::parseExpressionIf(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);
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@
|
|||
#ifndef COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
||||
#define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
||||
|
||||
#include "compiler/preprocessor/Lexer.h"
|
||||
#include "compiler/preprocessor/Macro.h"
|
||||
#include "compiler/preprocessor/SourceLocation.h"
|
||||
#include "Lexer.h"
|
||||
#include "Macro.h"
|
||||
#include "pp_utils.h"
|
||||
#include "SourceLocation.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
@ -29,6 +30,7 @@ class DirectiveParser : public Lexer
|
|||
void lex(Token *token) override;
|
||||
|
||||
private:
|
||||
PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser);
|
||||
|
||||
void parseDirective(Token *token);
|
||||
void parseDefine(Token *token);
|
||||
|
|
|
|||
|
|
@ -99,15 +99,17 @@
|
|||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "DiagnosticsBase.h"
|
||||
#include "Lexer.h"
|
||||
#include "Token.h"
|
||||
#include "common/mathutil.h"
|
||||
|
||||
typedef int32_t YYSTYPE;
|
||||
typedef uint32_t UNSIGNED_TYPE;
|
||||
#if defined(_MSC_VER)
|
||||
typedef __int64 YYSTYPE;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef intmax_t YYSTYPE;
|
||||
#endif // _MSC_VER
|
||||
|
||||
#define YYENABLE_NLS 0
|
||||
#define YYLTYPE_IS_TRIVIAL 1
|
||||
|
|
@ -496,12 +498,9 @@ static const yytype_uint8 yytranslate[] =
|
|||
|
||||
#if YYDEBUG
|
||||
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
|
||||
static const yytype_uint16 yyrline[] =
|
||||
{
|
||||
0, 108, 108, 115, 116, 127, 127, 148, 148, 169,
|
||||
172, 175, 178, 181, 184, 187, 190, 193, 196, 221,
|
||||
246, 249, 252, 278, 305, 308, 311, 314, 326, 329
|
||||
};
|
||||
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,
|
||||
238, 241, 244, 264, 284, 287, 290, 293, 296, 299};
|
||||
#endif
|
||||
|
||||
#if YYDEBUG || YYERROR_VERBOSE || 0
|
||||
|
|
@ -1493,7 +1492,7 @@ yyreduce:
|
|||
case 18:
|
||||
|
||||
{
|
||||
if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31)
|
||||
if ((yyvsp[0]) < 0)
|
||||
{
|
||||
if (!context->isIgnoringErrors())
|
||||
{
|
||||
|
|
@ -1501,17 +1500,11 @@ yyreduce:
|
|||
stream << (yyvsp[-2]) << " >> " << (yyvsp[0]);
|
||||
std::string text = stream.str();
|
||||
context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
|
||||
context->token->location,
|
||||
text.c_str());
|
||||
context->token->location, text.c_str());
|
||||
*(context->valid) = false;
|
||||
}
|
||||
(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
|
||||
{
|
||||
(yyval) = (yyvsp[-2]) >> (yyvsp[0]);
|
||||
|
|
@ -1523,7 +1516,7 @@ yyreduce:
|
|||
case 19:
|
||||
|
||||
{
|
||||
if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31)
|
||||
if ((yyvsp[0]) < 0)
|
||||
{
|
||||
if (!context->isIgnoringErrors())
|
||||
{
|
||||
|
|
@ -1531,17 +1524,11 @@ yyreduce:
|
|||
stream << (yyvsp[-2]) << " << " << (yyvsp[0]);
|
||||
std::string text = stream.str();
|
||||
context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
|
||||
context->token->location,
|
||||
text.c_str());
|
||||
context->token->location, text.c_str());
|
||||
*(context->valid) = false;
|
||||
}
|
||||
(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
|
||||
{
|
||||
(yyval) = (yyvsp[-2]) << (yyvsp[0]);
|
||||
|
|
@ -1553,7 +1540,7 @@ yyreduce:
|
|||
case 20:
|
||||
|
||||
{
|
||||
(yyval) = gl::WrappingDiff<YYSTYPE>((yyvsp[-2]), (yyvsp[0]));
|
||||
(yyval) = (yyvsp[-2]) - (yyvsp[0]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -1561,7 +1548,7 @@ yyreduce:
|
|||
case 21:
|
||||
|
||||
{
|
||||
(yyval) = gl::WrappingSum<YYSTYPE>((yyvsp[-2]), (yyvsp[0]));
|
||||
(yyval) = (yyvsp[-2]) + (yyvsp[0]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -1583,12 +1570,6 @@ yyreduce:
|
|||
}
|
||||
(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
|
||||
{
|
||||
(yyval) = (yyvsp[-2]) % (yyvsp[0]);
|
||||
|
|
@ -1614,13 +1595,6 @@ yyreduce:
|
|||
}
|
||||
(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
|
||||
{
|
||||
(yyval) = (yyvsp[-2]) / (yyvsp[0]);
|
||||
|
|
@ -1632,7 +1606,7 @@ yyreduce:
|
|||
case 24:
|
||||
|
||||
{
|
||||
(yyval) = gl::WrappingMul((yyvsp[-2]), (yyvsp[0]));
|
||||
(yyval) = (yyvsp[-2]) * (yyvsp[0]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -1656,16 +1630,7 @@ yyreduce:
|
|||
case 27:
|
||||
|
||||
{
|
||||
// Check for negation of minimum representable integer to prevent undefined signed int
|
||||
// overflow.
|
||||
if ((yyvsp[0]) == std::numeric_limits<YYSTYPE>::min())
|
||||
{
|
||||
(yyval) = std::numeric_limits<YYSTYPE>::min();
|
||||
}
|
||||
else
|
||||
{
|
||||
(yyval) = -(yyvsp[0]);
|
||||
}
|
||||
(yyval) = - (yyvsp[0]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
#ifndef COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
||||
#define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||
#include "DiagnosticsBase.h"
|
||||
#include "pp_utils.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
@ -16,7 +16,7 @@ namespace pp
|
|||
class Lexer;
|
||||
struct Token;
|
||||
|
||||
class ExpressionParser : angle::NonCopyable
|
||||
class ExpressionParser
|
||||
{
|
||||
public:
|
||||
struct ErrorSettings
|
||||
|
|
@ -34,6 +34,8 @@ class ExpressionParser : angle::NonCopyable
|
|||
bool *valid);
|
||||
|
||||
private:
|
||||
PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser);
|
||||
|
||||
Lexer *mLexer;
|
||||
Diagnostics *mDiagnostics;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,15 +41,17 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser.
|
|||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "DiagnosticsBase.h"
|
||||
#include "Lexer.h"
|
||||
#include "Token.h"
|
||||
#include "common/mathutil.h"
|
||||
|
||||
typedef int32_t YYSTYPE;
|
||||
typedef uint32_t UNSIGNED_TYPE;
|
||||
#if defined(_MSC_VER)
|
||||
typedef __int64 YYSTYPE;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef intmax_t YYSTYPE;
|
||||
#endif // _MSC_VER
|
||||
|
||||
#define YYENABLE_NLS 0
|
||||
#define YYLTYPE_IS_TRIVIAL 1
|
||||
|
|
@ -194,7 +196,7 @@ expression
|
|||
$$ = $1 < $3;
|
||||
}
|
||||
| expression TOK_OP_RIGHT expression {
|
||||
if ($3 < 0 || $3 > 31)
|
||||
if ($3 < 0)
|
||||
{
|
||||
if (!context->isIgnoringErrors())
|
||||
{
|
||||
|
|
@ -208,18 +210,13 @@ expression
|
|||
}
|
||||
$$ = static_cast<YYSTYPE>(0);
|
||||
}
|
||||
else if ($1 < 0)
|
||||
{
|
||||
// Logical shift right.
|
||||
$$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) >> $3);
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = $1 >> $3;
|
||||
}
|
||||
}
|
||||
| expression TOK_OP_LEFT expression {
|
||||
if ($3 < 0 || $3 > 31)
|
||||
if ($3 < 0)
|
||||
{
|
||||
if (!context->isIgnoringErrors())
|
||||
{
|
||||
|
|
@ -233,21 +230,16 @@ expression
|
|||
}
|
||||
$$ = static_cast<YYSTYPE>(0);
|
||||
}
|
||||
else if ($1 < 0)
|
||||
{
|
||||
// Logical shift left.
|
||||
$$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) << $3);
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = $1 << $3;
|
||||
}
|
||||
}
|
||||
| expression '-' expression {
|
||||
$$ = gl::WrappingDiff<YYSTYPE>($1, $3);
|
||||
$$ = $1 - $3;
|
||||
}
|
||||
| expression '+' expression {
|
||||
$$ = gl::WrappingSum<YYSTYPE>($1, $3);
|
||||
$$ = $1 + $3;
|
||||
}
|
||||
| expression '%' expression {
|
||||
if ($3 == 0)
|
||||
|
|
@ -264,12 +256,6 @@ expression
|
|||
}
|
||||
$$ = 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
|
||||
{
|
||||
$$ = $1 % $3;
|
||||
|
|
@ -290,20 +276,13 @@ expression
|
|||
}
|
||||
$$ = 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
|
||||
{
|
||||
$$ = $1 / $3;
|
||||
}
|
||||
}
|
||||
| expression '*' expression {
|
||||
$$ = gl::WrappingMul($1, $3);
|
||||
$$ = $1 * $3;
|
||||
}
|
||||
| '!' expression %prec TOK_UNARY {
|
||||
$$ = ! $2;
|
||||
|
|
@ -312,16 +291,7 @@ expression
|
|||
$$ = ~ $2;
|
||||
}
|
||||
| '-' expression %prec TOK_UNARY {
|
||||
// Check for negation of minimum representable integer to prevent undefined signed int
|
||||
// overflow.
|
||||
if ($2 == std::numeric_limits<YYSTYPE>::min())
|
||||
{
|
||||
$$ = std::numeric_limits<YYSTYPE>::min();
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = -$2;
|
||||
}
|
||||
$$ = - $2;
|
||||
}
|
||||
| '+' expression %prec TOK_UNARY {
|
||||
$$ = + $2;
|
||||
|
|
|
|||
|
|
@ -4,13 +4,12 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/preprocessor/Input.h"
|
||||
#include "Input.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
|
|
@ -33,7 +32,7 @@ Input::Input(size_t count, const char *const string[], const int length[]) :
|
|||
const char *Input::skipChar()
|
||||
{
|
||||
// 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;
|
||||
if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef COMPILER_PREPROCESSOR_INPUT_H_
|
||||
#define COMPILER_PREPROCESSOR_INPUT_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <stddef.h>
|
||||
#include <vector>
|
||||
|
||||
namespace pp
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/preprocessor/Lexer.h"
|
||||
#include "Lexer.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,14 +7,12 @@
|
|||
#ifndef COMPILER_PREPROCESSOR_LEXER_H_
|
||||
#define COMPILER_PREPROCESSOR_LEXER_H_
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
struct Token;
|
||||
|
||||
class Lexer : angle::NonCopyable
|
||||
class Lexer
|
||||
{
|
||||
public:
|
||||
virtual ~Lexer();
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/preprocessor/Macro.h"
|
||||
#include "Macro.h"
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/preprocessor/Token.h"
|
||||
#include <sstream>
|
||||
|
||||
#include "Token.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
@ -22,9 +23,12 @@ bool Macro::equals(const Macro &other) const
|
|||
|
||||
void PredefineMacro(MacroSet *macroSet, const char *name, int value)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << value;
|
||||
|
||||
Token token;
|
||||
token.type = Token::CONST_INT;
|
||||
token.text = ToString(value);
|
||||
token.text = stream.str();
|
||||
|
||||
Macro macro;
|
||||
macro.predefined = true;
|
||||
|
|
|
|||
|
|
@ -26,12 +26,16 @@ struct Macro
|
|||
typedef std::vector<std::string> Parameters;
|
||||
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 predefined;
|
||||
mutable bool disabled;
|
||||
mutable int expansionCount;
|
||||
|
||||
Type type;
|
||||
std::string name;
|
||||
|
|
|
|||
|
|
@ -4,22 +4,17 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/preprocessor/MacroExpander.h"
|
||||
#include "MacroExpander.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||
#include "compiler/preprocessor/Token.h"
|
||||
#include "DiagnosticsBase.h"
|
||||
#include "Token.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const size_t kMaxContextTokens = 10000;
|
||||
|
||||
class TokenLexer : public Lexer
|
||||
{
|
||||
public:
|
||||
|
|
@ -45,52 +40,22 @@ class TokenLexer : public Lexer
|
|||
}
|
||||
|
||||
private:
|
||||
PP_DISALLOW_COPY_AND_ASSIGN(TokenLexer);
|
||||
|
||||
TokenVector mTokens;
|
||||
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)
|
||||
: mLexer(lexer),
|
||||
mMacroSet(macroSet),
|
||||
mDiagnostics(diagnostics),
|
||||
mTotalTokensInContexts(0),
|
||||
mDeferReenablingMacros(false)
|
||||
: mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics)
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
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 the token immediately after the macro name is not a '(',
|
||||
// this macro should not be expanded.
|
||||
macro.expansionCount--;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +114,6 @@ void MacroExpander::getToken(Token *token)
|
|||
}
|
||||
else
|
||||
{
|
||||
ASSERT(mTotalTokensInContexts == 0);
|
||||
mLexer->lex(token);
|
||||
}
|
||||
}
|
||||
|
|
@ -165,11 +124,11 @@ void MacroExpander::ungetToken(const Token &token)
|
|||
{
|
||||
MacroContext *context = mContextStack.back();
|
||||
context->unget();
|
||||
ASSERT(context->replacements[context->index] == token);
|
||||
assert(context->replacements[context->index] == token);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(!mReserveToken.get());
|
||||
assert(!mReserveToken.get());
|
||||
mReserveToken.reset(new Token(token));
|
||||
}
|
||||
}
|
||||
|
|
@ -187,10 +146,10 @@ bool MacroExpander::isNextTokenLeftParen()
|
|||
|
||||
bool MacroExpander::pushMacro(const Macro ¯o, const Token &identifier)
|
||||
{
|
||||
ASSERT(!macro.disabled);
|
||||
ASSERT(!identifier.expansionDisabled());
|
||||
ASSERT(identifier.type == Token::IDENTIFIER);
|
||||
ASSERT(identifier.text == macro.name);
|
||||
assert(!macro.disabled);
|
||||
assert(!identifier.expansionDisabled());
|
||||
assert(identifier.type == Token::IDENTIFIER);
|
||||
assert(identifier.text == macro.name);
|
||||
|
||||
std::vector<Token> replacements;
|
||||
if (!expandMacro(macro, identifier, &replacements))
|
||||
|
|
@ -203,30 +162,19 @@ bool MacroExpander::pushMacro(const Macro ¯o, const Token &identifier)
|
|||
context->macro = ¯o;
|
||||
context->replacements.swap(replacements);
|
||||
mContextStack.push_back(context);
|
||||
mTotalTokensInContexts += context->replacements.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroExpander::popMacro()
|
||||
{
|
||||
ASSERT(!mContextStack.empty());
|
||||
assert(!mContextStack.empty());
|
||||
|
||||
MacroContext *context = mContextStack.back();
|
||||
mContextStack.pop_back();
|
||||
|
||||
ASSERT(context->empty());
|
||||
ASSERT(context->macro->disabled);
|
||||
ASSERT(context->macro->expansionCount > 0);
|
||||
if (mDeferReenablingMacros)
|
||||
{
|
||||
mMacrosToReenable.push_back(context->macro);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->macro->disabled = false;
|
||||
}
|
||||
context->macro->expansionCount--;
|
||||
mTotalTokensInContexts -= context->replacements.size();
|
||||
assert(context->empty());
|
||||
assert(context->macro->disabled);
|
||||
context->macro->disabled = false;
|
||||
delete context;
|
||||
}
|
||||
|
||||
|
|
@ -251,21 +199,25 @@ bool MacroExpander::expandMacro(const Macro ¯o,
|
|||
const char kLine[] = "__LINE__";
|
||||
const char kFile[] = "__FILE__";
|
||||
|
||||
ASSERT(replacements->size() == 1);
|
||||
assert(replacements->size() == 1);
|
||||
Token& repl = replacements->front();
|
||||
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)
|
||||
{
|
||||
repl.text = ToString(identifier.location.file);
|
||||
std::ostringstream stream;
|
||||
stream << identifier.location.file;
|
||||
repl.text = stream.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(macro.type == Macro::kTypeFunc);
|
||||
assert(macro.type == Macro::kTypeFunc);
|
||||
std::vector<MacroArg> args;
|
||||
args.reserve(macro.parameters.size());
|
||||
if (!collectMacroArgs(macro, identifier, &args, &replacementLocation))
|
||||
|
|
@ -296,17 +248,10 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o,
|
|||
{
|
||||
Token token;
|
||||
getToken(&token);
|
||||
ASSERT(token.type == '(');
|
||||
assert(token.type == '(');
|
||||
|
||||
args->push_back(MacroArg());
|
||||
|
||||
// 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)
|
||||
for (int openParens = 1; openParens != 0; )
|
||||
{
|
||||
getToken(&token);
|
||||
|
||||
|
|
@ -372,9 +317,9 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o,
|
|||
// Pre-expand each argument before substitution.
|
||||
// This step expands each argument individually before they are
|
||||
// inserted into the macro body.
|
||||
size_t numTokens = 0;
|
||||
for (auto &arg : *args)
|
||||
for (std::size_t i = 0; i < args->size(); ++i)
|
||||
{
|
||||
MacroArg &arg = args->at(i);
|
||||
TokenLexer lexer(&arg);
|
||||
MacroExpander expander(&lexer, mMacroSet, mDiagnostics);
|
||||
|
||||
|
|
@ -384,12 +329,6 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o,
|
|||
{
|
||||
arg.push_back(token);
|
||||
expander.lex(&token);
|
||||
numTokens++;
|
||||
if (numTokens + mTotalTokensInContexts > kMaxContextTokens)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -401,14 +340,6 @@ void MacroExpander::replaceMacroParams(const Macro ¯o,
|
|||
{
|
||||
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];
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@
|
|||
#ifndef COMPILER_PREPROCESSOR_MACROEXPANDER_H_
|
||||
#define COMPILER_PREPROCESSOR_MACROEXPANDER_H_
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "compiler/preprocessor/Lexer.h"
|
||||
#include "compiler/preprocessor/Macro.h"
|
||||
#include "Lexer.h"
|
||||
#include "Macro.h"
|
||||
#include "pp_utils.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
@ -28,6 +30,8 @@ class MacroExpander : public Lexer
|
|||
void lex(Token *token) override;
|
||||
|
||||
private:
|
||||
PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander);
|
||||
|
||||
void getToken(Token *token);
|
||||
void ungetToken(const Token &token);
|
||||
bool isNextTokenLeftParen();
|
||||
|
|
@ -50,14 +54,28 @@ class MacroExpander : public Lexer
|
|||
|
||||
struct MacroContext
|
||||
{
|
||||
MacroContext();
|
||||
bool empty() const;
|
||||
const Token &get();
|
||||
void unget();
|
||||
|
||||
const Macro *macro;
|
||||
std::size_t index;
|
||||
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;
|
||||
|
|
@ -66,12 +84,6 @@ class MacroExpander : public Lexer
|
|||
|
||||
std::unique_ptr<Token> mReserveToken;
|
||||
std::vector<MacroContext *> mContextStack;
|
||||
size_t mTotalTokensInContexts;
|
||||
|
||||
bool mDeferReenablingMacros;
|
||||
std::vector<const Macro *> mMacrosToReenable;
|
||||
|
||||
class ScopedMacroReenabler;
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
|
|
|
|||
|
|
@ -4,15 +4,16 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/preprocessor/Preprocessor.h"
|
||||
#include "Preprocessor.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||
#include "compiler/preprocessor/DirectiveParser.h"
|
||||
#include "compiler/preprocessor/Macro.h"
|
||||
#include "compiler/preprocessor/MacroExpander.h"
|
||||
#include "compiler/preprocessor/Token.h"
|
||||
#include "compiler/preprocessor/Tokenizer.h"
|
||||
#include <cassert>
|
||||
|
||||
#include "DiagnosticsBase.h"
|
||||
#include "DirectiveParser.h"
|
||||
#include "Macro.h"
|
||||
#include "MacroExpander.h"
|
||||
#include "Token.h"
|
||||
#include "Tokenizer.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
@ -77,8 +78,8 @@ void Preprocessor::lex(Token *token)
|
|||
// Convert preprocessing tokens to compiler tokens or report
|
||||
// diagnostics.
|
||||
case Token::PP_HASH:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
assert(false);
|
||||
break;
|
||||
case Token::PP_NUMBER:
|
||||
mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER,
|
||||
token->location, token->text);
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
#ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_
|
||||
#define COMPILER_PREPROCESSOR_PREPROCESSOR_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "pp_utils.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
@ -19,7 +19,7 @@ class DirectiveHandler;
|
|||
struct PreprocessorImpl;
|
||||
struct Token;
|
||||
|
||||
class Preprocessor : angle::NonCopyable
|
||||
class Preprocessor
|
||||
{
|
||||
public:
|
||||
Preprocessor(Diagnostics *diagnostics, DirectiveHandler *directiveHandler);
|
||||
|
|
@ -44,6 +44,8 @@ class Preprocessor : angle::NonCopyable
|
|||
void setMaxTokenSize(size_t maxTokenSize);
|
||||
|
||||
private:
|
||||
PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor);
|
||||
|
||||
PreprocessorImpl *mImpl;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "compiler/preprocessor/Token.h"
|
||||
#include "Token.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "compiler/preprocessor/numeric_lex.h"
|
||||
#include <cassert>
|
||||
|
||||
#include "numeric_lex.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
@ -54,19 +55,19 @@ void Token::setExpansionDisabled(bool disable)
|
|||
|
||||
bool Token::iValue(int *value) const
|
||||
{
|
||||
ASSERT(type == CONST_INT);
|
||||
assert(type == CONST_INT);
|
||||
return numeric_lex_int(text, value);
|
||||
}
|
||||
|
||||
bool Token::uValue(unsigned int *value) const
|
||||
{
|
||||
ASSERT(type == CONST_INT);
|
||||
assert(type == CONST_INT);
|
||||
return numeric_lex_int(text, value);
|
||||
}
|
||||
|
||||
bool Token::fValue(float *value) const
|
||||
{
|
||||
ASSERT(type == CONST_FLOAT);
|
||||
assert(type == CONST_FLOAT);
|
||||
return numeric_lex_float(text, value);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "compiler/preprocessor/SourceLocation.h"
|
||||
#include "SourceLocation.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
@ -113,7 +113,7 @@ inline bool operator!=(const Token &lhs, const Token &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
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -7,9 +7,9 @@
|
|||
#ifndef COMPILER_PREPROCESSOR_TOKENIZER_H_
|
||||
#define COMPILER_PREPROCESSOR_TOKENIZER_H_
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/preprocessor/Input.h"
|
||||
#include "compiler/preprocessor/Lexer.h"
|
||||
#include "Input.h"
|
||||
#include "Lexer.h"
|
||||
#include "pp_utils.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
|
@ -45,6 +45,7 @@ class Tokenizer : public Lexer
|
|||
void lex(Token *token) override;
|
||||
|
||||
private:
|
||||
PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer);
|
||||
bool initScanner();
|
||||
void destroyScanner();
|
||||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
|
|||
#pragma warning(disable: 4005)
|
||||
#endif
|
||||
|
||||
#include "compiler/preprocessor/Tokenizer.h"
|
||||
#include "Tokenizer.h"
|
||||
|
||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||
#include "compiler/preprocessor/Token.h"
|
||||
#include "DiagnosticsBase.h"
|
||||
#include "Token.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// Triggered by the auto-generated yy_fatal_error function.
|
||||
|
|
@ -280,7 +280,9 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
|
|||
|
||||
namespace pp {
|
||||
|
||||
Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(256)
|
||||
Tokenizer::Tokenizer(Diagnostics *diagnostics)
|
||||
: mHandle(0),
|
||||
mMaxTokenSize(256)
|
||||
{
|
||||
mContext.diagnostics = diagnostics;
|
||||
}
|
||||
|
|
@ -337,7 +339,7 @@ void Tokenizer::lex(Token *token)
|
|||
|
||||
bool Tokenizer::initScanner()
|
||||
{
|
||||
if ((mHandle == nullptr) && yylex_init_extra(&mContext, &mHandle))
|
||||
if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle))
|
||||
return false;
|
||||
|
||||
yyrestart(0, mHandle);
|
||||
|
|
@ -346,11 +348,11 @@ bool Tokenizer::initScanner()
|
|||
|
||||
void Tokenizer::destroyScanner()
|
||||
{
|
||||
if (mHandle == nullptr)
|
||||
if (mHandle == NULL)
|
||||
return;
|
||||
|
||||
yylex_destroy(mHandle);
|
||||
mHandle = nullptr;
|
||||
mHandle = NULL;
|
||||
}
|
||||
|
||||
} // namespace pp
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#ifndef COMPILER_PREPROCESSOR_NUMERICLEX_H_
|
||||
#define COMPILER_PREPROCESSOR_NUMERICLEX_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
|
||||
namespace pp {
|
||||
|
|
@ -64,7 +63,7 @@ bool numeric_lex_float(const std::string &str, FloatType *value)
|
|||
stream.imbue(std::locale::classic());
|
||||
|
||||
stream >> (*value);
|
||||
return !stream.fail() && std::isfinite(*value);
|
||||
return !stream.fail();
|
||||
#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
|
||||
index 1ba63df..2a206ab 100644
|
||||
--- a/src/compiler/translator/glslang_lex.cpp
|
||||
+++ 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;
|
||||
--- a/src/compiler/glslang_lex.cpp
|
||||
+++ b/src/compiler/glslang_lex.cpp
|
||||
@@ -68,6 +68,7 @@ typedef int16_t flex_int16_t;
|
||||
typedef uint16_t flex_uint16_t;
|
||||
typedef int32_t flex_int32_t;
|
||||
typedef uint32_t flex_uint32_t;
|
||||
|
|
@ -15,10 +8,10 @@ index 1ba63df..2a206ab 100644
|
|||
#else
|
||||
typedef signed char flex_int8_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
|
||||
+#define YY_TYPEDEF_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_END_OF_FILE 1
|
||||
#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) \
|
||||
do { \
|
||||
- int yyl;\
|
||||
- for ( yyl = n; yyl < yyleng; ++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' )\
|
||||
--yylineno;\
|
||||
}while(0)
|
||||
@@ -1692,7 +1697,7 @@ yy_find_action:
|
||||
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
|
||||
{
|
||||
yy_size_t yyl;
|
||||
- for ( yyl = 0; yyl < yyleng; ++yyl )
|
||||
+ for ( yyl = 0; yyl < static_cast<yy_size_t>(yyleng); ++yyl )
|
||||
if ( yytext[yyl] == '\n' )
|
||||
|
||||
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;
|
||||
@@ -378,7 +379,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
|
||||
*/
|
||||
#define YY_DO_BEFORE_ACTION \
|
||||
yyg->yytext_ptr = yy_bp; \
|
||||
- yyleng = (size_t) (yy_cp - yy_bp); \
|
||||
+ yyleng = (yy_size_t) (yy_cp - yy_bp); \
|
||||
yyg->yy_hold_char = *yy_cp; \
|
||||
*yy_cp = '\0'; \
|
||||
yyg->yy_c_buf_p = yy_cp;
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@
|
|||
#include "compiler/translator/CallDAG.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
|
@ -34,7 +31,7 @@ class PullGradient : public TIntermTraverser
|
|||
ASSERT(index < metadataList->size());
|
||||
}
|
||||
|
||||
void traverse(TIntermFunctionDefinition *node)
|
||||
void traverse(TIntermAggregate *node)
|
||||
{
|
||||
node->traverse(this);
|
||||
ASSERT(mParents.empty());
|
||||
|
|
@ -75,9 +72,9 @@ class PullGradient : public TIntermTraverser
|
|||
return true;
|
||||
}
|
||||
|
||||
bool visitIfElse(Visit visit, TIntermIfElse *ifElse) override
|
||||
bool visitSelection(Visit visit, TIntermSelection *selection) override
|
||||
{
|
||||
visitControlFlow(visit, ifElse);
|
||||
visitControlFlow(visit, selection);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -106,8 +103,9 @@ class PullGradient : public TIntermTraverser
|
|||
{
|
||||
if (node->isUserDefined())
|
||||
{
|
||||
size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
|
||||
size_t calleeIndex = mDag.findIndex(node);
|
||||
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
|
||||
UNUSED_ASSERTION_VARIABLE(mIndex);
|
||||
|
||||
if ((*mMetadataList)[calleeIndex].mUsesGradient) {
|
||||
onGradient();
|
||||
|
|
@ -115,8 +113,7 @@ class PullGradient : public TIntermTraverser
|
|||
}
|
||||
else
|
||||
{
|
||||
TString name =
|
||||
TFunction::unmangleName(node->getFunctionSymbolInfo()->getName());
|
||||
TString name = TFunction::unmangleName(node->getName());
|
||||
|
||||
if (name == "texture2D" ||
|
||||
name == "texture2DProj" ||
|
||||
|
|
@ -160,7 +157,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
|
|||
{
|
||||
}
|
||||
|
||||
void traverse(TIntermFunctionDefinition *node)
|
||||
void traverse(TIntermAggregate *node)
|
||||
{
|
||||
node->traverse(this);
|
||||
ASSERT(mLoopsAndSwitches.empty());
|
||||
|
|
@ -199,7 +196,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
|
|||
return true;
|
||||
}
|
||||
|
||||
bool visitIfElse(Visit visit, TIntermIfElse *node) override
|
||||
bool visitSelection(Visit visit, TIntermSelection *node) override
|
||||
{
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
|
|
@ -278,8 +275,9 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
|
|||
{
|
||||
if (node->isUserDefined())
|
||||
{
|
||||
size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
|
||||
size_t calleeIndex = mDag.findIndex(node);
|
||||
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
|
||||
UNUSED_ASSERTION_VARIABLE(mIndex);
|
||||
|
||||
if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
|
||||
{
|
||||
|
|
@ -312,7 +310,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
|
|||
const CallDAG &mDag;
|
||||
|
||||
std::vector<TIntermNode*> mLoopsAndSwitches;
|
||||
std::vector<TIntermIfElse *> mIfs;
|
||||
std::vector<TIntermSelection*> mIfs;
|
||||
};
|
||||
|
||||
// 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);
|
||||
ASSERT(mNestedDiscont == (mMetadata->mCalledInDiscontinuousLoop ? 1 : 0));
|
||||
|
|
@ -358,8 +356,9 @@ class PushDiscontinuousLoops : public TIntermTraverser
|
|||
case EOpFunctionCall:
|
||||
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);
|
||||
UNUSED_ASSERTION_VARIABLE(mIndex);
|
||||
|
||||
(*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true;
|
||||
}
|
||||
|
|
@ -386,7 +385,7 @@ bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node)
|
|||
return mControlFlowsContainingGradient.count(node) > 0;
|
||||
}
|
||||
|
||||
bool ASTMetadataHLSL::hasGradientLoop(TIntermIfElse *node)
|
||||
bool ASTMetadataHLSL::hasGradientLoop(TIntermSelection *node)
|
||||
{
|
||||
return mIfsContainingGradientLoop.count(node) > 0;
|
||||
}
|
||||
|
|
@ -450,5 +449,3 @@ MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag)
|
|||
|
||||
return metadataList;
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -12,12 +12,9 @@
|
|||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
class CallDAG;
|
||||
class TIntermNode;
|
||||
class TIntermIfElse;
|
||||
class TIntermSelection;
|
||||
class TIntermLoop;
|
||||
|
||||
struct ASTMetadataHLSL
|
||||
|
|
@ -33,7 +30,7 @@ struct ASTMetadataHLSL
|
|||
// Here "something uses a gradient" means here that it either contains a
|
||||
// gradient operation, or a call to a function that uses a gradient.
|
||||
bool hasGradientInCallGraph(TIntermLoop *node);
|
||||
bool hasGradientLoop(TIntermIfElse *node);
|
||||
bool hasGradientLoop(TIntermSelection *node);
|
||||
|
||||
// Does the function use a gradient.
|
||||
bool mUsesGradient;
|
||||
|
|
@ -47,7 +44,7 @@ struct ASTMetadataHLSL
|
|||
bool mCalledInDiscontinuousLoop;
|
||||
bool mHasGradientLoopInCallGraph;
|
||||
std::set<TIntermLoop*> mDiscontinuousLoops;
|
||||
std::set<TIntermIfElse *> mIfsContainingGradientLoop;
|
||||
std::set<TIntermSelection *> mIfsContainingGradientLoop;
|
||||
|
||||
// Will we need to generate a Lod0 version of the function.
|
||||
bool mNeedsLod0;
|
||||
|
|
@ -58,6 +55,4 @@ typedef std::vector<ASTMetadataHLSL> MetadataList;
|
|||
// Return the AST analysis result, in the order defined by the call DAG
|
||||
MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag);
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#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:
|
||||
AddDefaultReturnStatementsTraverser() : TIntermTraverser(true, false, false) {}
|
||||
|
||||
static bool IsFunctionWithoutReturnStatement(TIntermFunctionDefinition *node, TType *returnType)
|
||||
static bool IsFunctionWithoutReturnStatement(TIntermAggregate *node, TType *returnType)
|
||||
{
|
||||
*returnType = node->getType();
|
||||
if (node->getType().getBasicType() == EbtVoid)
|
||||
if (node->getOp() != EOpFunction || node->getType().getBasicType() == EbtVoid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TIntermBlock *bodyNode = node->getBody();
|
||||
TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode();
|
||||
TIntermAggregate *lastNode = node->getSequence()->back()->getAsAggregate();
|
||||
if (lastNode == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
TIntermBranch *returnNode = lastNode->getSequence()->front()->getAsBranchNode();
|
||||
if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -49,16 +54,51 @@ class AddDefaultReturnStatementsTraverser : private TIntermTraverser
|
|||
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;
|
||||
if (IsFunctionWithoutReturnStatement(node, &returnType))
|
||||
{
|
||||
TIntermBranch *branch =
|
||||
new TIntermBranch(EOpReturn, TIntermTyped::CreateZero(returnType));
|
||||
new TIntermBranch(EOpReturn, GenerateTypeConstructor(returnType));
|
||||
|
||||
TIntermBlock *bodyNode = node->getBody();
|
||||
bodyNode->getSequence()->push_back(branch);
|
||||
TIntermAggregate *lastNode = node->getSequence()->back()->getAsAggregate();
|
||||
lastNode->getSequence()->push_back(branch);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@
|
|||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
|
@ -44,7 +41,8 @@ TIntermAggregate *CreateReplacementCall(TIntermAggregate *originalCall, TIntermT
|
|||
TIntermAggregate *replacementCall = new TIntermAggregate(EOpFunctionCall);
|
||||
replacementCall->setType(TType(EbtVoid));
|
||||
replacementCall->setUserDefined();
|
||||
*replacementCall->getFunctionSymbolInfo() = *originalCall->getFunctionSymbolInfo();
|
||||
replacementCall->setNameObj(originalCall->getNameObj());
|
||||
replacementCall->setFunctionId(originalCall->getFunctionId());
|
||||
replacementCall->setLine(originalCall->getLine());
|
||||
TIntermSequence *replacementParameters = replacementCall->getSequence();
|
||||
TIntermSequence *originalParameters = originalCall->getSequence();
|
||||
|
|
@ -63,7 +61,6 @@ class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser
|
|||
private:
|
||||
ArrayReturnValueToOutParameterTraverser();
|
||||
|
||||
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
|
||||
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
|
||||
bool visitBranch(Visit visit, TIntermBranch *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)
|
||||
{
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
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.
|
||||
TIntermAggregate *replacement = new TIntermAggregate;
|
||||
|
|
@ -133,7 +118,8 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter
|
|||
CopyAggregateChildren(node, replacement);
|
||||
replacement->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
|
||||
replacement->setUserDefined();
|
||||
*replacement->getFunctionSymbolInfo() = *node->getFunctionSymbolInfo();
|
||||
replacement->setNameObj(node->getNameObj());
|
||||
replacement->setFunctionId(node->getFunctionId());
|
||||
replacement->setLine(node->getLine());
|
||||
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
|
||||
// only need to worry about the case where a function call returning an array forms an expression by
|
||||
// itself.
|
||||
TIntermBlock *parentBlock = getParentNode()->getAsBlock();
|
||||
if (parentBlock)
|
||||
TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
|
||||
if (parentAgg != nullptr && parentAgg->getOp() == EOpSequence)
|
||||
{
|
||||
nextTemporaryIndex();
|
||||
TIntermSequence replacements;
|
||||
replacements.push_back(createTempDeclaration(node->getType()));
|
||||
TIntermSymbol *returnSymbol = createTempSymbol(node->getType());
|
||||
replacements.push_back(CreateReplacementCall(node, returnSymbol));
|
||||
mMultiReplacements.push_back(
|
||||
NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
|
||||
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacements));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (visit == PostVisit)
|
||||
{
|
||||
if (node->getOp() == EOpFunction)
|
||||
{
|
||||
mInFunctionWithArrayReturnValue = false;
|
||||
}
|
||||
}
|
||||
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.
|
||||
TIntermSequence replacements;
|
||||
|
||||
TIntermBinary *replacementAssignment = new TIntermBinary(EOpAssign);
|
||||
TIntermTyped *expression = node->getExpression();
|
||||
ASSERT(expression != nullptr);
|
||||
TIntermSymbol *returnValueSymbol = CreateReturnValueSymbol(expression->getType());
|
||||
TIntermBinary *replacementAssignment =
|
||||
new TIntermBinary(EOpAssign, returnValueSymbol, expression);
|
||||
replacementAssignment->setLeft(CreateReturnValueSymbol(expression->getType()));
|
||||
replacementAssignment->setRight(node->getExpression());
|
||||
replacementAssignment->setType(expression->getType());
|
||||
replacementAssignment->setLine(expression->getLine());
|
||||
replacements.push_back(replacementAssignment);
|
||||
|
||||
|
|
@ -187,8 +180,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBr
|
|||
replacementBranch->setLine(node->getLine());
|
||||
replacements.push_back(replacementBranch);
|
||||
|
||||
mMultiReplacements.push_back(
|
||||
NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, replacements));
|
||||
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsAggregate(), node, replacements));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -213,5 +205,3 @@ void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIn
|
|||
{
|
||||
ArrayReturnValueToOutParameterTraverser::apply(root, temporaryIndex);
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -9,11 +9,8 @@
|
|||
#ifndef COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
|
||||
#define COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
|
||||
|
||||
namespace sh
|
||||
{
|
||||
class TIntermNode;
|
||||
|
||||
void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIndex);
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@
|
|||
#include "common/debug.h"
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
//
|
||||
// Precision qualifiers
|
||||
//
|
||||
|
|
@ -35,10 +32,10 @@ inline const char* getPrecisionString(TPrecision p)
|
|||
{
|
||||
switch(p)
|
||||
{
|
||||
case EbpHigh: return "highp";
|
||||
case EbpMedium: return "mediump";
|
||||
case EbpLow: return "lowp";
|
||||
default: return "mediump"; // Safest fallback
|
||||
case EbpHigh: return "highp"; break;
|
||||
case EbpMedium: return "mediump"; break;
|
||||
case EbpLow: return "lowp"; break;
|
||||
default: return "mediump"; break; // Safest fallback
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -79,98 +76,19 @@ enum TBasicType
|
|||
EbtSampler2DShadow,
|
||||
EbtSamplerCubeShadow,
|
||||
EbtSampler2DArrayShadow,
|
||||
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
|
||||
EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
|
||||
EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
|
||||
EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
|
||||
EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and
|
||||
// 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,
|
||||
|
||||
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
|
||||
EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
|
||||
EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
|
||||
EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
|
||||
EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray
|
||||
EbtStruct,
|
||||
EbtInterfaceBlock,
|
||||
EbtAddress, // should be deprecated??
|
||||
EbtAddress, // should be deprecated??
|
||||
|
||||
// end of list
|
||||
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);
|
||||
|
||||
inline bool IsSampler(TBasicType type)
|
||||
|
|
@ -178,22 +96,6 @@ inline bool IsSampler(TBasicType type)
|
|||
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)
|
||||
{
|
||||
switch (type)
|
||||
|
|
@ -224,56 +126,6 @@ inline bool IsIntegerSampler(TBasicType type)
|
|||
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)
|
||||
{
|
||||
switch (type)
|
||||
|
|
@ -431,7 +283,7 @@ inline bool IsInteger(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,
|
||||
|
||||
// GLSL ES 3.0 vertex output and fragment input
|
||||
EvqSmooth, // Incomplete qualifier, smooth is the default
|
||||
EvqFlat, // Incomplete qualifier
|
||||
EvqCentroid, // Incomplete qualifier
|
||||
EvqSmoothOut,
|
||||
EvqFlatOut,
|
||||
EvqSmooth, // Incomplete qualifier, smooth is the default
|
||||
EvqFlat, // Incomplete qualifier
|
||||
EvqSmoothOut = EvqSmooth,
|
||||
EvqFlatOut = EvqFlat,
|
||||
EvqCentroidOut, // Implies smooth
|
||||
EvqSmoothIn,
|
||||
EvqFlatIn,
|
||||
|
|
@ -508,40 +359,10 @@ enum TQualifier
|
|||
EvqGlobalInvocationID,
|
||||
EvqLocalInvocationIndex,
|
||||
|
||||
// GLSL ES 3.1 memory qualifiers
|
||||
EvqReadOnly,
|
||||
EvqWriteOnly,
|
||||
EvqCoherent,
|
||||
EvqRestrict,
|
||||
EvqVolatile,
|
||||
|
||||
// end of list
|
||||
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
|
||||
{
|
||||
EmpUnspecified,
|
||||
|
|
@ -560,44 +381,36 @@ enum TLayoutBlockStorage
|
|||
struct TLayoutQualifier
|
||||
{
|
||||
int location;
|
||||
unsigned int locationsSpecified;
|
||||
TLayoutMatrixPacking matrixPacking;
|
||||
TLayoutBlockStorage blockStorage;
|
||||
|
||||
// Compute shader layout qualifiers.
|
||||
sh::WorkGroupSize localSize;
|
||||
|
||||
// Image format layout qualifier
|
||||
TLayoutImageInternalFormat imageInternalFormat;
|
||||
|
||||
static TLayoutQualifier create()
|
||||
{
|
||||
TLayoutQualifier layoutQualifier;
|
||||
|
||||
layoutQualifier.location = -1;
|
||||
layoutQualifier.locationsSpecified = 0;
|
||||
layoutQualifier.matrixPacking = EmpUnspecified;
|
||||
layoutQualifier.blockStorage = EbsUnspecified;
|
||||
|
||||
layoutQualifier.localSize.fill(-1);
|
||||
|
||||
layoutQualifier.imageInternalFormat = EiifUnspecified;
|
||||
return layoutQualifier;
|
||||
}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return location == -1 && matrixPacking == EmpUnspecified &&
|
||||
blockStorage == EbsUnspecified && !localSize.isAnyValueSet() &&
|
||||
imageInternalFormat == EiifUnspecified;
|
||||
blockStorage == EbsUnspecified && !localSize.isAnyValueSet();
|
||||
}
|
||||
|
||||
bool isCombinationValid() const
|
||||
{
|
||||
bool workSizeSpecified = localSize.isAnyValueSet();
|
||||
bool otherLayoutQualifiersSpecified =
|
||||
(location != -1 || matrixPacking != EmpUnspecified || blockStorage != EbsUnspecified ||
|
||||
imageInternalFormat != EiifUnspecified);
|
||||
(location != -1 || matrixPacking != EmpUnspecified || blockStorage != EbsUnspecified);
|
||||
|
||||
// we can have either the work group size specified, or the other layout qualifiers
|
||||
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)
|
||||
{
|
||||
switch (dimension)
|
||||
|
|
@ -700,9 +482,6 @@ inline const char* getQualifierString(TQualifier q)
|
|||
case EvqSmoothIn: return "smooth in";
|
||||
case EvqFlatIn: return "flat in";
|
||||
case EvqCentroidIn: return "smooth centroid in";
|
||||
case EvqCentroid: return "centroid";
|
||||
case EvqFlat: return "flat";
|
||||
case EvqSmooth: return "smooth";
|
||||
case EvqComputeIn: return "in";
|
||||
case EvqNumWorkGroups: return "NumWorkGroups";
|
||||
case EvqWorkGroupSize: return "WorkGroupSize";
|
||||
|
|
@ -710,8 +489,6 @@ inline const char* getQualifierString(TQualifier q)
|
|||
case EvqLocalInvocationID: return "LocalInvocationID";
|
||||
case EvqGlobalInvocationID: return "GlobalInvocationID";
|
||||
case EvqLocalInvocationIndex: return "LocalInvocationIndex";
|
||||
case EvqReadOnly: return "readonly";
|
||||
case EvqWriteOnly: return "writeonly";
|
||||
default: UNREACHABLE(); return "unknown qualifier";
|
||||
}
|
||||
// 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:
|
||||
return "rgba32f";
|
||||
case EiifRGBA16F:
|
||||
return "rgba16f";
|
||||
case EiifR32F:
|
||||
return "r32f";
|
||||
case EiifRGBA32UI:
|
||||
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";
|
||||
case EvqSmoothOut: return "smooth"; break;
|
||||
case EvqCentroidOut: return "smooth centroid"; break;
|
||||
case EvqFlatOut: return "flat"; break;
|
||||
case EvqSmoothIn: return "smooth"; break;
|
||||
case EvqCentroidIn: return "smooth centroid"; break;
|
||||
case EvqFlatIn: return "flat"; break;
|
||||
default: UNREACHABLE(); return "unknown interpolation";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#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/Cache.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
|
|
@ -245,5 +242,3 @@ BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::FunctionId::getCopy
|
|||
{
|
||||
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/IntermNode.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
//
|
||||
// This class decides which built-in functions need to be replaced with the
|
||||
// emulated ones.
|
||||
|
|
@ -85,6 +82,4 @@ class BuiltInFunctionEmulator
|
|||
std::vector<FunctionId> mFunctions;
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
|
||||
|
|
|
|||
|
|
@ -11,68 +11,32 @@
|
|||
#include "compiler/translator/SymbolTable.h"
|
||||
#include "compiler/translator/VersionGLSL.h"
|
||||
|
||||
namespace sh
|
||||
void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType)
|
||||
{
|
||||
|
||||
void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
|
||||
sh::GLenum shaderType)
|
||||
{
|
||||
if (shaderType == GL_VERTEX_SHADER)
|
||||
{
|
||||
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;
|
||||
// we use macros here instead of function definitions to work around more GLSL
|
||||
// compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are
|
||||
// problematic because if the argument has side-effects they will be repeatedly
|
||||
// evaluated. This is unlikely to show up in real shaders, but is something to
|
||||
// consider.
|
||||
|
||||
const TType *float1 = TCache::getType(EbtFloat);
|
||||
const TType *float2 = TCache::getType(EbtFloat, 2);
|
||||
const TType *float3 = TCache::getType(EbtFloat, 3);
|
||||
const TType *float4 = TCache::getType(EbtFloat, 4);
|
||||
|
||||
// !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false.
|
||||
emu->addEmulatedFunction(
|
||||
EOpIsNan, float1,
|
||||
"bool webgl_isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
|
||||
emu->addEmulatedFunction(
|
||||
EOpIsNan, float2,
|
||||
"bvec2 webgl_isnan_emu(vec2 x)\n"
|
||||
"{\n"
|
||||
" bvec2 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,
|
||||
"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");
|
||||
if (shaderType == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
emu->addEmulatedFunction(EOpCos, float1, "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }");
|
||||
emu->addEmulatedFunction(EOpCos, float2, "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }");
|
||||
emu->addEmulatedFunction(EOpCos, float3, "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }");
|
||||
emu->addEmulatedFunction(EOpCos, float4, "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }");
|
||||
}
|
||||
emu->addEmulatedFunction(EOpDistance, float1, float1, "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))");
|
||||
emu->addEmulatedFunction(EOpDot, float1, float1, "#define webgl_dot_emu(x, y) ((x) * (y))");
|
||||
emu->addEmulatedFunction(EOpLength, float1, "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))");
|
||||
emu->addEmulatedFunction(EOpNormalize, float1, "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))");
|
||||
emu->addEmulatedFunction(EOpReflect, float1, float1, "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))");
|
||||
emu->addEmulatedFunction(EOpFaceForward, float1, float1, float1, "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))");
|
||||
}
|
||||
|
||||
// Emulate built-in functions missing from GLSL 1.30 and higher
|
||||
|
|
@ -217,9 +181,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
|
|||
" float scale;\n"
|
||||
" if(exponent < 0)\n"
|
||||
" {\n"
|
||||
" // The negative unary operator is buggy on OSX.\n"
|
||||
" // Work around this by using abs instead.\n"
|
||||
" scale = 1.0 / (1 << abs(exponent));\n"
|
||||
" scale = 1.0 / (1 << -exponent);\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
|
|
@ -251,5 +213,3 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
|
|||
// clang-format on
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -9,27 +9,17 @@
|
|||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
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,
|
||||
sh::GLenum shaderType);
|
||||
|
||||
//
|
||||
// This works around isnan() bug in Intel Mac drivers
|
||||
//
|
||||
void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
|
||||
int targetGLSLVersion);
|
||||
void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType);
|
||||
|
||||
//
|
||||
// This function is emulating built-in functions missing from GLSL 1.30 and higher.
|
||||
//
|
||||
void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType,
|
||||
int targetGLSLVersion);
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
|
||||
|
|
|
|||
|
|
@ -8,62 +8,6 @@
|
|||
#include "compiler/translator/BuiltInFunctionEmulator.h"
|
||||
#include "compiler/translator/BuiltInFunctionEmulatorHLSL.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)
|
||||
{
|
||||
|
|
@ -495,5 +439,3 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
|
|||
"}\n");
|
||||
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -9,19 +9,8 @@
|
|||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
class BuiltInFunctionEmulator;
|
||||
|
||||
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_
|
||||
|
|
|
|||
|
|
@ -12,9 +12,6 @@
|
|||
#include "common/debug.h"
|
||||
#include "compiler/translator/Cache.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
|
@ -47,6 +44,7 @@ TCache::TypeKey::TypeKey(TBasicType basicType,
|
|||
"TypeKey::value is too small");
|
||||
|
||||
const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max();
|
||||
UNUSED_ASSERTION_VARIABLE(MaxEnumValue);
|
||||
|
||||
// TODO: change to static_assert() once we deprecate MSVC 2013 support
|
||||
ASSERT(MaxEnumValue >= EbtLast &&
|
||||
|
|
@ -100,5 +98,3 @@ const TType *TCache::getType(TBasicType basicType,
|
|||
|
||||
return type;
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@
|
|||
#include "compiler/translator/Types.h"
|
||||
#include "compiler/translator/PoolAlloc.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
class TCache
|
||||
{
|
||||
public:
|
||||
|
|
@ -90,6 +87,4 @@ class TCache
|
|||
static TCache *sCache;
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_CACHE_H_
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@
|
|||
#include "compiler/translator/CallDAG.h"
|
||||
#include "compiler/translator/InfoSink.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
// The CallDAGCreator does all the processing required to create the CallDAG
|
||||
// structure so that the latter contains only the necessary variables.
|
||||
class CallDAG::CallDAGCreator : public TIntermTraverser
|
||||
|
|
@ -47,7 +44,6 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
|||
skipped++;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(mFunctions.size() == mCurrentIndex + skipped);
|
||||
return INITDAG_SUCCESS;
|
||||
}
|
||||
|
|
@ -79,8 +75,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
|||
record.callees.push_back(static_cast<int>(callee->index));
|
||||
}
|
||||
|
||||
(*idToIndex)[data.node->getFunctionSymbolInfo()->getId()] =
|
||||
static_cast<int>(data.index);
|
||||
(*idToIndex)[data.node->getFunctionId()] = static_cast<int>(data.index);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -97,39 +92,13 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
|||
}
|
||||
|
||||
std::set<CreatorFunctionData*> callees;
|
||||
TIntermFunctionDefinition *node;
|
||||
TIntermAggregate *node;
|
||||
TString name;
|
||||
size_t index;
|
||||
bool indexAssigned;
|
||||
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
|
||||
bool visitAggregate(Visit visit, TIntermAggregate *node) override
|
||||
{
|
||||
|
|
@ -139,10 +108,36 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
|||
if (visit == PreVisit)
|
||||
{
|
||||
// Function declaration, create an empty record.
|
||||
auto &record = mFunctions[node->getFunctionSymbolInfo()->getName()];
|
||||
record.name = node->getFunctionSymbolInfo()->getName();
|
||||
auto& record = mFunctions[node->getName()];
|
||||
record.name = node->getName();
|
||||
}
|
||||
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:
|
||||
{
|
||||
// Function call, add the callees
|
||||
|
|
@ -151,7 +146,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
|||
// Do not handle calls to builtin functions
|
||||
if (node->isUserDefined())
|
||||
{
|
||||
auto it = mFunctions.find(node->getFunctionSymbolInfo()->getName());
|
||||
auto it = mFunctions.find(node->getName());
|
||||
ASSERT(it != mFunctions.end());
|
||||
|
||||
// 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
|
||||
InitResult assignIndicesInternal(CreatorFunctionData *root)
|
||||
InitResult assignIndicesInternal(CreatorFunctionData *function)
|
||||
{
|
||||
// Iterative implementation of the index assignment algorithm. A recursive version
|
||||
// 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(function);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// If we didn't have to detect recursion, functionsToProcess could be a simple queue
|
||||
// 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())
|
||||
if (function->visiting)
|
||||
{
|
||||
CreatorFunctionData *function = functionsToProcess.back();
|
||||
|
||||
if (function->visiting)
|
||||
if (mCreationInfo)
|
||||
{
|
||||
function->visiting = false;
|
||||
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;
|
||||
}
|
||||
*mCreationInfo << "Recursive function call in the following call chain:" << function->name;
|
||||
}
|
||||
return INITDAG_RECURSION;
|
||||
}
|
||||
function->visiting = true;
|
||||
|
||||
for (auto &callee : function->callees)
|
||||
{
|
||||
InitResult result = assignIndicesInternal(callee);
|
||||
if (result != INITDAG_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
// 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)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
*mCreationInfo << " -> ";
|
||||
}
|
||||
*mCreationInfo << function->name << ")";
|
||||
first = false;
|
||||
*mCreationInfo << " <- " << function->name << ")";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
function->index = mCurrentIndex++;
|
||||
function->indexAssigned = true;
|
||||
|
||||
function->visiting = false;
|
||||
return INITDAG_SUCCESS;
|
||||
}
|
||||
|
||||
TInfoSinkBase *mCreationInfo;
|
||||
|
|
@ -287,9 +232,13 @@ CallDAG::~CallDAG()
|
|||
|
||||
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())
|
||||
{
|
||||
|
|
@ -309,7 +258,7 @@ const CallDAG::Record &CallDAG::getRecordFromIndex(size_t index) 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());
|
||||
return mRecords[index];
|
||||
}
|
||||
|
|
@ -327,8 +276,6 @@ void CallDAG::clear()
|
|||
|
||||
CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info)
|
||||
{
|
||||
ASSERT(info);
|
||||
|
||||
CallDAGCreator creator(info);
|
||||
|
||||
// Creates the mapping of functions to callees
|
||||
|
|
@ -344,5 +291,3 @@ CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info)
|
|||
creator.fillDataStructures(&mRecords, &mFunctionIdToIndex);
|
||||
return INITDAG_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
#include "compiler/translator/IntermNode.h"
|
||||
#include "compiler/translator/VariableInfo.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
// The translator needs to analyze the the graph of the function calls
|
||||
// to run checks and analyses; since in GLSL recursion is not allowed
|
||||
|
|
@ -43,7 +41,7 @@ class CallDAG : angle::NonCopyable
|
|||
struct Record
|
||||
{
|
||||
std::string name;
|
||||
TIntermFunctionDefinition *node;
|
||||
TIntermAggregate *node;
|
||||
std::vector<int> callees;
|
||||
};
|
||||
|
||||
|
|
@ -59,7 +57,7 @@ class CallDAG : angle::NonCopyable
|
|||
InitResult init(TIntermNode *root, TInfoSinkBase *info);
|
||||
|
||||
// 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 &getRecord(const TIntermAggregate *function) const;
|
||||
|
|
@ -74,6 +72,4 @@ class CallDAG : angle::NonCopyable
|
|||
class CallDAGCreator;
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_CALLDAG_H_
|
||||
|
|
|
|||
|
|
@ -6,79 +6,71 @@
|
|||
|
||||
#ifdef ANGLE_ENABLE_ESSL
|
||||
#include "compiler/translator/TranslatorESSL.h"
|
||||
#endif // ANGLE_ENABLE_ESSL
|
||||
#endif
|
||||
|
||||
#ifdef ANGLE_ENABLE_GLSL
|
||||
#include "compiler/translator/TranslatorGLSL.h"
|
||||
#endif // ANGLE_ENABLE_GLSL
|
||||
#endif
|
||||
|
||||
#ifdef ANGLE_ENABLE_HLSL
|
||||
#include "compiler/translator/TranslatorHLSL.h"
|
||||
#endif // ANGLE_ENABLE_HLSL
|
||||
|
||||
namespace sh
|
||||
{
|
||||
#endif // ANGLE_ENABLE_HLSL
|
||||
|
||||
//
|
||||
// This function must be provided to create the actual
|
||||
// compile object used by higher level code. It returns
|
||||
// a subclass of TCompiler.
|
||||
//
|
||||
TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
|
||||
TCompiler* ConstructCompiler(
|
||||
sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
|
||||
{
|
||||
switch (output)
|
||||
{
|
||||
case SH_ESSL_OUTPUT:
|
||||
switch (output) {
|
||||
case SH_ESSL_OUTPUT:
|
||||
#ifdef ANGLE_ENABLE_ESSL
|
||||
return new TranslatorESSL(type, spec);
|
||||
return new TranslatorESSL(type, spec);
|
||||
#else
|
||||
// This compiler is not supported in this configuration. Return NULL per the
|
||||
// sh::ConstructCompiler API.
|
||||
return nullptr;
|
||||
#endif // ANGLE_ENABLE_ESSL
|
||||
|
||||
case SH_GLSL_130_OUTPUT:
|
||||
case SH_GLSL_140_OUTPUT:
|
||||
case SH_GLSL_150_CORE_OUTPUT:
|
||||
case SH_GLSL_330_CORE_OUTPUT:
|
||||
case SH_GLSL_400_CORE_OUTPUT:
|
||||
case SH_GLSL_410_CORE_OUTPUT:
|
||||
case SH_GLSL_420_CORE_OUTPUT:
|
||||
case SH_GLSL_430_CORE_OUTPUT:
|
||||
case SH_GLSL_440_CORE_OUTPUT:
|
||||
case SH_GLSL_450_CORE_OUTPUT:
|
||||
case SH_GLSL_COMPATIBILITY_OUTPUT:
|
||||
// This compiler is not supported in this
|
||||
// configuration. Return NULL per the ShConstructCompiler API.
|
||||
return nullptr;
|
||||
#endif // ANGLE_ENABLE_ESSL
|
||||
case SH_GLSL_130_OUTPUT:
|
||||
case SH_GLSL_140_OUTPUT:
|
||||
case SH_GLSL_150_CORE_OUTPUT:
|
||||
case SH_GLSL_330_CORE_OUTPUT:
|
||||
case SH_GLSL_400_CORE_OUTPUT:
|
||||
case SH_GLSL_410_CORE_OUTPUT:
|
||||
case SH_GLSL_420_CORE_OUTPUT:
|
||||
case SH_GLSL_430_CORE_OUTPUT:
|
||||
case SH_GLSL_440_CORE_OUTPUT:
|
||||
case SH_GLSL_450_CORE_OUTPUT:
|
||||
case SH_GLSL_COMPATIBILITY_OUTPUT:
|
||||
#ifdef ANGLE_ENABLE_GLSL
|
||||
return new TranslatorGLSL(type, spec, output);
|
||||
return new TranslatorGLSL(type, spec, output);
|
||||
#else
|
||||
// This compiler is not supported in this configuration. Return NULL per the
|
||||
// sh::ConstructCompiler API.
|
||||
return nullptr;
|
||||
#endif // ANGLE_ENABLE_GLSL
|
||||
|
||||
case SH_HLSL_3_0_OUTPUT:
|
||||
case SH_HLSL_4_1_OUTPUT:
|
||||
case SH_HLSL_4_0_FL9_3_OUTPUT:
|
||||
// This compiler is not supported in this
|
||||
// configuration. Return NULL per the ShConstructCompiler API.
|
||||
return nullptr;
|
||||
#endif // ANGLE_ENABLE_GLSL
|
||||
case SH_HLSL_3_0_OUTPUT:
|
||||
case SH_HLSL_4_1_OUTPUT:
|
||||
case SH_HLSL_4_0_FL9_3_OUTPUT:
|
||||
#ifdef ANGLE_ENABLE_HLSL
|
||||
return new TranslatorHLSL(type, spec, output);
|
||||
return new TranslatorHLSL(type, spec, output);
|
||||
#else
|
||||
// This compiler is not supported in this configuration. Return NULL per the
|
||||
// sh::ConstructCompiler API.
|
||||
return nullptr;
|
||||
#endif // ANGLE_ENABLE_HLSL
|
||||
|
||||
default:
|
||||
// Unknown format. Return NULL per the sh::ConstructCompiler API.
|
||||
return nullptr;
|
||||
// This compiler is not supported in this
|
||||
// configuration. Return NULL per the ShConstructCompiler API.
|
||||
return nullptr;
|
||||
#endif // ANGLE_ENABLE_HLSL
|
||||
default:
|
||||
// Unknown format. Return NULL per the ShConstructCompiler API.
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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 "compiler/translator/PoolAlloc.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
struct TSourceLoc {
|
||||
int first_file;
|
||||
int first_line;
|
||||
|
|
@ -95,6 +92,4 @@ inline TString str(T i)
|
|||
return buffer;
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_COMMON_H_
|
||||
|
|
|
|||
|
|
@ -4,18 +4,11 @@
|
|||
// 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/Compiler.h"
|
||||
#include "compiler/translator/CallDAG.h"
|
||||
#include "compiler/translator/DeferGlobalInitializers.h"
|
||||
#include "compiler/translator/EmulateGLFragColorBroadcast.h"
|
||||
#include "compiler/translator/EmulatePrecision.h"
|
||||
#include "compiler/translator/ForLoopUnroll.h"
|
||||
#include "compiler/translator/Initialize.h"
|
||||
#include "compiler/translator/InitializeParseContext.h"
|
||||
|
|
@ -23,100 +16,41 @@
|
|||
#include "compiler/translator/ParseContext.h"
|
||||
#include "compiler/translator/PruneEmptyDeclarations.h"
|
||||
#include "compiler/translator/RegenerateStructNames.h"
|
||||
#include "compiler/translator/RemoveInvariantDeclaration.h"
|
||||
#include "compiler/translator/RemovePow.h"
|
||||
#include "compiler/translator/RenameFunction.h"
|
||||
#include "compiler/translator/RewriteDoWhile.h"
|
||||
#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
|
||||
#include "compiler/translator/UnfoldShortCircuitAST.h"
|
||||
#include "compiler/translator/UseInterfaceBlockFields.h"
|
||||
#include "compiler/translator/ValidateLimitations.h"
|
||||
#include "compiler/translator/ValidateMaxParameters.h"
|
||||
#include "compiler/translator/ValidateOutputs.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"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
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
|
||||
#include "angle_gl.h"
|
||||
#include "common/utilities.h"
|
||||
|
||||
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)
|
||||
{
|
||||
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 ||
|
||||
output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
|
||||
output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
|
||||
}
|
||||
|
||||
bool IsGLSL420OrNewer(ShShaderOutput output)
|
||||
{
|
||||
return (output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_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;
|
||||
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 ||
|
||||
output == SH_GLSL_420_CORE_OUTPUT ||
|
||||
output == SH_GLSL_430_CORE_OUTPUT ||
|
||||
output == SH_GLSL_440_CORE_OUTPUT ||
|
||||
output == SH_GLSL_450_CORE_OUTPUT);
|
||||
}
|
||||
|
||||
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
|
||||
|
|
@ -125,10 +59,11 @@ size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
|
|||
// size undefined. ES3 defines a max size of 1024 characters.
|
||||
switch (spec)
|
||||
{
|
||||
case SH_WEBGL_SPEC:
|
||||
return 256;
|
||||
default:
|
||||
return 1024;
|
||||
case SH_WEBGL_SPEC:
|
||||
case SH_CSS_SHADERS_SPEC:
|
||||
return 256;
|
||||
default:
|
||||
return 1024;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,18 +109,19 @@ int MapSpecToShaderVersion(ShShaderSpec spec)
|
|||
{
|
||||
switch (spec)
|
||||
{
|
||||
case SH_GLES2_SPEC:
|
||||
case SH_WEBGL_SPEC:
|
||||
return 100;
|
||||
case SH_GLES3_SPEC:
|
||||
case SH_WEBGL2_SPEC:
|
||||
return 300;
|
||||
case SH_GLES3_1_SPEC:
|
||||
case SH_WEBGL3_SPEC:
|
||||
return 310;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
case SH_GLES2_SPEC:
|
||||
case SH_WEBGL_SPEC:
|
||||
case SH_CSS_SHADERS_SPEC:
|
||||
return 100;
|
||||
case SH_GLES3_SPEC:
|
||||
case SH_WEBGL2_SPEC:
|
||||
return 300;
|
||||
case SH_GLES3_1_SPEC:
|
||||
case SH_WEBGL3_SPEC:
|
||||
return 310;
|
||||
default:
|
||||
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,
|
||||
// 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;
|
||||
}
|
||||
|
||||
TIntermBlock *TCompiler::compileTreeForTesting(const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
ShCompileOptions compileOptions)
|
||||
TIntermNode *TCompiler::compileTreeForTesting(const char* const shaderStrings[],
|
||||
size_t numStrings, int compileOptions)
|
||||
{
|
||||
return compileTreeImpl(shaderStrings, numStrings, compileOptions);
|
||||
}
|
||||
|
||||
TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
const ShCompileOptions compileOptions)
|
||||
TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
const int compileOptions)
|
||||
{
|
||||
clearResults();
|
||||
|
||||
|
|
@ -288,7 +223,8 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
|||
++firstSource;
|
||||
}
|
||||
|
||||
TParseContext parseContext(symbolTable, extensionBehavior, shaderType, shaderSpec,
|
||||
TIntermediate intermediate(infoSink);
|
||||
TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec,
|
||||
compileOptions, true, infoSink, getResources());
|
||||
|
||||
parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh);
|
||||
|
|
@ -311,7 +247,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
|||
success = false;
|
||||
}
|
||||
|
||||
TIntermBlock *root = nullptr;
|
||||
TIntermNode *root = nullptr;
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
|
@ -322,6 +258,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
|||
mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize();
|
||||
|
||||
root = parseContext.getTreeRoot();
|
||||
root = intermediate.postProcess(root);
|
||||
|
||||
// Highp might have been auto-enabled based on shader version
|
||||
fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
|
||||
|
|
@ -358,17 +295,11 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
|||
if (success && shouldRunLoopAndIndexingValidation(compileOptions))
|
||||
success = validateLimitations(root);
|
||||
|
||||
// Fail compilation if precision emulation not supported.
|
||||
if (success && getResources().WEBGL_debug_shader_precision &&
|
||||
getPragma().debugShaderPrecision)
|
||||
{
|
||||
if (!EmulatePrecision::SupportedInLanguage(outputType))
|
||||
{
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Precision emulation not supported for this output type.";
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (success && (compileOptions & SH_TIMING_RESTRICTIONS))
|
||||
success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0);
|
||||
|
||||
if (success && shaderSpec == SH_CSS_SHADERS_SPEC)
|
||||
rewriteCSSShader(root);
|
||||
|
||||
// Unroll for-loop markup needs to happen after validateLimitations pass.
|
||||
if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
|
||||
|
|
@ -410,16 +341,10 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
|||
(outputType == SH_GLSL_COMPATIBILITY_OUTPUT)))
|
||||
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
|
||||
if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS))
|
||||
RewriteDoWhile(root, getTemporaryIndex());
|
||||
|
||||
if (success && (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION))
|
||||
sh::AddAndTrueToLoopCondition(root);
|
||||
|
||||
if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT))
|
||||
{
|
||||
UnfoldShortCircuitAST unfoldShortCircuit;
|
||||
|
|
@ -435,10 +360,6 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
|||
if (success && shouldCollectVariables(compileOptions))
|
||||
{
|
||||
collectVariables(root);
|
||||
if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
|
||||
{
|
||||
useAllMembersInUnusedStandardAndSharedBlocks(root);
|
||||
}
|
||||
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
|
||||
{
|
||||
success = enforcePackingRestrictions();
|
||||
|
|
@ -456,8 +377,9 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
|||
|
||||
if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS))
|
||||
{
|
||||
ScalarizeVecAndMatConstructorArgs(root, shaderType, fragmentPrecisionHigh,
|
||||
&mTemporaryIndex);
|
||||
ScalarizeVecAndMatConstructorArgs scalarizer(
|
||||
shaderType, fragmentPrecisionHigh);
|
||||
root->traverse(&scalarizer);
|
||||
}
|
||||
|
||||
if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES))
|
||||
|
|
@ -486,18 +408,12 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool TCompiler::compile(const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
ShCompileOptions compileOptionsIn)
|
||||
bool TCompiler::compile(const char *const shaderStrings[], size_t numStrings, int 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)
|
||||
return true;
|
||||
|
||||
ShCompileOptions compileOptions = compileOptionsIn;
|
||||
int compileOptions = compileOptionsIn;
|
||||
|
||||
// Apply key workarounds.
|
||||
if (shouldFlattenPragmaStdglInvariantAll())
|
||||
|
|
@ -506,19 +422,8 @@ bool TCompiler::compile(const char *const shaderStrings[],
|
|||
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);
|
||||
TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
|
||||
TIntermNode *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
|
||||
|
||||
if (root)
|
||||
{
|
||||
|
|
@ -547,26 +452,32 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
|
|||
symbolTable.push(); // ESSL3_1_BUILTINS
|
||||
|
||||
TPublicType integer;
|
||||
integer.initializeBasicType(EbtInt);
|
||||
integer.type = EbtInt;
|
||||
integer.primarySize = 1;
|
||||
integer.secondarySize = 1;
|
||||
integer.array = false;
|
||||
|
||||
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:
|
||||
symbolTable.setDefaultPrecision(integer, EbpMedium);
|
||||
break;
|
||||
case GL_VERTEX_SHADER:
|
||||
symbolTable.setDefaultPrecision(integer, EbpHigh);
|
||||
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
|
||||
break;
|
||||
case GL_COMPUTE_SHADER:
|
||||
symbolTable.setDefaultPrecision(integer, EbpHigh);
|
||||
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
|
||||
break;
|
||||
default:
|
||||
assert(false && "Language not supported");
|
||||
case GL_FRAGMENT_SHADER:
|
||||
symbolTable.setDefaultPrecision(integer, EbpMedium);
|
||||
break;
|
||||
case GL_VERTEX_SHADER:
|
||||
symbolTable.setDefaultPrecision(integer, EbpHigh);
|
||||
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
|
||||
break;
|
||||
case GL_COMPUTE_SHADER:
|
||||
symbolTable.setDefaultPrecision(integer, EbpHigh);
|
||||
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
|
||||
break;
|
||||
default:
|
||||
assert(false && "Language not supported");
|
||||
}
|
||||
// Set defaults for sampler types that have default precision, even those that are
|
||||
// only available if an extension exists.
|
||||
|
|
@ -589,7 +500,10 @@ void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType)
|
|||
{
|
||||
ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd);
|
||||
TPublicType sampler;
|
||||
sampler.initializeBasicType(samplerType);
|
||||
sampler.primarySize = 1;
|
||||
sampler.secondarySize = 1;
|
||||
sampler.array = false;
|
||||
sampler.type = samplerType;
|
||||
symbolTable.setDefaultPrecision(sampler, EbpLow);
|
||||
}
|
||||
|
||||
|
|
@ -599,60 +513,60 @@ void TCompiler::setResourceString()
|
|||
|
||||
// clang-format off
|
||||
strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs
|
||||
<< ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
|
||||
<< ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
|
||||
<< ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits
|
||||
<< ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits
|
||||
<< ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits
|
||||
<< ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors
|
||||
<< ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
|
||||
<< ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
|
||||
<< ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
|
||||
<< ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3
|
||||
<< ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external
|
||||
<< ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
|
||||
<< ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
|
||||
<< ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
|
||||
<< ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity
|
||||
<< ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
|
||||
<< ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters
|
||||
<< ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended
|
||||
<< ":EXT_frag_depth:" << compileResources.EXT_frag_depth
|
||||
<< ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
|
||||
<< ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
|
||||
<< ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
|
||||
<< ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
|
||||
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
|
||||
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
|
||||
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
|
||||
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
|
||||
<< ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
|
||||
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers
|
||||
<< ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision
|
||||
<< ":MaxImageUnits:" << compileResources.MaxImageUnits
|
||||
<< ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms
|
||||
<< ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms
|
||||
<< ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms
|
||||
<< ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms
|
||||
<< ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources
|
||||
<< ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0]
|
||||
<< ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1]
|
||||
<< ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2]
|
||||
<< ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0]
|
||||
<< ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1]
|
||||
<< ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2]
|
||||
<< ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents
|
||||
<< ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits
|
||||
<< ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters
|
||||
<< ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers
|
||||
<< ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters
|
||||
<< ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters
|
||||
<< ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters
|
||||
<< ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings
|
||||
<< ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers
|
||||
<< ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers
|
||||
<< ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers
|
||||
<< ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize;
|
||||
<< ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
|
||||
<< ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
|
||||
<< ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits
|
||||
<< ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits
|
||||
<< ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits
|
||||
<< ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors
|
||||
<< ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
|
||||
<< ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
|
||||
<< ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
|
||||
<< ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3
|
||||
<< ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external
|
||||
<< ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
|
||||
<< ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
|
||||
<< ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
|
||||
<< ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity
|
||||
<< ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
|
||||
<< ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters
|
||||
<< ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended
|
||||
<< ":EXT_frag_depth:" << compileResources.EXT_frag_depth
|
||||
<< ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
|
||||
<< ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
|
||||
<< ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
|
||||
<< ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
|
||||
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
|
||||
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
|
||||
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
|
||||
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
|
||||
<< ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
|
||||
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers
|
||||
<< ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision
|
||||
<< ":MaxImageUnits:" << compileResources.MaxImageUnits
|
||||
<< ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms
|
||||
<< ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms
|
||||
<< ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms
|
||||
<< ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms
|
||||
<< ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources
|
||||
<< ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0]
|
||||
<< ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1]
|
||||
<< ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2]
|
||||
<< ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0]
|
||||
<< ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1]
|
||||
<< ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2]
|
||||
<< ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents
|
||||
<< ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits
|
||||
<< ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters
|
||||
<< ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers
|
||||
<< ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters
|
||||
<< ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters
|
||||
<< ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters
|
||||
<< ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings
|
||||
<< ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers
|
||||
<< ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers
|
||||
<< ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers
|
||||
<< ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize;
|
||||
// clang-format on
|
||||
|
||||
builtInResourcesString = strstream.str();
|
||||
|
|
@ -687,16 +601,16 @@ bool TCompiler::initCallDag(TIntermNode *root)
|
|||
|
||||
switch (mCallDag.init(root, &infoSink.info))
|
||||
{
|
||||
case CallDAG::INITDAG_SUCCESS:
|
||||
return true;
|
||||
case CallDAG::INITDAG_RECURSION:
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Function recursion detected";
|
||||
return false;
|
||||
case CallDAG::INITDAG_UNDEFINED:
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Unimplemented function detected";
|
||||
return false;
|
||||
case CallDAG::INITDAG_SUCCESS:
|
||||
return true;
|
||||
case CallDAG::INITDAG_RECURSION:
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Function recursion detected";
|
||||
return false;
|
||||
case CallDAG::INITDAG_UNDEFINED:
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Unimplemented function detected";
|
||||
return false;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
|
|
@ -790,38 +704,30 @@ class TCompiler::UnusedPredicate
|
|||
{
|
||||
public:
|
||||
UnusedPredicate(const CallDAG *callDag, const std::vector<FunctionMetadata> *metadatas)
|
||||
: mCallDag(callDag), mMetadatas(metadatas)
|
||||
: mCallDag(callDag),
|
||||
mMetadatas(metadatas)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator ()(TIntermNode *node)
|
||||
{
|
||||
const TIntermAggregate *asAggregate = node->getAsAggregate();
|
||||
const TIntermFunctionDefinition *asFunction = node->getAsFunctionDefinition();
|
||||
|
||||
const TFunctionSymbolInfo *functionInfo = nullptr;
|
||||
|
||||
if (asFunction)
|
||||
{
|
||||
functionInfo = asFunction->getFunctionSymbolInfo();
|
||||
}
|
||||
else if (asAggregate)
|
||||
{
|
||||
if (asAggregate->getOp() == EOpPrototype)
|
||||
{
|
||||
functionInfo = asAggregate->getFunctionSymbolInfo();
|
||||
}
|
||||
}
|
||||
if (functionInfo == nullptr)
|
||||
if (asAggregate == nullptr)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// This happens only for unimplemented prototypes which are thus unused
|
||||
ASSERT(asAggregate && asAggregate->getOp() == EOpPrototype);
|
||||
ASSERT(asAggregate->getOp() == EOpPrototype);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -834,10 +740,13 @@ class TCompiler::UnusedPredicate
|
|||
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);
|
||||
TIntermSequence *sequence = root->getSequence();
|
||||
TIntermSequence *sequence = rootNode->getSequence();
|
||||
|
||||
if (!sequence->empty())
|
||||
{
|
||||
|
|
@ -854,6 +763,12 @@ bool TCompiler::validateOutputs(TIntermNode* root)
|
|||
return (validateOutputs.validateAndCountErrors(infoSink.info) == 0);
|
||||
}
|
||||
|
||||
void TCompiler::rewriteCSSShader(TIntermNode* root)
|
||||
{
|
||||
RenameFunction renamer("main(", "css_main(");
|
||||
root->traverse(&renamer);
|
||||
}
|
||||
|
||||
bool TCompiler::validateLimitations(TIntermNode* root)
|
||||
{
|
||||
ValidateLimitations validate(shaderType, &infoSink.info);
|
||||
|
|
@ -861,9 +776,39 @@ bool TCompiler::validateLimitations(TIntermNode* root)
|
|||
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)
|
||||
{
|
||||
TMaxDepthTraverser traverser(maxExpressionComplexity + 1);
|
||||
TMaxDepthTraverser traverser(maxExpressionComplexity+1);
|
||||
root->traverse(&traverser);
|
||||
|
||||
if (traverser.getMaxDepth() > maxExpressionComplexity)
|
||||
|
|
@ -881,13 +826,26 @@ bool TCompiler::limitExpressionComplexity(TIntermNode* root)
|
|||
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)
|
||||
{
|
||||
if (!variablesCollected)
|
||||
{
|
||||
sh::CollectVariables collect(&attributes, &outputVariables, &uniforms, &varyings,
|
||||
&interfaceBlocks, hashFunction, symbolTable,
|
||||
extensionBehavior);
|
||||
&interfaceBlocks, hashFunction, symbolTable, extensionBehavior);
|
||||
root->traverse(&collect);
|
||||
|
||||
// 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()
|
||||
{
|
||||
VariablePacker packer;
|
||||
|
|
@ -918,23 +866,7 @@ void TCompiler::initializeGLPosition(TIntermNode* root)
|
|||
sh::ShaderVariable var(GL_FLOAT_VEC4, 0);
|
||||
var.name = "gl_Position";
|
||||
list.push_back(var);
|
||||
InitializeVariables(root, list, symbolTable);
|
||||
}
|
||||
|
||||
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);
|
||||
InitializeVariables(root, list);
|
||||
}
|
||||
|
||||
void TCompiler::initializeOutputVariables(TIntermNode *root)
|
||||
|
|
@ -955,7 +887,7 @@ void TCompiler::initializeOutputVariables(TIntermNode *root)
|
|||
list.push_back(var);
|
||||
}
|
||||
}
|
||||
InitializeVariables(root, list, symbolTable);
|
||||
InitializeVariables(root, list);
|
||||
}
|
||||
|
||||
const TExtensionBehavior& TCompiler::getExtensionBehavior() const
|
||||
|
|
@ -988,7 +920,7 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
|
|||
return builtInFunctionEmulator;
|
||||
}
|
||||
|
||||
void TCompiler::writePragma(ShCompileOptions compileOptions)
|
||||
void TCompiler::writePragma(int compileOptions)
|
||||
{
|
||||
if (!(compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL))
|
||||
{
|
||||
|
|
@ -1011,5 +943,3 @@ bool TCompiler::isVaryingDefined(const char *varyingName)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -24,16 +24,15 @@
|
|||
#include "compiler/translator/VariableInfo.h"
|
||||
#include "third_party/compiler/ArrayBoundsClamper.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
class TCompiler;
|
||||
class TDependencyGraph;
|
||||
#ifdef ANGLE_ENABLE_HLSL
|
||||
class TranslatorHLSL;
|
||||
#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);
|
||||
|
||||
|
|
@ -41,16 +40,6 @@ bool IsWebGLBasedSpec(ShShaderSpec spec);
|
|||
// Helper function to check if the shader type is GLSL.
|
||||
//
|
||||
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.
|
||||
|
|
@ -85,14 +74,12 @@ class TCompiler : public TShHandleBase
|
|||
|
||||
// compileTreeForTesting should be used only when tests require access to
|
||||
// the AST. Users of this function need to manually manage the global pool
|
||||
// allocator. Returns nullptr whenever there are compilation errors.
|
||||
TIntermBlock *compileTreeForTesting(const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
ShCompileOptions compileOptions);
|
||||
// allocator. Returns NULL whenever there are compilation errors.
|
||||
TIntermNode *compileTreeForTesting(const char* const shaderStrings[],
|
||||
size_t numStrings, int compileOptions);
|
||||
|
||||
bool compile(const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
ShCompileOptions compileOptions);
|
||||
bool compile(const char* const shaderStrings[],
|
||||
size_t numStrings, int compileOptions);
|
||||
|
||||
// Get results of the last compilation.
|
||||
int getShaderVersion() const { return shaderVersion; }
|
||||
|
|
@ -117,7 +104,7 @@ class TCompiler : public TShHandleBase
|
|||
ShShaderOutput getOutputType() const { return outputType; }
|
||||
const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
|
||||
|
||||
bool shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const;
|
||||
bool shouldRunLoopAndIndexingValidation(int compileOptions) const;
|
||||
|
||||
// Get the resources set by InitBuiltInSymbolTable
|
||||
const ShBuiltInResources& getResources() const;
|
||||
|
|
@ -132,21 +119,20 @@ class TCompiler : public TShHandleBase
|
|||
bool checkCallDepth();
|
||||
// Returns true if a program has no conflicting or missing fragment outputs
|
||||
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
|
||||
// functionality mandated in GLSL 1.0 spec Appendix A.
|
||||
bool validateLimitations(TIntermNode* root);
|
||||
// Collect info for all attribs, uniforms, varyings.
|
||||
void collectVariables(TIntermNode* root);
|
||||
// Add emulated functions to the built-in function emulator.
|
||||
virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
|
||||
ShCompileOptions compileOptions){};
|
||||
virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) {};
|
||||
// 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
|
||||
// Appendix A, section 7, the shader does not use too many uniforms.
|
||||
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().
|
||||
// This is to avoid undefined behaviors.
|
||||
void initializeOutputVariables(TIntermNode *root);
|
||||
|
|
@ -155,13 +141,20 @@ class TCompiler : public TShHandleBase
|
|||
// while spec says it is allowed.
|
||||
// This function should only be applied to vertex shaders.
|
||||
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.
|
||||
bool limitExpressionComplexity(TIntermNode* root);
|
||||
// Get built-in extensions with default behavior.
|
||||
const TExtensionBehavior& getExtensionBehavior() const;
|
||||
const char *getSourcePath() const;
|
||||
const TPragma& getPragma() const { return mPragma; }
|
||||
void writePragma(ShCompileOptions compileOptions);
|
||||
void writePragma(int compileOptions);
|
||||
unsigned int *getTemporaryIndex() { return &mTemporaryIndex; }
|
||||
// Relies on collectVariables having been called.
|
||||
bool isVaryingDefined(const char *varyingName);
|
||||
|
|
@ -170,16 +163,20 @@ class TCompiler : public TShHandleBase
|
|||
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
|
||||
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
|
||||
|
||||
virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
|
||||
virtual bool shouldCollectVariables(ShCompileOptions compileOptions);
|
||||
virtual bool shouldCollectVariables(int compileOptions)
|
||||
{
|
||||
return (compileOptions & SH_VARIABLES) != 0;
|
||||
}
|
||||
|
||||
virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
|
||||
|
||||
bool wereVariablesCollected() const;
|
||||
std::vector<sh::Attribute> attributes;
|
||||
std::vector<sh::OutputVariable> outputVariables;
|
||||
std::vector<sh::Uniform> uniforms;
|
||||
std::vector<sh::ShaderVariable> expandedUniforms;
|
||||
std::vector<sh::Varying> varyings;
|
||||
std::vector<sh::InterfaceBlock> interfaceBlocks;
|
||||
bool variablesCollected;
|
||||
|
||||
private:
|
||||
// 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);
|
||||
|
||||
// Collect info for all attribs, uniforms, varyings.
|
||||
void collectVariables(TIntermNode *root);
|
||||
|
||||
bool variablesCollected;
|
||||
|
||||
// Removes unused function declarations and prototypes from the AST
|
||||
class UnusedPredicate;
|
||||
bool pruneUnusedFunctions(TIntermBlock *root);
|
||||
bool pruneUnusedFunctions(TIntermNode *root);
|
||||
|
||||
TIntermBlock *compileTreeImpl(const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
const ShCompileOptions compileOptions);
|
||||
TIntermNode *compileTreeImpl(const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
const int compileOptions);
|
||||
|
||||
sh::GLenum shaderType;
|
||||
ShShaderSpec shaderSpec;
|
||||
|
|
@ -269,6 +261,4 @@ TCompiler* ConstructCompiler(
|
|||
sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
|
||||
void DeleteCompiler(TCompiler*);
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#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 "compiler/translator/Common.h"
|
||||
#include "compiler/translator/BaseTypes.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
class TDiagnostics;
|
||||
|
||||
class TConstantUnion
|
||||
{
|
||||
public:
|
||||
class TConstantUnion {
|
||||
public:
|
||||
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 setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
|
||||
|
|
@ -35,57 +91,258 @@ class TConstantUnion
|
|||
float getFConst() const { return fConst; }
|
||||
bool getBConst() const { return bConst; }
|
||||
|
||||
bool operator==(const int i) const;
|
||||
bool operator==(const unsigned int u) const;
|
||||
bool operator==(const float f) const;
|
||||
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 float f) const;
|
||||
bool operator!=(const bool b) const;
|
||||
bool operator!=(const TConstantUnion &constant) const;
|
||||
bool operator>(const TConstantUnion &constant) const;
|
||||
bool operator<(const TConstantUnion &constant) const;
|
||||
static TConstantUnion add(const TConstantUnion &lhs,
|
||||
const TConstantUnion &rhs,
|
||||
TDiagnostics *diag,
|
||||
const TSourceLoc &line);
|
||||
static TConstantUnion sub(const TConstantUnion &lhs,
|
||||
const TConstantUnion &rhs,
|
||||
TDiagnostics *diag,
|
||||
const TSourceLoc &line);
|
||||
static TConstantUnion mul(const TConstantUnion &lhs,
|
||||
const TConstantUnion &rhs,
|
||||
TDiagnostics *diag,
|
||||
const TSourceLoc &line);
|
||||
TConstantUnion operator%(const TConstantUnion &constant) const;
|
||||
static TConstantUnion rshift(const TConstantUnion &lhs,
|
||||
const TConstantUnion &rhs,
|
||||
TDiagnostics *diag,
|
||||
const TSourceLoc &line);
|
||||
static TConstantUnion lshift(const TConstantUnion &lhs,
|
||||
const TConstantUnion &rhs,
|
||||
TDiagnostics *diag,
|
||||
const TSourceLoc &line);
|
||||
TConstantUnion operator&(const TConstantUnion &constant) const;
|
||||
TConstantUnion operator|(const TConstantUnion &constant) const;
|
||||
TConstantUnion operator^(const TConstantUnion &constant) const;
|
||||
TConstantUnion operator&&(const TConstantUnion &constant) const;
|
||||
TConstantUnion operator||(const TConstantUnion &constant) const;
|
||||
bool operator==(const int i) const
|
||||
{
|
||||
return i == iConst;
|
||||
}
|
||||
|
||||
bool operator==(const unsigned int u) const
|
||||
{
|
||||
return u == uConst;
|
||||
}
|
||||
|
||||
bool operator==(const float f) const
|
||||
{
|
||||
return f == fConst;
|
||||
}
|
||||
|
||||
bool operator==(const bool b) const
|
||||
{
|
||||
return b == bConst;
|
||||
}
|
||||
|
||||
bool 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 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; }
|
||||
private:
|
||||
union {
|
||||
int iConst; // used for ivec, scalar ints
|
||||
unsigned int uConst; // used for uvec, scalar uints
|
||||
bool bConst; // used for bvec, scalar bools
|
||||
float fConst; // used for vec, mat, scalar floats
|
||||
};
|
||||
private:
|
||||
|
||||
union {
|
||||
int iConst; // used for ivec, scalar ints
|
||||
unsigned int uConst; // used for uvec, scalar uints
|
||||
bool bConst; // used for bvec, scalar bools
|
||||
float fConst; // used for vec, mat, scalar floats
|
||||
} ;
|
||||
|
||||
TBasicType type;
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_
|
||||
|
|
|
|||
|
|
@ -15,43 +15,42 @@
|
|||
#include "compiler/translator/IntermNode.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void SetInternalFunctionName(TFunctionSymbolInfo *functionInfo, const char *name)
|
||||
void SetInternalFunctionName(TIntermAggregate *functionNode, const char *name)
|
||||
{
|
||||
TString nameStr(name);
|
||||
nameStr = TFunction::mangleName(nameStr);
|
||||
TName nameObj(nameStr);
|
||||
nameObj.setInternal(true);
|
||||
functionInfo->setNameObj(nameObj);
|
||||
functionNode->setNameObj(nameObj);
|
||||
}
|
||||
|
||||
TIntermAggregate *CreateFunctionPrototypeNode(const char *name, const int functionId)
|
||||
{
|
||||
TIntermAggregate *functionNode = new TIntermAggregate(EOpPrototype);
|
||||
|
||||
SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
|
||||
SetInternalFunctionName(functionNode, name);
|
||||
TType returnType(EbtVoid);
|
||||
functionNode->setType(returnType);
|
||||
functionNode->getFunctionSymbolInfo()->setId(functionId);
|
||||
functionNode->setFunctionId(functionId);
|
||||
return functionNode;
|
||||
}
|
||||
|
||||
TIntermFunctionDefinition *CreateFunctionDefinitionNode(const char *name,
|
||||
TIntermBlock *functionBody,
|
||||
const int functionId)
|
||||
TIntermAggregate *CreateFunctionDefinitionNode(const char *name,
|
||||
TIntermAggregate *functionBody,
|
||||
const int functionId)
|
||||
{
|
||||
TType returnType(EbtVoid);
|
||||
TIntermAggregate *functionNode = new TIntermAggregate(EOpFunction);
|
||||
TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters);
|
||||
TIntermFunctionDefinition *functionNode =
|
||||
new TIntermFunctionDefinition(returnType, paramsNode, functionBody);
|
||||
functionNode->getSequence()->push_back(paramsNode);
|
||||
functionNode->getSequence()->push_back(functionBody);
|
||||
|
||||
SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
|
||||
functionNode->getFunctionSymbolInfo()->setId(functionId);
|
||||
SetInternalFunctionName(functionNode, name);
|
||||
TType returnType(EbtVoid);
|
||||
functionNode->setType(returnType);
|
||||
functionNode->setFunctionId(functionId);
|
||||
return functionNode;
|
||||
}
|
||||
|
||||
|
|
@ -60,10 +59,10 @@ TIntermAggregate *CreateFunctionCallNode(const char *name, const int functionId)
|
|||
TIntermAggregate *functionNode = new TIntermAggregate(EOpFunctionCall);
|
||||
|
||||
functionNode->setUserDefined();
|
||||
SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
|
||||
SetInternalFunctionName(functionNode, name);
|
||||
TType returnType(EbtVoid);
|
||||
functionNode->setType(returnType);
|
||||
functionNode->getFunctionSymbolInfo()->setId(functionId);
|
||||
functionNode->setFunctionId(functionId);
|
||||
return functionNode;
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +73,7 @@ class DeferGlobalInitializersTraverser : public TIntermTraverser
|
|||
|
||||
bool visitBinary(Visit visit, TIntermBinary *node) override;
|
||||
|
||||
void insertInitFunction(TIntermBlock *root);
|
||||
void insertInitFunction(TIntermNode *root);
|
||||
|
||||
private:
|
||||
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,
|
||||
// since otherwise there's a chance that HLSL output will generate extra statements
|
||||
// from the initializer expression.
|
||||
TIntermBinary *deferredInit =
|
||||
new TIntermBinary(EOpAssign, symbolNode->deepCopy(), node->getRight());
|
||||
TIntermBinary *deferredInit = new TIntermBinary(EOpAssign);
|
||||
deferredInit->setLeft(symbolNode->deepCopy());
|
||||
deferredInit->setRight(node->getRight());
|
||||
deferredInit->setType(node->getType());
|
||||
mDeferredInitializers.push_back(deferredInit);
|
||||
|
||||
// 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)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
TIntermBinary *siblingBinary = siblingNode->getAsBinaryNode();
|
||||
|
|
@ -135,51 +136,56 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n
|
|||
return false;
|
||||
}
|
||||
|
||||
void DeferGlobalInitializersTraverser::insertInitFunction(TIntermBlock *root)
|
||||
void DeferGlobalInitializersTraverser::insertInitFunction(TIntermNode *root)
|
||||
{
|
||||
if (mDeferredInitializers.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const int initFunctionId = TSymbolTable::nextUniqueId();
|
||||
TIntermAggregate *rootAgg = root->getAsAggregate();
|
||||
ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence);
|
||||
|
||||
const char *functionName = "initializeDeferredGlobals";
|
||||
|
||||
// Add function prototype to the beginning of the shader
|
||||
TIntermAggregate *functionPrototypeNode =
|
||||
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
|
||||
TIntermBlock *functionBodyNode = new TIntermBlock();
|
||||
TIntermAggregate *functionBodyNode = new TIntermAggregate(EOpSequence);
|
||||
TIntermSequence *functionBody = functionBodyNode->getSequence();
|
||||
for (const auto &deferredInit : mDeferredInitializers)
|
||||
{
|
||||
functionBody->push_back(deferredInit);
|
||||
}
|
||||
TIntermFunctionDefinition *functionDefinition =
|
||||
TIntermAggregate *functionDefinition =
|
||||
CreateFunctionDefinitionNode(functionName, functionBodyNode, initFunctionId);
|
||||
root->getSequence()->push_back(functionDefinition);
|
||||
rootAgg->getSequence()->push_back(functionDefinition);
|
||||
|
||||
// Insert call into main function
|
||||
for (TIntermNode *node : *root->getSequence())
|
||||
for (TIntermNode *node : *rootAgg->getSequence())
|
||||
{
|
||||
TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
|
||||
if (nodeFunction != nullptr && nodeFunction->getFunctionSymbolInfo()->isMain())
|
||||
TIntermAggregate *nodeAgg = node->getAsAggregate();
|
||||
if (nodeAgg != nullptr && nodeAgg->getOp() == EOpFunction &&
|
||||
TFunction::unmangleName(nodeAgg->getName()) == "main")
|
||||
{
|
||||
TIntermAggregate *functionCallNode =
|
||||
CreateFunctionCallNode(functionName, initFunctionId);
|
||||
|
||||
TIntermBlock *mainBody = nodeFunction->getBody();
|
||||
ASSERT(mainBody != nullptr);
|
||||
mainBody->getSequence()->insert(mainBody->getSequence()->begin(), functionCallNode);
|
||||
TIntermNode *mainBody = nodeAgg->getSequence()->back();
|
||||
TIntermAggregate *mainBodyAgg = mainBody->getAsAggregate();
|
||||
ASSERT(mainBodyAgg != nullptr && mainBodyAgg->getOp() == EOpSequence);
|
||||
mainBodyAgg->getSequence()->insert(mainBodyAgg->getSequence()->begin(),
|
||||
functionCallNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void DeferGlobalInitializers(TIntermBlock *root)
|
||||
void DeferGlobalInitializers(TIntermNode *root)
|
||||
{
|
||||
DeferGlobalInitializersTraverser traverser;
|
||||
root->traverse(&traverser);
|
||||
|
|
@ -190,5 +196,3 @@ void DeferGlobalInitializers(TIntermBlock *root)
|
|||
// Add the function with initialization and the call to that.
|
||||
traverser.insertInitFunction(root);
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -13,11 +13,8 @@
|
|||
#ifndef COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
|
||||
#define COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
|
||||
|
||||
class TIntermBlock;
|
||||
class TIntermNode;
|
||||
|
||||
namespace sh
|
||||
{
|
||||
void DeferGlobalInitializers(TIntermBlock *root);
|
||||
} // namespace sh
|
||||
void DeferGlobalInitializers(TIntermNode *root);
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@
|
|||
#include "compiler/translator/Common.h"
|
||||
#include "compiler/translator/InfoSink.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
TDiagnostics::TDiagnostics(TInfoSink& infoSink) :
|
||||
mInfoSink(infoSink),
|
||||
mNumErrors(0),
|
||||
|
|
@ -82,5 +79,3 @@ void TDiagnostics::print(ID id,
|
|||
{
|
||||
writeInfo(severity(id), loc, message(id), text, "");
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@
|
|||
#include "common/angleutils.h"
|
||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
class TInfoSink;
|
||||
struct TSourceLoc;
|
||||
|
||||
|
|
@ -48,6 +45,4 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable
|
|||
int mNumWarnings;
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_
|
||||
|
|
|
|||
|
|
@ -12,9 +12,6 @@
|
|||
#include "common/debug.h"
|
||||
#include "compiler/translator/Diagnostics.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
static TBehavior getBehavior(const std::string& str)
|
||||
{
|
||||
const char kRequire[] = "require";
|
||||
|
|
@ -198,5 +195,3 @@ void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
|
|||
"version number", str, "not supported");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@
|
|||
#include "compiler/preprocessor/DirectiveHandlerBase.h"
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
class TDiagnostics;
|
||||
|
||||
class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
|
||||
|
|
@ -52,6 +50,4 @@ class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
|
|||
bool mDebugShaderPrecisionSupported;
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
|
||||
|
|
|
|||
|
|
@ -14,60 +14,59 @@
|
|||
#include "compiler/translator/EmulateGLFragColorBroadcast.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
GLFragColorBroadcastTraverser(int maxDrawBuffers)
|
||||
: TIntermTraverser(true, false, false),
|
||||
mMainSequence(nullptr),
|
||||
mGLFragColorUsed(false),
|
||||
mMaxDrawBuffers(maxDrawBuffers)
|
||||
GLFragColorBroadcastTraverser()
|
||||
: TIntermTraverser(true, false, false), mMainSequence(nullptr), mGLFragColorUsed(false)
|
||||
{
|
||||
}
|
||||
|
||||
void broadcastGLFragColor();
|
||||
void broadcastGLFragColor(int maxDrawBuffers);
|
||||
|
||||
bool isGLFragColorUsed() const { return mGLFragColorUsed; }
|
||||
|
||||
protected:
|
||||
void visitSymbol(TIntermSymbol *node) override;
|
||||
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
|
||||
|
||||
TIntermBinary *constructGLFragDataNode(int index) const;
|
||||
TIntermBinary *constructGLFragDataAssignNode(int index) const;
|
||||
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
|
||||
|
||||
private:
|
||||
TIntermSequence *mMainSequence;
|
||||
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)
|
||||
{
|
||||
if (node->getSymbol() == "gl_FragColor")
|
||||
|
|
@ -77,22 +76,34 @@ void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
|
|||
}
|
||||
}
|
||||
|
||||
bool GLFragColorBroadcastTraverser::visitFunctionDefinition(Visit visit,
|
||||
TIntermFunctionDefinition *node)
|
||||
bool GLFragColorBroadcastTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
{
|
||||
ASSERT(visit == PreVisit);
|
||||
if (node->getFunctionSymbolInfo()->isMain())
|
||||
switch (node->getOp())
|
||||
{
|
||||
TIntermBlock *body = node->getBody();
|
||||
ASSERT(body);
|
||||
mMainSequence = body->getSequence();
|
||||
case EOpFunction:
|
||||
// Function definition.
|
||||
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;
|
||||
}
|
||||
|
||||
void GLFragColorBroadcastTraverser::broadcastGLFragColor()
|
||||
void GLFragColorBroadcastTraverser::broadcastGLFragColor(int maxDrawBuffers)
|
||||
{
|
||||
ASSERT(mMaxDrawBuffers > 1);
|
||||
ASSERT(maxDrawBuffers > 1);
|
||||
if (!mGLFragColorUsed)
|
||||
{
|
||||
return;
|
||||
|
|
@ -102,7 +113,7 @@ void GLFragColorBroadcastTraverser::broadcastGLFragColor()
|
|||
// gl_FragData[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));
|
||||
}
|
||||
|
|
@ -115,12 +126,12 @@ void EmulateGLFragColorBroadcast(TIntermNode *root,
|
|||
std::vector<sh::OutputVariable> *outputVariables)
|
||||
{
|
||||
ASSERT(maxDrawBuffers > 1);
|
||||
GLFragColorBroadcastTraverser traverser(maxDrawBuffers);
|
||||
GLFragColorBroadcastTraverser traverser;
|
||||
root->traverse(&traverser);
|
||||
if (traverser.isGLFragColorUsed())
|
||||
{
|
||||
traverser.updateTree();
|
||||
traverser.broadcastGLFragColor();
|
||||
traverser.broadcastGLFragColor(maxDrawBuffers);
|
||||
for (auto &var : *outputVariables)
|
||||
{
|
||||
if (var.name == "gl_FragColor")
|
||||
|
|
@ -133,5 +144,3 @@ void EmulateGLFragColorBroadcast(TIntermNode *root,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
namespace sh
|
||||
{
|
||||
struct OutputVariable;
|
||||
}
|
||||
|
||||
class TIntermNode;
|
||||
|
||||
// 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.
|
||||
void EmulateGLFragColorBroadcast(TIntermNode *root,
|
||||
int maxDrawBuffers,
|
||||
std::vector<OutputVariable> *outputVariables);
|
||||
}
|
||||
std::vector<sh::OutputVariable> *outputVariables);
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
|
@ -94,7 +91,6 @@ class RoundingHelperWriterHLSL : public RoundingHelperWriter
|
|||
|
||||
RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage)
|
||||
{
|
||||
ASSERT(EmulatePrecision::SupportedInLanguage(outputLanguage));
|
||||
switch (outputLanguage)
|
||||
{
|
||||
case SH_HLSL_4_1_OUTPUT:
|
||||
|
|
@ -102,6 +98,9 @@ RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOut
|
|||
case SH_ESSL_OUTPUT:
|
||||
return new RoundingHelperWriterESSL(outputLanguage);
|
||||
default:
|
||||
// Other languages not yet supported
|
||||
ASSERT(outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
|
||||
IsGLSL130OrNewer(outputLanguage));
|
||||
return new RoundingHelperWriterGLSL(outputLanguage);
|
||||
}
|
||||
}
|
||||
|
|
@ -433,7 +432,7 @@ TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *chil
|
|||
callNode->setOp(EOpFunctionCall);
|
||||
TName nameObj(TFunction::mangleName(name));
|
||||
nameObj.setInternal(true);
|
||||
callNode->getFunctionSymbolInfo()->setNameObj(nameObj);
|
||||
callNode->setNameObj(nameObj);
|
||||
callNode->getSequence()->push_back(child);
|
||||
return callNode;
|
||||
}
|
||||
|
|
@ -470,16 +469,15 @@ bool parentUsesResult(TIntermNode* parent, TIntermNode* node)
|
|||
return false;
|
||||
}
|
||||
|
||||
TIntermBlock *blockParent = parent->getAsBlock();
|
||||
// If the parent is a block, the result is not assigned anywhere,
|
||||
TIntermAggregate *aggParent = parent->getAsAggregate();
|
||||
// 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
|
||||
// unnecessary rounding of unused return values of assignment.
|
||||
if (blockParent)
|
||||
if (aggParent && aggParent->getOp() == EOpSequence)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
TIntermBinary *binaryParent = parent->getAsBinaryNode();
|
||||
if (binaryParent && binaryParent->getOp() == EOpComma && (binaryParent->getRight() != node))
|
||||
if (aggParent && aggParent->getOp() == EOpComma && (aggParent->getSequence()->back() != node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -513,7 +511,7 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
|
|||
if (op == EOpInitialize && visit == InVisit)
|
||||
mDeclaringVariables = false;
|
||||
|
||||
if ((op == EOpIndexDirectStruct) && visit == InVisit)
|
||||
if ((op == EOpIndexDirectStruct || op == EOpVectorSwizzle) && visit == InVisit)
|
||||
visitChildren = false;
|
||||
|
||||
if (visit != PreVisit)
|
||||
|
|
@ -601,30 +599,14 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
|
|||
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 visitChildren = true;
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpSequence:
|
||||
case EOpConstructStruct:
|
||||
case EOpFunction:
|
||||
break;
|
||||
case EOpPrototype:
|
||||
visitChildren = false;
|
||||
|
|
@ -635,6 +617,21 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
|
|||
case EOpInvariantDeclaration:
|
||||
visitChildren = false;
|
||||
break;
|
||||
case EOpDeclaration:
|
||||
// Variable declaration.
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
mDeclaringVariables = true;
|
||||
}
|
||||
else if (visit == InVisit)
|
||||
{
|
||||
mDeclaringVariables = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDeclaringVariables = false;
|
||||
}
|
||||
break;
|
||||
case EOpFunctionCall:
|
||||
{
|
||||
// Function call.
|
||||
|
|
@ -708,19 +705,3 @@ void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase &sink,
|
|||
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
|
||||
// to every translated shader with emulation enabled.
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
class EmulatePrecision : public TLValueTrackingTraverser
|
||||
{
|
||||
public:
|
||||
|
|
@ -30,14 +27,11 @@ class EmulatePrecision : public TLValueTrackingTraverser
|
|||
bool visitBinary(Visit visit, TIntermBinary *node) override;
|
||||
bool visitUnary(Visit visit, TIntermUnary *node) override;
|
||||
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
|
||||
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
|
||||
|
||||
void writeEmulationHelpers(TInfoSinkBase &sink,
|
||||
const int shaderVersion,
|
||||
const ShShaderOutput outputLanguage);
|
||||
|
||||
static bool SupportedInLanguage(const ShShaderOutput outputLanguage);
|
||||
|
||||
private:
|
||||
struct TypePair
|
||||
{
|
||||
|
|
@ -67,6 +61,4 @@ class EmulatePrecision : public TLValueTrackingTraverser
|
|||
bool mDeclaringVariables;
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
|||
TIntermTyped *lhs = sequence->at(0)->getAsTyped();
|
||||
ASSERT(lhs);
|
||||
|
||||
TIntermDeclaration *init = createTempInitDeclaration(lhs);
|
||||
TIntermAggregate *init = createTempInitDeclaration(lhs);
|
||||
TIntermTyped *current = createTempSymbol(lhs->getType());
|
||||
|
||||
insertStatementInParentBlock(init);
|
||||
|
|
@ -124,7 +124,10 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
|||
// Create a chain of n-1 multiples.
|
||||
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());
|
||||
current = mul;
|
||||
}
|
||||
|
|
@ -135,7 +138,9 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
|||
TConstantUnion *oneVal = new TConstantUnion();
|
||||
oneVal->setFConst(1.0f);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@
|
|||
|
||||
#include "compiler/translator/VersionGLSL.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
TExtensionGLSL::TExtensionGLSL(ShShaderOutput output)
|
||||
: TIntermTraverser(true, false, false), mTargetVersion(ShaderOutputTypeToGLSLVersion(output))
|
||||
{
|
||||
|
|
@ -101,5 +98,3 @@ void TExtensionGLSL::checkOperator(TIntermOperator *node)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@
|
|||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
// Traverses the intermediate tree to determine which GLSL extensions are required
|
||||
// to support the shader.
|
||||
class TExtensionGLSL : public TIntermTraverser
|
||||
|
|
@ -39,6 +36,4 @@ class TExtensionGLSL : public TIntermTraverser
|
|||
std::set<std::string> mRequiredExtensions;
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@
|
|||
#include "compiler/translator/ValidateLimitations.h"
|
||||
#include "angle_gl.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node)
|
||||
{
|
||||
if (mUnrollCondition != kSamplerArrayIndex)
|
||||
|
|
@ -54,7 +51,7 @@ bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node)
|
|||
// Check if loop index type is integer.
|
||||
// This is called after ValidateLimitations pass, so the loop has the limited form specified
|
||||
// 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();
|
||||
if (symbol->getBasicType() == EbtInt)
|
||||
node->setUnrollFlag(true);
|
||||
|
|
@ -98,5 +95,3 @@ void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@
|
|||
|
||||
#include "compiler/translator/LoopInfo.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
// This class detects for-loops that needs to be unrolled.
|
||||
// Currently we support two unroll conditions:
|
||||
// 1) kForLoopWithIntegerIndex: unroll if the index type is integer.
|
||||
|
|
@ -53,6 +50,4 @@ class ForLoopUnrollMarker : public TIntermTraverser
|
|||
bool mHasRunLoopValidation;
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@
|
|||
|
||||
#include "compiler/translator/InfoSink.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
void TInfoSinkBase::prefix(TPrefixType p) {
|
||||
switch(p) {
|
||||
case EPrefixNone:
|
||||
|
|
@ -55,5 +52,3 @@ void TInfoSinkBase::message(TPrefixType p, const TSourceLoc& loc, const char* m)
|
|||
sink.append(m);
|
||||
sink.append("\n");
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@
|
|||
#include <stdlib.h>
|
||||
#include "compiler/translator/Common.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
// Returns the fractional part of the given floating-point number.
|
||||
inline float fractionalPart(float f) {
|
||||
float intPart = 0.0f;
|
||||
|
|
@ -116,6 +113,4 @@ public:
|
|||
TInfoSinkBase obj;
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_INFOSINK_H_
|
||||
|
|
|
|||
|
|
@ -16,12 +16,8 @@
|
|||
#include "compiler/translator/IntermNode.h"
|
||||
#include "angle_gl.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
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 *float2 = TCache::getType(EbtFloat, 2);
|
||||
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, 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
|
||||
//
|
||||
|
|
@ -535,13 +511,16 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
|
|||
symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors,
|
||||
EbpMedium);
|
||||
|
||||
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers,
|
||||
EbpMedium);
|
||||
if (resources.EXT_blend_func_extended)
|
||||
if (spec != SH_CSS_SHADERS_SPEC)
|
||||
{
|
||||
symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended",
|
||||
"gl_MaxDualSourceDrawBuffersEXT",
|
||||
resources.MaxDualSourceDrawBuffers);
|
||||
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers,
|
||||
EbpMedium);
|
||||
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",
|
||||
|
|
@ -611,73 +590,85 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
|
|||
switch (type)
|
||||
{
|
||||
case GL_FRAGMENT_SHADER:
|
||||
{
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"),
|
||||
TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"),
|
||||
TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"),
|
||||
TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"),
|
||||
TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"),
|
||||
TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
|
||||
symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"),
|
||||
TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
|
||||
|
||||
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));
|
||||
//
|
||||
// In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available.
|
||||
// Instead, css_MixColor and css_ColorMatrix are available.
|
||||
//
|
||||
if (spec != SH_CSS_SHADERS_SPEC)
|
||||
{
|
||||
symbolTable.insert(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)
|
||||
{
|
||||
symbolTable.insert(
|
||||
ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
|
||||
new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"),
|
||||
TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4)));
|
||||
TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true);
|
||||
secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers);
|
||||
symbolTable.insert(
|
||||
ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
|
||||
new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData));
|
||||
}
|
||||
if (resources.EXT_blend_func_extended)
|
||||
{
|
||||
symbolTable.insert(
|
||||
ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
|
||||
new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"),
|
||||
TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4)));
|
||||
TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true);
|
||||
secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers);
|
||||
symbolTable.insert(
|
||||
ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
|
||||
new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData));
|
||||
}
|
||||
|
||||
if (resources.EXT_frag_depth)
|
||||
{
|
||||
symbolTable.insert(
|
||||
ESSL1_BUILTINS, "GL_EXT_frag_depth",
|
||||
new TVariable(
|
||||
NewPoolTString("gl_FragDepthEXT"),
|
||||
TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
|
||||
EvqFragDepthEXT, 1)));
|
||||
}
|
||||
if (resources.EXT_frag_depth)
|
||||
{
|
||||
symbolTable.insert(
|
||||
ESSL1_BUILTINS, "GL_EXT_frag_depth",
|
||||
new TVariable(
|
||||
NewPoolTString("gl_FragDepthEXT"),
|
||||
TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
|
||||
EvqFragDepthEXT, 1)));
|
||||
}
|
||||
|
||||
symbolTable.insert(ESSL3_BUILTINS,
|
||||
new TVariable(NewPoolTString("gl_FragDepth"),
|
||||
TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
|
||||
symbolTable.insert(ESSL3_BUILTINS,
|
||||
new TVariable(NewPoolTString("gl_FragDepth"),
|
||||
TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
|
||||
|
||||
if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
|
||||
{
|
||||
TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true);
|
||||
lastFragData.setArraySize(resources.MaxDrawBuffers);
|
||||
if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
|
||||
{
|
||||
TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true);
|
||||
lastFragData.setArraySize(resources.MaxDrawBuffers);
|
||||
|
||||
if (resources.EXT_shader_framebuffer_fetch)
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
|
||||
}
|
||||
else if (resources.NV_shader_framebuffer_fetch)
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragColor"),
|
||||
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
|
||||
}
|
||||
}
|
||||
else if (resources.ARM_shader_framebuffer_fetch)
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragColorARM"),
|
||||
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
|
||||
}
|
||||
}
|
||||
if (resources.EXT_shader_framebuffer_fetch)
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
|
||||
}
|
||||
else if (resources.NV_shader_framebuffer_fetch)
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragColor"),
|
||||
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
|
||||
}
|
||||
}
|
||||
else if (resources.ARM_shader_framebuffer_fetch)
|
||||
{
|
||||
symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch",
|
||||
new TVariable(NewPoolTString("gl_LastFragColorARM"),
|
||||
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;
|
||||
|
||||
|
|
@ -758,5 +749,3 @@ void ResetExtensionBehavior(TExtensionBehavior &extBehavior)
|
|||
ext_iter->second = EBhUndefined;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@
|
|||
#include "compiler/translator/Compiler.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &table);
|
||||
|
||||
void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
|
||||
|
|
@ -29,6 +26,4 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
|
|||
// extensions will remain unsupported.
|
||||
void ResetExtensionBehavior(TExtensionBehavior &extensionBehavior);
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_INITIALIZE_H_
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
bool InitProcess()
|
||||
{
|
||||
if (!InitializePoolIndex()) {
|
||||
|
|
@ -39,5 +36,3 @@ void DetachProcess()
|
|||
FreePoolIndex();
|
||||
TCache::destroy();
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -6,11 +6,8 @@
|
|||
#ifndef COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
||||
#define COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
||||
|
||||
namespace sh
|
||||
{
|
||||
bool InitProcess();
|
||||
void DetachProcess();
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_INITIALIZEDLL_H_
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
TLSIndex GlobalParseContextIndex = TLS_INVALID_INDEX;
|
||||
|
||||
bool InitializeParseContextIndex()
|
||||
|
|
@ -43,4 +40,3 @@ TParseContext* GetGlobalParseContext()
|
|||
return static_cast<TParseContext*>(GetTLSValue(GlobalParseContextIndex));
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
|||
|
|
@ -7,15 +7,11 @@
|
|||
#ifndef COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
||||
#define COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
bool InitializeParseContextIndex();
|
||||
void FreeParseContextIndex();
|
||||
|
||||
class TParseContext;
|
||||
extern void SetGlobalParseContext(TParseContext* context);
|
||||
extern TParseContext* GetGlobalParseContext();
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
|
||||
|
|
|
|||
|
|
@ -9,122 +9,191 @@
|
|||
#include "angle_gl.h"
|
||||
#include "common/debug.h"
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
#include "compiler/translator/util.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
VariableInitializer(const InitVariableList &vars, const TSymbolTable &symbolTable)
|
||||
: TIntermTraverser(true, false, false),
|
||||
mVariables(vars),
|
||||
mSymbolTable(symbolTable),
|
||||
mCodeInserted(false)
|
||||
VariableInitializer(const InitVariableList &vars)
|
||||
: TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false)
|
||||
{
|
||||
ASSERT(mSymbolTable.atGlobalLevel());
|
||||
}
|
||||
|
||||
protected:
|
||||
bool visitBinary(Visit, TIntermBinary *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 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:
|
||||
void insertInitCode(TIntermSequence *sequence);
|
||||
|
||||
const InitVariableList &mVariables;
|
||||
const TSymbolTable &mSymbolTable;
|
||||
bool mCodeInserted;
|
||||
};
|
||||
|
||||
// VariableInitializer implementation.
|
||||
|
||||
bool VariableInitializer::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
|
||||
bool VariableInitializer::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
{
|
||||
// Function definition.
|
||||
ASSERT(visit == PreVisit);
|
||||
if (node->getFunctionSymbolInfo()->isMain())
|
||||
bool visitChildren = !mCodeInserted;
|
||||
switch (node->getOp())
|
||||
{
|
||||
TIntermBlock *body = node->getBody();
|
||||
insertInitCode(body->getSequence());
|
||||
mCodeInserted = true;
|
||||
case EOpSequence:
|
||||
break;
|
||||
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)
|
||||
{
|
||||
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());
|
||||
|
||||
if (var.isArray())
|
||||
{
|
||||
// Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which
|
||||
// doesn't have array assignment.
|
||||
TType type = sh::ConvertShaderVariableTypeToTType(var.type);
|
||||
size_t pos = name.find_last_of('[');
|
||||
if (pos != TString::npos)
|
||||
{
|
||||
name = name.substr(0, pos);
|
||||
}
|
||||
TType elementType = sh::GetShaderVariableBasicType(var);
|
||||
TType arrayType = elementType;
|
||||
arrayType.setArraySize(var.elementCount());
|
||||
|
||||
for (unsigned int i = 0; i < var.arraySize; ++i)
|
||||
for (int index = static_cast<int>(var.arraySize) - 1; index >= 0; --index)
|
||||
{
|
||||
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, arrayType);
|
||||
TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol,
|
||||
TIntermTyped::CreateIndexNode(i));
|
||||
TIntermBinary *assign = new TIntermBinary(EOpAssign);
|
||||
sequence->insert(sequence->begin(), assign);
|
||||
|
||||
TIntermTyped *zero = TIntermTyped::CreateZero(elementType);
|
||||
TIntermBinary *assignment = new TIntermBinary(EOpAssign, element, zero);
|
||||
TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
|
||||
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())
|
||||
{
|
||||
TVariable *structInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
|
||||
ASSERT(structInfo);
|
||||
TFieldList *fields = new TFieldList;
|
||||
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());
|
||||
TIntermTyped *zero = TIntermTyped::CreateZero(structInfo->getType());
|
||||
TIntermBinary *indexDirectStruct = new TIntermBinary(EOpIndexDirectStruct);
|
||||
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);
|
||||
sequence->insert(sequence->begin(), assign);
|
||||
const sh::ShaderVariable &field = var.fields[fieldIndex];
|
||||
TType fieldType = sh::ConvertShaderVariableTypeToTType(field.type);
|
||||
TIntermConstantUnion *zeroConst = constructConstUnionNode(fieldType);
|
||||
assign->setRight(zeroConst);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TType type = sh::GetShaderVariableBasicType(var);
|
||||
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
|
||||
TIntermTyped *zero = TIntermTyped::CreateZero(type);
|
||||
|
||||
TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
|
||||
TType type = sh::ConvertShaderVariableTypeToTType(var.type);
|
||||
TIntermBinary *assign = new TIntermBinary(EOpAssign);
|
||||
sequence->insert(sequence->begin(), assign);
|
||||
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
|
||||
assign->setLeft(symbol);
|
||||
TIntermConstantUnion *zeroConst = constructConstUnionNode(type);
|
||||
assign->setRight(zeroConst);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace anonymous
|
||||
|
||||
void InitializeVariables(TIntermNode *root,
|
||||
const InitVariableList &vars,
|
||||
const TSymbolTable &symbolTable)
|
||||
void InitializeVariables(TIntermNode *root, const InitVariableList &vars)
|
||||
{
|
||||
VariableInitializer initializer(vars, symbolTable);
|
||||
VariableInitializer initializer(vars);
|
||||
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