зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1251375. Update to ANGLE/2653
This commit is contained in:
Родитель
157a38bc63
Коммит
745acee9fd
|
@ -118,7 +118,7 @@ ShaderOutput(gl::GLContext* gl)
|
|||
}
|
||||
}
|
||||
|
||||
return SH_GLSL_OUTPUT;
|
||||
return SH_GLSL_COMPATIBILITY_OUTPUT;
|
||||
}
|
||||
|
||||
webgl::ShaderValidator*
|
||||
|
@ -129,7 +129,7 @@ WebGLContext::CreateShaderValidator(GLenum shaderType) const
|
|||
|
||||
ShShaderSpec spec = IsWebGL2() ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC;
|
||||
ShShaderOutput outputLanguage = gl->IsGLES() ? SH_ESSL_OUTPUT
|
||||
: SH_GLSL_OUTPUT;
|
||||
: SH_GLSL_COMPATIBILITY_OUTPUT;
|
||||
|
||||
// If we're using WebGL2 we want a more specific version of GLSL
|
||||
if (IsWebGL2())
|
||||
|
|
|
@ -15,7 +15,7 @@ fail-if = (os == 'android')
|
|||
[webgl-mochitest/ensure-exts/test_EXT_color_buffer_half_float.html]
|
||||
fail-if = (os == 'android')
|
||||
[webgl-mochitest/ensure-exts/test_EXT_disjoint_timer_query.html]
|
||||
fail-if = (os == 'android') || (os == 'mac') || (os == 'win')
|
||||
fail-if = (os == 'android') || (os == 'mac') || (os == 'win' && os_version == '6.1')
|
||||
[webgl-mochitest/ensure-exts/test_EXT_frag_depth.html]
|
||||
fail-if = (os == 'android')
|
||||
[webgl-mochitest/ensure-exts/test_EXT_sRGB.html]
|
||||
|
|
|
@ -15,24 +15,20 @@ angle_git_is_present = exec_script("src/commit_id.py",
|
|||
|
||||
angle_use_commit_id = angle_git_is_present == 1
|
||||
|
||||
gles_gypi = exec_script(
|
||||
"//build/gypi_to_gn.py",
|
||||
[ rebase_path("src/libGLESv2.gypi") ],
|
||||
"scope",
|
||||
[ "src/libGLESv2.gypi" ])
|
||||
gles_gypi = exec_script("//build/gypi_to_gn.py",
|
||||
[ rebase_path("src/libGLESv2.gypi") ],
|
||||
"scope",
|
||||
[ "src/libGLESv2.gypi" ])
|
||||
|
||||
compiler_gypi = exec_script(
|
||||
"//build/gypi_to_gn.py",
|
||||
[ rebase_path("src/compiler.gypi") ],
|
||||
"scope",
|
||||
[ "src/compiler.gypi" ])
|
||||
compiler_gypi = exec_script("//build/gypi_to_gn.py",
|
||||
[ rebase_path("src/compiler.gypi") ],
|
||||
"scope",
|
||||
[ "src/compiler.gypi" ])
|
||||
|
||||
# This config is exported to dependent targets (and also applied to internal
|
||||
# ones).
|
||||
config("external_config") {
|
||||
include_dirs = [
|
||||
"include",
|
||||
]
|
||||
include_dirs = [ "include" ]
|
||||
}
|
||||
|
||||
# This config is applied to internal Angle targets (not pushed to dependents).
|
||||
|
@ -45,8 +41,12 @@ config("internal_config") {
|
|||
|
||||
if (is_win) {
|
||||
copy("copy_compiler_dll") {
|
||||
sources = [ "$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll" ]
|
||||
outputs = [ "$root_build_dir/d3dcompiler_47.dll" ]
|
||||
sources = [
|
||||
"$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll",
|
||||
]
|
||||
outputs = [
|
||||
"$root_out_dir/d3dcompiler_47.dll",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,11 +58,6 @@ component("translator") {
|
|||
|
||||
defines = [ "ANGLE_TRANSLATOR_IMPLEMENTATION" ]
|
||||
|
||||
if (angle_enable_hlsl) {
|
||||
sources += rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_HLSL" ]
|
||||
}
|
||||
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
configs += [
|
||||
":internal_config",
|
||||
|
@ -84,9 +79,9 @@ source_set("includes") {
|
|||
"include/GLES2/gl2ext.h",
|
||||
"include/GLES2/gl2platform.h",
|
||||
"include/GLES3/gl3.h",
|
||||
"include/GLES3/gl3platform.h",
|
||||
"include/GLES3/gl31.h",
|
||||
"include/GLES3/gl32.h",
|
||||
"include/GLES3/gl3platform.h",
|
||||
"include/GLSLANG/ShaderLang.h",
|
||||
"include/KHR/khrplatform.h",
|
||||
]
|
||||
|
@ -106,12 +101,9 @@ config("translator_static_config") {
|
|||
defines = [ "ANGLE_TRANSLATOR_STATIC" ]
|
||||
}
|
||||
|
||||
|
||||
config("debug_annotations_config") {
|
||||
if (is_debug) {
|
||||
defines = [
|
||||
"ANGLE_ENABLE_DEBUG_ANNOTATIONS",
|
||||
]
|
||||
defines = [ "ANGLE_ENABLE_DEBUG_ANNOTATIONS" ]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,10 +120,24 @@ static_library("angle_common") {
|
|||
|
||||
static_library("translator_lib") {
|
||||
sources = rebase_path(compiler_gypi.angle_translator_lib_sources, ".", "src")
|
||||
defines = []
|
||||
|
||||
if (angle_enable_essl) {
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_lib_essl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_ESSL" ]
|
||||
}
|
||||
|
||||
if (angle_enable_glsl) {
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_lib_glsl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_GLSL" ]
|
||||
}
|
||||
|
||||
if (angle_enable_hlsl) {
|
||||
sources += rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src")
|
||||
defines = [ "ANGLE_ENABLE_HLSL" ]
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_HLSL" ]
|
||||
}
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
configs += [
|
||||
|
@ -246,18 +252,13 @@ static_library("libANGLE") {
|
|||
|
||||
include_dirs = []
|
||||
libs = []
|
||||
defines = [
|
||||
"LIBANGLE_IMPLEMENTATION",
|
||||
]
|
||||
defines = [ "LIBANGLE_IMPLEMENTATION" ]
|
||||
|
||||
# Shared D3D sources.
|
||||
if (angle_enable_d3d9 || angle_enable_d3d11) {
|
||||
sources += rebase_path(gles_gypi.libangle_d3d_shared_sources, ".", "src")
|
||||
|
||||
defines += [
|
||||
"ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " +
|
||||
"\"d3dcompiler_47.dll\", \"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }",
|
||||
]
|
||||
defines += [ "ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " + "\"d3dcompiler_47.dll\", \"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }" ]
|
||||
}
|
||||
|
||||
if (angle_enable_d3d9) {
|
||||
|
@ -285,9 +286,7 @@ static_library("libANGLE") {
|
|||
}
|
||||
|
||||
if (is_debug) {
|
||||
defines += [
|
||||
"ANGLE_GENERATE_SHADER_DEBUG_INFO",
|
||||
]
|
||||
defines += [ "ANGLE_GENERATE_SHADER_DEBUG_INFO" ]
|
||||
}
|
||||
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
|
@ -300,10 +299,10 @@ static_library("libANGLE") {
|
|||
]
|
||||
|
||||
deps = [
|
||||
":angle_common",
|
||||
":commit_id",
|
||||
":includes",
|
||||
":translator_static",
|
||||
":angle_common",
|
||||
]
|
||||
|
||||
if (is_win) {
|
||||
|
@ -315,8 +314,8 @@ shared_library("libGLESv2") {
|
|||
sources = rebase_path(gles_gypi.libglesv2_sources, ".", "src")
|
||||
|
||||
if (is_win) {
|
||||
ldflags = [ "/DEF:" +
|
||||
rebase_path("src/libGLESv2/libGLESv2.def", root_build_dir) ]
|
||||
ldflags =
|
||||
[ "/DEF:" + rebase_path("src/libGLESv2/libGLESv2.def", root_build_dir) ]
|
||||
}
|
||||
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
|
@ -328,9 +327,7 @@ shared_library("libGLESv2") {
|
|||
"//build/config/compiler:no_chromium_code",
|
||||
]
|
||||
|
||||
defines = [
|
||||
"LIBGLESV2_IMPLEMENTATION",
|
||||
]
|
||||
defines = [ "LIBGLESV2_IMPLEMENTATION" ]
|
||||
|
||||
deps = [
|
||||
":includes",
|
||||
|
@ -342,8 +339,7 @@ shared_library("libEGL") {
|
|||
sources = rebase_path(gles_gypi.libegl_sources, ".", "src")
|
||||
|
||||
if (is_win) {
|
||||
ldflags = [ "/DEF:" +
|
||||
rebase_path("src/libEGL/libEGL.def", root_build_dir) ]
|
||||
ldflags = [ "/DEF:" + rebase_path("src/libEGL/libEGL.def", root_build_dir) ]
|
||||
}
|
||||
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
|
@ -355,9 +351,7 @@ shared_library("libEGL") {
|
|||
"//build/config/compiler:no_chromium_code",
|
||||
]
|
||||
|
||||
defines = [
|
||||
"LIBEGL_IMPLEMENTATION",
|
||||
]
|
||||
defines = [ "LIBEGL_IMPLEMENTATION" ]
|
||||
|
||||
deps = [
|
||||
":includes",
|
||||
|
@ -365,11 +359,17 @@ shared_library("libEGL") {
|
|||
]
|
||||
}
|
||||
|
||||
util_gypi = exec_script(
|
||||
"//build/gypi_to_gn.py",
|
||||
[ rebase_path("util/util.gyp") ],
|
||||
"scope",
|
||||
[ "util/util.gyp" ])
|
||||
util_gypi = exec_script("//build/gypi_to_gn.py",
|
||||
[ rebase_path("util/util.gyp") ],
|
||||
"scope",
|
||||
[ "util/util.gyp" ])
|
||||
|
||||
config("angle_util_config") {
|
||||
include_dirs = [ "util" ]
|
||||
if (is_linux) {
|
||||
libs = [ "X11" ]
|
||||
}
|
||||
}
|
||||
|
||||
static_library("angle_util") {
|
||||
sources = rebase_path(util_gypi.util_sources, ".", "util")
|
||||
|
@ -396,16 +396,15 @@ static_library("angle_util") {
|
|||
"EGL_EGLEXT_PROTOTYPES",
|
||||
]
|
||||
|
||||
configs += [
|
||||
":internal_config",
|
||||
":debug_annotations_config",
|
||||
]
|
||||
configs += [ ":debug_annotations_config" ]
|
||||
|
||||
include_dirs = [
|
||||
"util",
|
||||
public_configs = [
|
||||
":angle_util_config",
|
||||
":internal_config",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":angle_common",
|
||||
":libEGL",
|
||||
":libGLESv2",
|
||||
]
|
||||
|
|
|
@ -66,6 +66,40 @@ hooks = [
|
|||
'-s', 'buildtools/linux64/clang-format.sha1',
|
||||
],
|
||||
},
|
||||
# Pull GN binaries using checked-in hashes.
|
||||
{
|
||||
'name': 'gn_win',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=win32',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-gn',
|
||||
'-s', 'buildtools/win/gn.exe.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'gn_mac',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=darwin',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-gn',
|
||||
'-s', 'buildtools/mac/gn.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'gn_linux64',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=linux*',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-gn',
|
||||
'-s', 'buildtools/linux64/gn.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
# A change to a .gyp, .gypi, or to GYP itself should run the generator.
|
||||
"pattern": ".",
|
||||
|
|
|
@ -39,5 +39,6 @@ View the [Dev setup instructions](doc/DevSetup.md). For generating a Windows Sto
|
|||
* Read about WebGL on the [Khronos WebGL Wiki](http://khronos.org/webgl/wiki/Main_Page).
|
||||
* Learn about implementation details in the [OpenGL Insights chapter on ANGLE](http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-ANGLE.pdf) and this [ANGLE presentation](https://drive.google.com/file/d/0Bw29oYeC09QbbHoxNE5EUFh0RGs/view?usp=sharing).
|
||||
* Learn about the past, present, and future of the ANGLE implementation in [this recent presentation](https://docs.google.com/presentation/d/1CucIsdGVDmdTWRUbg68IxLE5jXwCb2y1E9YVhQo0thg/pub?start=false&loop=false).
|
||||
* Notes on [debugging ANGLE](doc/DebuggingTips.md).
|
||||
* If you use ANGLE in your own project, we'd love to hear about it!
|
||||
|
||||
|
|
|
@ -468,6 +468,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
|
|||
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
|
||||
#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
|
||||
|
||||
#ifndef EGL_ANGLE_direct_composition
|
||||
#define EGL_ANGLE_direct_composition 1
|
||||
#define EGL_DIRECT_COMPOSITION_ANGLE 0x33A5
|
||||
#endif /* EGL_ANGLE_direct_composition */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle
|
||||
#define EGL_ANGLE_platform_angle 1
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||
|
@ -504,6 +509,26 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
|
|||
#define EGL_X11_VISUAL_ID_ANGLE 0x33A3
|
||||
#endif /* EGL_ANGLE_x11_visual */
|
||||
|
||||
#ifndef EGL_ANGLE_flexible_surface_compatibility
|
||||
#define EGL_ANGLE_flexible_surface_compatibility 1
|
||||
#define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6
|
||||
#endif /* EGL_ANGLE_flexible_surface_compatibility */
|
||||
|
||||
#ifndef EGL_ANGLE_surface_orientation
|
||||
#define EGL_ANGLE_surface_orientation
|
||||
#define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7
|
||||
#define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8
|
||||
#define EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001
|
||||
#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002
|
||||
#endif /* EGL_ANGLE_surface_orientation */
|
||||
|
||||
#ifndef EGL_ANGLE_experimental_present_path
|
||||
#define EGL_ANGLE_experimental_present_path
|
||||
#define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4
|
||||
#define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9
|
||||
#define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA
|
||||
#endif /* EGL_ANGLE_experimental_present_path */
|
||||
|
||||
#ifndef EGL_ARM_pixmap_multisample_discard
|
||||
#define EGL_ARM_pixmap_multisample_discard 1
|
||||
#define EGL_DISCARD_SAMPLES_ARM 0x3286
|
||||
|
|
|
@ -2920,6 +2920,21 @@ GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
|
|||
#define GL_SHADER_BINARY_VIV 0x8FC4
|
||||
#endif /* GL_VIV_shader_binary */
|
||||
|
||||
#ifndef GL_ANGLE_lossy_etc_decode
|
||||
#define GL_ANGLE_lossy_etc_decode 1
|
||||
#define GL_ETC1_RGB8_LOSSY_DECODE_ANGLE 0x9690
|
||||
#define GL_COMPRESSED_R11_LOSSY_DECODE_EAC_ANGLE 0x9691
|
||||
#define GL_COMPRESSED_SIGNED_R11_LOSSY_DECODE_EAC_ANGLE 0x9692
|
||||
#define GL_COMPRESSED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9693
|
||||
#define GL_COMPRESSED_SIGNED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9694
|
||||
#define GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE 0x9695
|
||||
#define GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE 0x9696
|
||||
#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9697
|
||||
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9698
|
||||
#define GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x9699
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x969A
|
||||
#endif /* GL_ANGLE_lossy_etc_decode */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -48,7 +48,7 @@ typedef unsigned int GLenum;
|
|||
|
||||
// Version number for shader translation API.
|
||||
// It is incremented every time the API changes.
|
||||
#define ANGLE_SH_VERSION 140
|
||||
#define ANGLE_SH_VERSION 143
|
||||
|
||||
typedef enum {
|
||||
SH_GLES2_SPEC = 0x8B40,
|
||||
|
@ -80,30 +80,35 @@ typedef enum {
|
|||
SH_CSS_SHADERS_SPEC = 0x8B42
|
||||
} ShShaderSpec;
|
||||
|
||||
typedef enum {
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
// SH_GLSL_OUTPUT is deprecated. This is to not break the build.
|
||||
SH_GLSL_OUTPUT = 0x8B46,
|
||||
SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46,
|
||||
// SH_GLSL_CORE_OUTPUT is deprecated.
|
||||
SH_GLSL_CORE_OUTPUT = 0x8B47,
|
||||
//Note: GL introduced core profiles in 1.5. However, for compatiblity with Chromium, we treat SH_GLSL_CORE_OUTPUT as GLSL_130_OUTPUT.
|
||||
//TODO: Remove SH_GLSL_CORE_OUTPUT
|
||||
SH_GLSL_130_OUTPUT = 0x8B47,
|
||||
SH_GLSL_140_OUTPUT = 0x8B80,
|
||||
SH_GLSL_150_CORE_OUTPUT = 0x8B81,
|
||||
SH_GLSL_330_CORE_OUTPUT = 0x8B82,
|
||||
SH_GLSL_400_CORE_OUTPUT = 0x8B83,
|
||||
SH_GLSL_410_CORE_OUTPUT = 0x8B84,
|
||||
SH_GLSL_420_CORE_OUTPUT = 0x8B85,
|
||||
SH_GLSL_430_CORE_OUTPUT = 0x8B86,
|
||||
SH_GLSL_440_CORE_OUTPUT = 0x8B87,
|
||||
SH_GLSL_450_CORE_OUTPUT = 0x8B88,
|
||||
typedef enum
|
||||
{
|
||||
// ESSL output only supported in some configurations.
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
|
||||
// HLSL output only supported in some configurations.
|
||||
SH_HLSL_OUTPUT = 0x8B48,
|
||||
SH_HLSL9_OUTPUT = 0x8B48,
|
||||
SH_HLSL11_OUTPUT = 0x8B49
|
||||
// GLSL output only supported in some configurations.
|
||||
SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46,
|
||||
// Note: GL introduced core profiles in 1.5.
|
||||
SH_GLSL_130_OUTPUT = 0x8B47,
|
||||
SH_GLSL_140_OUTPUT = 0x8B80,
|
||||
SH_GLSL_150_CORE_OUTPUT = 0x8B81,
|
||||
SH_GLSL_330_CORE_OUTPUT = 0x8B82,
|
||||
SH_GLSL_400_CORE_OUTPUT = 0x8B83,
|
||||
SH_GLSL_410_CORE_OUTPUT = 0x8B84,
|
||||
SH_GLSL_420_CORE_OUTPUT = 0x8B85,
|
||||
SH_GLSL_430_CORE_OUTPUT = 0x8B86,
|
||||
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.
|
||||
|
@ -334,9 +339,9 @@ COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle ha
|
|||
// 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 - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
|
||||
// SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT. Note: HLSL output is only
|
||||
// supported in some configurations.
|
||||
// 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.
|
||||
COMPILER_EXPORT ShHandle ShConstructCompiler(
|
||||
sh::GLenum type,
|
||||
|
|
|
@ -200,6 +200,9 @@ struct COMPILER_EXPORT InterfaceBlock
|
|||
InterfaceBlock(const InterfaceBlock &other);
|
||||
InterfaceBlock &operator=(const InterfaceBlock &other);
|
||||
|
||||
// Fields from blocks with non-empty instance names are prefixed with the block name.
|
||||
std::string fieldPrefix() const;
|
||||
|
||||
std::string name;
|
||||
std::string mappedName;
|
||||
std::string instanceName;
|
||||
|
@ -210,6 +213,6 @@ struct COMPILER_EXPORT InterfaceBlock
|
|||
std::vector<InterfaceBlockField> fields;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace sh
|
||||
|
||||
#endif // GLSLANG_SHADERVARS_H_
|
||||
|
|
|
@ -108,7 +108,8 @@ SOURCES += [
|
|||
'src/compiler/translator/glslang_tab.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['GNU_CXX'] or CONFIG['CLANG_CL']:
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += [
|
||||
'-Wno-attributes',
|
||||
'-Wno-shadow',
|
||||
|
@ -116,16 +117,16 @@ if CONFIG['GNU_CXX'] or CONFIG['CLANG_CL']:
|
|||
'-Wno-unknown-pragmas',
|
||||
'-Wno-unreachable-code',
|
||||
]
|
||||
if CONFIG['GNU_CXX'] and not CONFIG['CLANG_CXX'] and not CONFIG['CLANG_CL']:
|
||||
CXXFLAGS += [
|
||||
'-Wno-shadow-compatible-local',
|
||||
'-Wno-shadow-local',
|
||||
]
|
||||
if CONFIG['CLANG_CXX'] or CONFIG['CLANG_CL']:
|
||||
CXXFLAGS += [
|
||||
'-Wno-inconsistent-missing-override',
|
||||
'-Wno-unused-private-field',
|
||||
]
|
||||
if CONFIG['CLANG_CXX']:
|
||||
CXXFLAGS += [
|
||||
'-Wno-inconsistent-missing-override',
|
||||
'-Wno-unused-private-field',
|
||||
]
|
||||
else:
|
||||
CXXFLAGS += [
|
||||
'-Wno-shadow-compatible-local',
|
||||
'-Wno-shadow-local',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_DIRECTX_SDK_PATH'] and not CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
|
||||
LOCAL_INCLUDES += ['%' + '%s/include/' % CONFIG['MOZ_DIRECTX_SDK_PATH']]
|
||||
|
@ -154,6 +155,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
DIRS += [ 'src/libANGLE', 'src/libGLESv2', 'src/libEGL' ]
|
||||
|
||||
DEFINES['ANGLE_ENABLE_HLSL'] = "1"
|
||||
DEFINES['ANGLE_ENABLE_GLSL'] = "1"
|
||||
DEFINES['ANGLE_ENABLE_ESSL'] = "1"
|
||||
DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
|
||||
|
||||
EXPORTS.angle += [ 'include/GLSLANG/ShaderLang.h', 'include/GLSLANG/ShaderVars.h' ]
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
'angle_enable_d3d9%': 0,
|
||||
'angle_enable_d3d11%': 0,
|
||||
'angle_enable_gl%': 0,
|
||||
'angle_enable_essl%': 1, # Enable this for all configs by default
|
||||
'angle_enable_glsl%': 1, # Enable this for all configs by default
|
||||
'angle_enable_hlsl%': 0,
|
||||
'angle_link_glx%': 0,
|
||||
'angle_gl_library_type%': 'shared_library',
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#define ANGLE_COMMIT_HASH "d00f803db3a2"
|
||||
#define ANGLE_COMMIT_HASH "f1101625dbbe"
|
||||
#define ANGLE_COMMIT_HASH_SIZE 12
|
||||
#define ANGLE_COMMIT_DATE "2015-12-15 23:09:49 -0500"
|
||||
#define ANGLE_COMMIT_DATE "2016-02-24 21:04:03 -0500"
|
||||
|
|
|
@ -55,7 +55,7 @@ TEST_F(BitSetIteratorTest, EmptySet)
|
|||
for (unsigned long bit : IterateBitSet(mStateBits))
|
||||
{
|
||||
sawBit = true;
|
||||
UNUSED_TRACE_VARIABLE(bit);
|
||||
UNUSED_VARIABLE(bit);
|
||||
}
|
||||
EXPECT_FALSE(sawBit);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,13 @@ struct Optional
|
|||
return *this;
|
||||
}
|
||||
|
||||
Optional &operator=(T &&value)
|
||||
{
|
||||
mValue = std::move(value);
|
||||
mValid = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
mValid = false;
|
||||
|
|
|
@ -8,8 +8,15 @@
|
|||
#include "common/debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
namespace angle
|
||||
{
|
||||
const uintptr_t DirtyPointer = std::numeric_limits<uintptr_t>::max();
|
||||
}
|
||||
|
||||
size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
|
||||
{
|
||||
// Attempt to just print to the current buffer
|
||||
|
|
|
@ -33,6 +33,7 @@ class NonCopyable
|
|||
void operator=(const NonCopyable&) = delete;
|
||||
};
|
||||
|
||||
extern const uintptr_t DirtyPointer;
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
|
|
|
@ -53,7 +53,7 @@ void output(bool traceInDebugOnly, MessageType messageType, DebugTraceOutputType
|
|||
}
|
||||
|
||||
std::string formattedMessage;
|
||||
UNUSED_TRACE_VARIABLE(formattedMessage);
|
||||
UNUSED_VARIABLE(formattedMessage);
|
||||
|
||||
#if !defined(NDEBUG) && defined(_MSC_VER)
|
||||
if (messageType == MESSAGE_ERR)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "common/angleutils.h"
|
||||
|
||||
#if !defined(TRACE_OUTPUT_FILE)
|
||||
#define TRACE_OUTPUT_FILE "debug.txt"
|
||||
#define TRACE_OUTPUT_FILE "angle_debug.txt"
|
||||
#endif
|
||||
|
||||
namespace gl
|
||||
|
@ -91,7 +91,7 @@ bool DebugAnnotationsActive();
|
|||
#if defined(_MSC_VER)
|
||||
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
|
||||
#else
|
||||
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper(message "\n", ##__VA_ARGS__);
|
||||
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper("%s" message "\n", __FUNCTION__, ##__VA_ARGS__);
|
||||
#endif // _MSC_VER
|
||||
#else
|
||||
#define EVENT(message, ...) (void(0))
|
||||
|
@ -114,11 +114,7 @@ bool DebugAnnotationsActive();
|
|||
#define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
|
||||
#endif
|
||||
|
||||
#ifndef ANGLE_ENABLE_DEBUG_TRACE
|
||||
#define UNUSED_TRACE_VARIABLE(variable) ((void)variable)
|
||||
#else
|
||||
#define UNUSED_TRACE_VARIABLE(variable)
|
||||
#endif
|
||||
#define UNUSED_VARIABLE(variable) ((void)variable)
|
||||
|
||||
// A macro to indicate unimplemented functionality
|
||||
|
||||
|
|
|
@ -493,9 +493,10 @@ inline unsigned int average(unsigned int a, unsigned int b)
|
|||
return ((a ^ b) >> 1) + (a & b);
|
||||
}
|
||||
|
||||
inline signed int average(signed int a, signed int b)
|
||||
inline int average(int a, int b)
|
||||
{
|
||||
return ((long long)a + (long long)b) / 2;
|
||||
long long average = (static_cast<long long>(a) + static_cast<long long>(b)) / 2ll;
|
||||
return static_cast<int>(average);
|
||||
}
|
||||
|
||||
inline float average(float a, float b)
|
||||
|
@ -584,9 +585,10 @@ struct IndexRange
|
|||
// packSnorm2x16 : round(clamp(c, -1, +1) * 32767.0)
|
||||
inline uint32_t packSnorm2x16(float f1, float f2)
|
||||
{
|
||||
uint16_t leastSignificantBits = static_cast<uint16_t>(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f));
|
||||
uint16_t mostSignificantBits = static_cast<uint16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f));
|
||||
return static_cast<uint32_t>(mostSignificantBits) << 16 | static_cast<uint32_t>(leastSignificantBits);
|
||||
int16_t leastSignificantBits = static_cast<int16_t>(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f));
|
||||
int16_t mostSignificantBits = static_cast<int16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f));
|
||||
return static_cast<uint32_t>(mostSignificantBits) << 16 |
|
||||
(static_cast<uint32_t>(leastSignificantBits) & 0xFFFF);
|
||||
}
|
||||
|
||||
// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, each
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
'compiler/translator/BaseTypes.h',
|
||||
'compiler/translator/BuiltInFunctionEmulator.cpp',
|
||||
'compiler/translator/BuiltInFunctionEmulator.h',
|
||||
'compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
|
||||
'compiler/translator/BuiltInFunctionEmulatorGLSL.h',
|
||||
'compiler/translator/Cache.cpp',
|
||||
'compiler/translator/Cache.h',
|
||||
'compiler/translator/CallDAG.cpp',
|
||||
|
@ -43,8 +41,6 @@
|
|||
'compiler/translator/EmulatePrecision.cpp',
|
||||
'compiler/translator/EmulatePrecision.h',
|
||||
'compiler/translator/ExtensionBehavior.h',
|
||||
'compiler/translator/ExtensionGLSL.cpp',
|
||||
'compiler/translator/ExtensionGLSL.h',
|
||||
'compiler/translator/FlagStd140Structs.cpp',
|
||||
'compiler/translator/FlagStd140Structs.h',
|
||||
'compiler/translator/ForLoopUnroll.cpp',
|
||||
|
@ -72,12 +68,6 @@
|
|||
'compiler/translator/NodeSearch.h',
|
||||
'compiler/translator/Operator.cpp',
|
||||
'compiler/translator/Operator.h',
|
||||
'compiler/translator/OutputESSL.cpp',
|
||||
'compiler/translator/OutputESSL.h',
|
||||
'compiler/translator/OutputGLSL.cpp',
|
||||
'compiler/translator/OutputGLSL.h',
|
||||
'compiler/translator/OutputGLSLBase.cpp',
|
||||
'compiler/translator/OutputGLSLBase.h',
|
||||
'compiler/translator/ParseContext.cpp',
|
||||
'compiler/translator/ParseContext.h',
|
||||
'compiler/translator/PoolAlloc.cpp',
|
||||
|
@ -100,10 +90,6 @@
|
|||
'compiler/translator/SearchSymbol.h',
|
||||
'compiler/translator/SymbolTable.cpp',
|
||||
'compiler/translator/SymbolTable.h',
|
||||
'compiler/translator/TranslatorESSL.cpp',
|
||||
'compiler/translator/TranslatorESSL.h',
|
||||
'compiler/translator/TranslatorGLSL.cpp',
|
||||
'compiler/translator/TranslatorGLSL.h',
|
||||
'compiler/translator/Types.cpp',
|
||||
'compiler/translator/Types.h',
|
||||
'compiler/translator/UnfoldShortCircuitAST.cpp',
|
||||
|
@ -120,8 +106,6 @@
|
|||
'compiler/translator/VariableInfo.h',
|
||||
'compiler/translator/VariablePacker.cpp',
|
||||
'compiler/translator/VariablePacker.h',
|
||||
'compiler/translator/VersionGLSL.cpp',
|
||||
'compiler/translator/VersionGLSL.h',
|
||||
'compiler/translator/blocklayout.cpp',
|
||||
'compiler/translator/blocklayout.h',
|
||||
'compiler/translator/depgraph/DependencyGraph.cpp',
|
||||
|
@ -148,6 +132,28 @@
|
|||
'third_party/compiler/ArrayBoundsClamper.cpp',
|
||||
'third_party/compiler/ArrayBoundsClamper.h',
|
||||
],
|
||||
'angle_translator_lib_essl_sources':
|
||||
[
|
||||
'compiler/translator/OutputESSL.cpp',
|
||||
'compiler/translator/OutputESSL.h',
|
||||
'compiler/translator/TranslatorESSL.cpp',
|
||||
'compiler/translator/TranslatorESSL.h',
|
||||
],
|
||||
'angle_translator_lib_glsl_sources':
|
||||
[
|
||||
'compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
|
||||
'compiler/translator/BuiltInFunctionEmulatorGLSL.h',
|
||||
'compiler/translator/ExtensionGLSL.cpp',
|
||||
'compiler/translator/ExtensionGLSL.h',
|
||||
'compiler/translator/OutputGLSL.cpp',
|
||||
'compiler/translator/OutputGLSL.h',
|
||||
'compiler/translator/OutputGLSLBase.cpp',
|
||||
'compiler/translator/OutputGLSLBase.h',
|
||||
'compiler/translator/TranslatorGLSL.cpp',
|
||||
'compiler/translator/TranslatorGLSL.h',
|
||||
'compiler/translator/VersionGLSL.cpp',
|
||||
'compiler/translator/VersionGLSL.h',
|
||||
],
|
||||
'angle_translator_lib_hlsl_sources':
|
||||
[
|
||||
'compiler/translator/ArrayReturnValueToOutParameter.cpp',
|
||||
|
@ -253,6 +259,42 @@
|
|||
},
|
||||
'conditions':
|
||||
[
|
||||
['angle_enable_essl==1',
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_ESSL',
|
||||
],
|
||||
'direct_dependent_settings':
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_ESSL',
|
||||
],
|
||||
},
|
||||
'sources':
|
||||
[
|
||||
'<@(angle_translator_lib_essl_sources)',
|
||||
],
|
||||
}],
|
||||
['angle_enable_glsl==1',
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_GLSL',
|
||||
],
|
||||
'direct_dependent_settings':
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_GLSL',
|
||||
],
|
||||
},
|
||||
'sources':
|
||||
[
|
||||
'<@(angle_translator_lib_glsl_sources)',
|
||||
],
|
||||
}],
|
||||
['angle_enable_hlsl==1',
|
||||
{
|
||||
'defines':
|
||||
|
|
|
@ -35,6 +35,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
|||
InitResult result = assignIndicesInternal(&it.second);
|
||||
if (result != INITDAG_SUCCESS)
|
||||
{
|
||||
*mCreationInfo << "\n";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +108,8 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
|||
if (visit == PreVisit)
|
||||
{
|
||||
// Function declaration, create an empty record.
|
||||
mFunctions[node->getName()];
|
||||
auto& record = mFunctions[node->getName()];
|
||||
record.name = node->getName();
|
||||
}
|
||||
break;
|
||||
case EOpFunction:
|
||||
|
@ -169,7 +171,8 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
|||
|
||||
if (!function->node)
|
||||
{
|
||||
*mCreationInfo << "Undefined function: " << function->name;
|
||||
*mCreationInfo << "Undefined function '" << function->name
|
||||
<< ")' used in the following call chain:";
|
||||
return INITDAG_UNDEFINED;
|
||||
}
|
||||
|
||||
|
@ -182,7 +185,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
|||
{
|
||||
if (mCreationInfo)
|
||||
{
|
||||
*mCreationInfo << "Recursive function call in the following call chain: " << function->name;
|
||||
*mCreationInfo << "Recursive function call in the following call chain:" << function->name;
|
||||
}
|
||||
return INITDAG_RECURSION;
|
||||
}
|
||||
|
@ -191,19 +194,15 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
|
|||
for (auto &callee : function->callees)
|
||||
{
|
||||
InitResult result = assignIndicesInternal(callee);
|
||||
if (result == INITDAG_RECURSION)
|
||||
if (result != INITDAG_SUCCESS)
|
||||
{
|
||||
// We know that there is a recursive function call chain in the AST,
|
||||
// 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)
|
||||
{
|
||||
*mCreationInfo << " <- " << function->name;
|
||||
*mCreationInfo << " <- " << function->name << ")";
|
||||
}
|
||||
return INITDAG_RECURSION;
|
||||
}
|
||||
else if (result == INITDAG_UNDEFINED)
|
||||
{
|
||||
return INITDAG_UNDEFINED;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,14 @@
|
|||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifdef ANGLE_ENABLE_ESSL
|
||||
#include "compiler/translator/TranslatorESSL.h"
|
||||
#endif
|
||||
|
||||
#ifdef ANGLE_ENABLE_GLSL
|
||||
#include "compiler/translator/TranslatorGLSL.h"
|
||||
#endif
|
||||
|
||||
#ifdef ANGLE_ENABLE_HLSL
|
||||
#include "compiler/translator/TranslatorHLSL.h"
|
||||
#endif // ANGLE_ENABLE_HLSL
|
||||
|
@ -20,7 +26,13 @@ TCompiler* ConstructCompiler(
|
|||
{
|
||||
switch (output) {
|
||||
case SH_ESSL_OUTPUT:
|
||||
#ifdef ANGLE_ENABLE_ESSL
|
||||
return new TranslatorESSL(type, spec);
|
||||
#else
|
||||
// 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:
|
||||
|
@ -32,19 +44,26 @@ TCompiler* ConstructCompiler(
|
|||
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);
|
||||
case SH_HLSL9_OUTPUT:
|
||||
case SH_HLSL11_OUTPUT:
|
||||
#else
|
||||
// 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);
|
||||
#else
|
||||
// This compiler is not supported in this
|
||||
// configuration. Return NULL per the ShConstructCompiler API.
|
||||
return NULL;
|
||||
return nullptr;
|
||||
#endif // ANGLE_ENABLE_HLSL
|
||||
default:
|
||||
// Unknown format. Return NULL per the ShConstructCompiler API.
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,18 +60,21 @@ inline TString* NewPoolTString(const char* s)
|
|||
//
|
||||
// Pool allocator versions of vectors, lists, and maps
|
||||
//
|
||||
template <class T> class TVector : public std::vector<T, pool_allocator<T> > {
|
||||
public:
|
||||
typedef typename std::vector<T, pool_allocator<T> >::size_type size_type;
|
||||
TVector() : std::vector<T, pool_allocator<T> >() {}
|
||||
TVector(const pool_allocator<T>& a) : std::vector<T, pool_allocator<T> >(a) {}
|
||||
TVector(size_type i): std::vector<T, pool_allocator<T> >(i) {}
|
||||
template <class T>
|
||||
class TVector : public std::vector<T, pool_allocator<T>>
|
||||
{
|
||||
public:
|
||||
typedef typename std::vector<T, pool_allocator<T>>::size_type size_type;
|
||||
TVector() : std::vector<T, pool_allocator<T>>() {}
|
||||
TVector(const pool_allocator<T> &a) : std::vector<T, pool_allocator<T>>(a) {}
|
||||
TVector(size_type i) : std::vector<T, pool_allocator<T>>(i) {}
|
||||
};
|
||||
|
||||
template <class K, class D, class CMP = std::less<K> >
|
||||
class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<const K, D> > > {
|
||||
public:
|
||||
typedef pool_allocator<std::pair<const K, D> > tAllocator;
|
||||
template <class K, class D, class CMP = std::less<K>>
|
||||
class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<const K, D>>>
|
||||
{
|
||||
public:
|
||||
typedef pool_allocator<std::pair<const K, D>> tAllocator;
|
||||
|
||||
TMap() : std::map<K, D, CMP, tAllocator>() {}
|
||||
// use correct two-stage name lookup supported in gcc 3.4 and above
|
||||
|
|
|
@ -322,7 +322,10 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
|||
if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
|
||||
arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
|
||||
|
||||
if (success && shaderType == GL_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION))
|
||||
// gl_Position is always written in compatibility output mode
|
||||
if (success && shaderType == GL_VERTEX_SHADER &&
|
||||
((compileOptions & SH_INIT_GL_POSITION) ||
|
||||
(outputType == SH_GLSL_COMPATIBILITY_OUTPUT)))
|
||||
initializeGLPosition(root);
|
||||
|
||||
// This pass might emit short circuits so keep it before the short circuit unfolding
|
||||
|
@ -607,7 +610,7 @@ bool TCompiler::tagUsedFunctions()
|
|||
}
|
||||
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "Missing main()";
|
||||
infoSink.info << "Missing main()\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -744,17 +747,6 @@ bool TCompiler::limitExpressionComplexity(TIntermNode* root)
|
|||
return false;
|
||||
}
|
||||
|
||||
TDependencyGraph graph(root);
|
||||
|
||||
for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
|
||||
iter != graph.endUserDefinedFunctionCalls();
|
||||
++iter)
|
||||
{
|
||||
TGraphFunctionCall* samplerSymbol = *iter;
|
||||
TDependencyGraphTraverser graphTraverser;
|
||||
samplerSymbol->traverse(&graphTraverser);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
#include "angle_gl.h"
|
||||
#include "common/debug.h"
|
||||
#include "compiler/translator/Diagnostics.h"
|
||||
|
||||
|
@ -25,13 +26,15 @@ static TBehavior getBehavior(const std::string& str)
|
|||
return EBhUndefined;
|
||||
}
|
||||
|
||||
TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
|
||||
TDiagnostics& diagnostics,
|
||||
int& shaderVersion,
|
||||
TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
|
||||
TDiagnostics &diagnostics,
|
||||
int &shaderVersion,
|
||||
sh::GLenum shaderType,
|
||||
bool debugShaderPrecisionSupported)
|
||||
: mExtensionBehavior(extBehavior),
|
||||
mDiagnostics(diagnostics),
|
||||
mShaderVersion(shaderVersion),
|
||||
mShaderType(shaderType),
|
||||
mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
|
||||
{
|
||||
}
|
||||
|
@ -57,7 +60,16 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
|
|||
const char kAll[] = "all";
|
||||
|
||||
if (name == kInvariant && value == kAll)
|
||||
{
|
||||
if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
// ESSL 3.00.4 section 4.6.1
|
||||
mDiagnostics.writeInfo(
|
||||
pp::Diagnostics::PP_ERROR, loc,
|
||||
"#pragma STDGL invariant(all) can not be used in fragment shader", name, value);
|
||||
}
|
||||
mPragma.stdgl.invariantAll = true;
|
||||
}
|
||||
// The STDGL pragma is used to reserve pragmas for use by future
|
||||
// revisions of GLSL. Do not generate an error on unexpected
|
||||
// name and value.
|
||||
|
|
|
@ -11,15 +11,17 @@
|
|||
#include "compiler/translator/ExtensionBehavior.h"
|
||||
#include "compiler/translator/Pragma.h"
|
||||
#include "compiler/preprocessor/DirectiveHandlerBase.h"
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
|
||||
class TDiagnostics;
|
||||
|
||||
class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
TDirectiveHandler(TExtensionBehavior& extBehavior,
|
||||
TDiagnostics& diagnostics,
|
||||
int& shaderVersion,
|
||||
TDirectiveHandler(TExtensionBehavior &extBehavior,
|
||||
TDiagnostics &diagnostics,
|
||||
int &shaderVersion,
|
||||
sh::GLenum shaderType,
|
||||
bool debugShaderPrecisionSupported);
|
||||
~TDirectiveHandler() override;
|
||||
|
||||
|
@ -44,6 +46,7 @@ class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
|
|||
TExtensionBehavior& mExtensionBehavior;
|
||||
TDiagnostics& mDiagnostics;
|
||||
int& mShaderVersion;
|
||||
sh::GLenum mShaderType;
|
||||
bool mDebugShaderPrecisionSupported;
|
||||
};
|
||||
|
||||
|
|
|
@ -83,19 +83,9 @@ TString OutputHLSL::TextureFunction::name() const
|
|||
{
|
||||
TString name = "gl_texture";
|
||||
|
||||
if (IsSampler2D(sampler))
|
||||
{
|
||||
name += "2D";
|
||||
}
|
||||
else if (IsSampler3D(sampler))
|
||||
{
|
||||
name += "3D";
|
||||
}
|
||||
else if (IsSamplerCube(sampler))
|
||||
{
|
||||
name += "Cube";
|
||||
}
|
||||
else UNREACHABLE();
|
||||
// We need to include full the sampler type in the function name to make the signature unique
|
||||
// on D3D11, where samplers are passed to texture functions as indices.
|
||||
name += TextureTypeSuffix(this->sampler);
|
||||
|
||||
if (proj)
|
||||
{
|
||||
|
@ -185,7 +175,7 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, int shaderVersion,
|
|||
mStructureHLSL = new StructureHLSL;
|
||||
mUniformHLSL = new UniformHLSL(mStructureHLSL, outputType, uniforms);
|
||||
|
||||
if (mOutputType == SH_HLSL9_OUTPUT)
|
||||
if (mOutputType == SH_HLSL_3_0_OUTPUT)
|
||||
{
|
||||
// Fragment shaders need dx_DepthRange, dx_ViewCoords and dx_DepthFront.
|
||||
// Vertex shaders need a slightly different set: dx_DepthRange, dx_ViewCoords and dx_ViewAdjust.
|
||||
|
@ -372,7 +362,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
|
||||
out << mStructureHLSL->structsHeader();
|
||||
|
||||
out << mUniformHLSL->uniformsHeader(mOutputType, mReferencedUniforms);
|
||||
mUniformHLSL->uniformsHeader(out, mOutputType, mReferencedUniforms);
|
||||
out << mUniformHLSL->interfaceBlocksHeader(mReferencedInterfaceBlocks);
|
||||
|
||||
if (!mEqualityFunctions.empty())
|
||||
|
@ -495,7 +485,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
"\n";
|
||||
}
|
||||
|
||||
if (mOutputType == SH_HLSL11_OUTPUT)
|
||||
if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
|
||||
{
|
||||
out << "cbuffer DriverConstants : register(b1)\n"
|
||||
"{\n";
|
||||
|
@ -515,6 +505,13 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
out << " float3 dx_DepthFront : packoffset(c2);\n";
|
||||
}
|
||||
|
||||
if (mUsesFragCoord)
|
||||
{
|
||||
// dx_ViewScale is only used in the fragment shader to correct
|
||||
// the value for glFragCoord if necessary
|
||||
out << " float2 dx_ViewScale : packoffset(c3);\n";
|
||||
}
|
||||
|
||||
out << "};\n";
|
||||
}
|
||||
else
|
||||
|
@ -599,7 +596,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
"\n";
|
||||
}
|
||||
|
||||
if (mOutputType == SH_HLSL11_OUTPUT)
|
||||
if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
|
||||
{
|
||||
out << "cbuffer DriverConstants : register(b1)\n"
|
||||
"{\n";
|
||||
|
@ -609,11 +606,13 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
out << " float3 dx_DepthRange : packoffset(c0);\n";
|
||||
}
|
||||
|
||||
// dx_ViewAdjust and dx_ViewCoords will only be used in Feature Level 9 shaders.
|
||||
// However, we declare it for all shaders (including Feature Level 10+).
|
||||
// The bytecode is the same whether we declare it or not, since D3DCompiler removes it if it's unused.
|
||||
// dx_ViewAdjust and dx_ViewCoords will only be used in Feature Level 9
|
||||
// shaders. However, we declare it for all shaders (including Feature Level 10+).
|
||||
// The bytecode is the same whether we declare it or not, since D3DCompiler removes it
|
||||
// if it's unused.
|
||||
out << " float4 dx_ViewAdjust : packoffset(c1);\n";
|
||||
out << " float2 dx_ViewCoords : packoffset(c2);\n";
|
||||
out << " float2 dx_ViewScale : packoffset(c3);\n";
|
||||
|
||||
out << "};\n"
|
||||
"\n";
|
||||
|
@ -699,7 +698,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
// Argument list
|
||||
int hlslCoords = 4;
|
||||
|
||||
if (mOutputType == SH_HLSL9_OUTPUT)
|
||||
if (mOutputType == SH_HLSL_3_0_OUTPUT)
|
||||
{
|
||||
switch(textureFunction->sampler)
|
||||
{
|
||||
|
@ -718,29 +717,20 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
else if (mOutputType == SH_HLSL11_OUTPUT)
|
||||
else
|
||||
{
|
||||
switch(textureFunction->sampler)
|
||||
hlslCoords = HLSLTextureCoordsCount(textureFunction->sampler);
|
||||
if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
|
||||
{
|
||||
case EbtSampler2D: out << "Texture2D x, SamplerState s"; hlslCoords = 2; break;
|
||||
case EbtSampler3D: out << "Texture3D x, SamplerState s"; hlslCoords = 3; break;
|
||||
case EbtSamplerCube: out << "TextureCube x, SamplerState s"; hlslCoords = 3; break;
|
||||
case EbtSampler2DArray: out << "Texture2DArray x, SamplerState s"; hlslCoords = 3; break;
|
||||
case EbtISampler2D: out << "Texture2D<int4> x, SamplerState s"; hlslCoords = 2; break;
|
||||
case EbtISampler3D: out << "Texture3D<int4> x, SamplerState s"; hlslCoords = 3; break;
|
||||
case EbtISamplerCube: out << "Texture2DArray<int4> x, SamplerState s"; hlslCoords = 3; break;
|
||||
case EbtISampler2DArray: out << "Texture2DArray<int4> x, SamplerState s"; hlslCoords = 3; break;
|
||||
case EbtUSampler2D: out << "Texture2D<uint4> x, SamplerState s"; hlslCoords = 2; break;
|
||||
case EbtUSampler3D: out << "Texture3D<uint4> x, SamplerState s"; hlslCoords = 3; break;
|
||||
case EbtUSamplerCube: out << "Texture2DArray<uint4> x, SamplerState s"; hlslCoords = 3; break;
|
||||
case EbtUSampler2DArray: out << "Texture2DArray<uint4> x, SamplerState s"; hlslCoords = 3; break;
|
||||
case EbtSampler2DShadow: out << "Texture2D x, SamplerComparisonState s"; hlslCoords = 2; break;
|
||||
case EbtSamplerCubeShadow: out << "TextureCube x, SamplerComparisonState s"; hlslCoords = 3; break;
|
||||
case EbtSampler2DArrayShadow: out << "Texture2DArray x, SamplerComparisonState s"; hlslCoords = 3; break;
|
||||
default: UNREACHABLE();
|
||||
out << TextureString(textureFunction->sampler) << " x, "
|
||||
<< SamplerString(textureFunction->sampler) << " s";
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(mOutputType == SH_HLSL_4_1_OUTPUT);
|
||||
out << "const uint samplerIndex";
|
||||
}
|
||||
}
|
||||
else UNREACHABLE();
|
||||
|
||||
if (textureFunction->method == TextureFunction::FETCH) // Integer coordinates
|
||||
{
|
||||
|
@ -831,6 +821,31 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
out << ")\n"
|
||||
"{\n";
|
||||
|
||||
// In some cases we use a variable to store the texture/sampler objects, but to work around
|
||||
// a D3D11 compiler bug related to discard inside a loop that is conditional on texture
|
||||
// sampling we need to call the function directly on a reference to the array. The bug was
|
||||
// found using dEQP-GLES3.functional.shaders.discard*loop_texture* tests.
|
||||
TString textureReference("x");
|
||||
TString samplerReference("s");
|
||||
if (mOutputType == SH_HLSL_4_1_OUTPUT)
|
||||
{
|
||||
TString suffix = TextureGroupSuffix(textureFunction->sampler);
|
||||
if (TextureGroup(textureFunction->sampler) == HLSL_TEXTURE_2D)
|
||||
{
|
||||
textureReference = TString("textures") + suffix + "[samplerIndex]";
|
||||
samplerReference = TString("samplers") + suffix + "[samplerIndex]";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << " const uint textureIndex = samplerIndex - textureIndexOffset" << suffix
|
||||
<< ";\n";
|
||||
textureReference = TString("textures") + suffix + "[textureIndex]";
|
||||
out << " const uint samplerArrayIndex = samplerIndex - samplerIndexOffset"
|
||||
<< suffix << ";\n";
|
||||
samplerReference = TString("samplers") + suffix + "[samplerArrayIndex]";
|
||||
}
|
||||
}
|
||||
|
||||
if (textureFunction->method == TextureFunction::SIZE)
|
||||
{
|
||||
if (IsSampler2D(textureFunction->sampler) || IsSamplerCube(textureFunction->sampler))
|
||||
|
@ -838,18 +853,21 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
if (IsSamplerArray(textureFunction->sampler))
|
||||
{
|
||||
out << " uint width; uint height; uint layers; uint numberOfLevels;\n"
|
||||
" x.GetDimensions(lod, width, height, layers, numberOfLevels);\n";
|
||||
<< " " << textureReference
|
||||
<< ".GetDimensions(lod, width, height, layers, numberOfLevels);\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << " uint width; uint height; uint numberOfLevels;\n"
|
||||
" x.GetDimensions(lod, width, height, numberOfLevels);\n";
|
||||
<< " " << textureReference
|
||||
<< ".GetDimensions(lod, width, height, numberOfLevels);\n";
|
||||
}
|
||||
}
|
||||
else if (IsSampler3D(textureFunction->sampler))
|
||||
{
|
||||
out << " uint width; uint height; uint depth; uint numberOfLevels;\n"
|
||||
" x.GetDimensions(lod, width, height, depth, numberOfLevels);\n";
|
||||
<< " " << textureReference
|
||||
<< ".GetDimensions(lod, width, height, depth, numberOfLevels);\n";
|
||||
}
|
||||
else UNREACHABLE();
|
||||
|
||||
|
@ -881,7 +899,8 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
|
||||
out << " uint mip = 0;\n";
|
||||
|
||||
out << " x.GetDimensions(mip, width, height, layers, levels);\n";
|
||||
out << " " << textureReference
|
||||
<< ".GetDimensions(mip, width, height, layers, levels);\n";
|
||||
|
||||
out << " bool xMajor = abs(t.x) > abs(t.y) && abs(t.x) > abs(t.z);\n";
|
||||
out << " bool yMajor = abs(t.y) > abs(t.z) && abs(t.y) > abs(t.x);\n";
|
||||
|
@ -911,7 +930,8 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
" float2 dy = ddy(tSized);\n"
|
||||
" float lod = 0.5f * log2(max(dot(dx, dx), dot(dy, dy)));\n"
|
||||
" mip = uint(min(max(round(lod), 0), levels - 1));\n"
|
||||
" x.GetDimensions(mip, width, height, layers, levels);\n";
|
||||
<< " " << textureReference
|
||||
<< ".GetDimensions(mip, width, height, layers, levels);\n";
|
||||
}
|
||||
}
|
||||
else if (IsIntegerSampler(textureFunction->sampler) &&
|
||||
|
@ -934,7 +954,8 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
else
|
||||
{
|
||||
|
||||
out << " x.GetDimensions(0, width, height, layers, levels);\n";
|
||||
out << " " << textureReference
|
||||
<< ".GetDimensions(0, width, height, layers, levels);\n";
|
||||
if (textureFunction->method == TextureFunction::IMPLICIT ||
|
||||
textureFunction->method == TextureFunction::BIAS)
|
||||
{
|
||||
|
@ -956,7 +977,8 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
|
||||
}
|
||||
|
||||
out << " x.GetDimensions(mip, width, height, layers, levels);\n";
|
||||
out << " " << textureReference
|
||||
<< ".GetDimensions(mip, width, height, layers, levels);\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -972,7 +994,8 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
}
|
||||
else
|
||||
{
|
||||
out << " x.GetDimensions(0, width, height, levels);\n";
|
||||
out << " " << textureReference
|
||||
<< ".GetDimensions(0, width, height, levels);\n";
|
||||
|
||||
if (textureFunction->method == TextureFunction::IMPLICIT ||
|
||||
textureFunction->method == TextureFunction::BIAS)
|
||||
|
@ -995,7 +1018,8 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
|
||||
}
|
||||
|
||||
out << " x.GetDimensions(mip, width, height, levels);\n";
|
||||
out << " " << textureReference
|
||||
<< ".GetDimensions(mip, width, height, levels);\n";
|
||||
}
|
||||
}
|
||||
else if (IsSampler3D(textureFunction->sampler))
|
||||
|
@ -1012,7 +1036,8 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
}
|
||||
else
|
||||
{
|
||||
out << " x.GetDimensions(0, width, height, depth, levels);\n";
|
||||
out << " " << textureReference
|
||||
<< ".GetDimensions(0, width, height, depth, levels);\n";
|
||||
|
||||
if (textureFunction->method == TextureFunction::IMPLICIT ||
|
||||
textureFunction->method == TextureFunction::BIAS)
|
||||
|
@ -1036,7 +1061,8 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
|
||||
}
|
||||
|
||||
out << " x.GetDimensions(mip, width, height, depth, levels);\n";
|
||||
out << " " << textureReference
|
||||
<< ".GetDimensions(mip, width, height, depth, levels);\n";
|
||||
}
|
||||
else UNREACHABLE();
|
||||
}
|
||||
|
@ -1044,7 +1070,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
out << " return ";
|
||||
|
||||
// HLSL intrinsic
|
||||
if (mOutputType == SH_HLSL9_OUTPUT)
|
||||
if (mOutputType == SH_HLSL_3_0_OUTPUT)
|
||||
{
|
||||
switch(textureFunction->sampler)
|
||||
{
|
||||
|
@ -1055,45 +1081,71 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
|
||||
switch(textureFunction->method)
|
||||
{
|
||||
case TextureFunction::IMPLICIT: out << "(s, "; break;
|
||||
case TextureFunction::BIAS: out << "bias(s, "; break;
|
||||
case TextureFunction::LOD: out << "lod(s, "; break;
|
||||
case TextureFunction::LOD0: out << "lod(s, "; break;
|
||||
case TextureFunction::LOD0BIAS: out << "lod(s, "; break;
|
||||
case TextureFunction::IMPLICIT:
|
||||
out << "(" << samplerReference << ", ";
|
||||
break;
|
||||
case TextureFunction::BIAS:
|
||||
out << "bias(" << samplerReference << ", ";
|
||||
break;
|
||||
case TextureFunction::LOD:
|
||||
out << "lod(" << samplerReference << ", ";
|
||||
break;
|
||||
case TextureFunction::LOD0:
|
||||
out << "lod(" << samplerReference << ", ";
|
||||
break;
|
||||
case TextureFunction::LOD0BIAS:
|
||||
out << "lod(" << samplerReference << ", ";
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
else if (mOutputType == SH_HLSL11_OUTPUT)
|
||||
else if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
|
||||
{
|
||||
if (textureFunction->method == TextureFunction::GRAD)
|
||||
{
|
||||
if (IsIntegerSampler(textureFunction->sampler))
|
||||
{
|
||||
out << "x.Load(";
|
||||
out << "" << textureReference << ".Load(";
|
||||
}
|
||||
else if (IsShadowSampler(textureFunction->sampler))
|
||||
{
|
||||
out << "x.SampleCmpLevelZero(s, ";
|
||||
out << "" << textureReference << ".SampleCmpLevelZero(" << samplerReference
|
||||
<< ", ";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "x.SampleGrad(s, ";
|
||||
out << "" << textureReference << ".SampleGrad(" << samplerReference << ", ";
|
||||
}
|
||||
}
|
||||
else if (IsIntegerSampler(textureFunction->sampler) ||
|
||||
textureFunction->method == TextureFunction::FETCH)
|
||||
{
|
||||
out << "x.Load(";
|
||||
out << "" << textureReference << ".Load(";
|
||||
}
|
||||
else if (IsShadowSampler(textureFunction->sampler))
|
||||
{
|
||||
switch(textureFunction->method)
|
||||
{
|
||||
case TextureFunction::IMPLICIT: out << "x.SampleCmp(s, "; break;
|
||||
case TextureFunction::BIAS: out << "x.SampleCmp(s, "; break;
|
||||
case TextureFunction::LOD: out << "x.SampleCmp(s, "; break;
|
||||
case TextureFunction::LOD0: out << "x.SampleCmpLevelZero(s, "; break;
|
||||
case TextureFunction::LOD0BIAS: out << "x.SampleCmpLevelZero(s, "; break;
|
||||
case TextureFunction::IMPLICIT:
|
||||
out << "" << textureReference << ".SampleCmp(" << samplerReference
|
||||
<< ", ";
|
||||
break;
|
||||
case TextureFunction::BIAS:
|
||||
out << "" << textureReference << ".SampleCmp(" << samplerReference
|
||||
<< ", ";
|
||||
break;
|
||||
case TextureFunction::LOD:
|
||||
out << "" << textureReference << ".SampleCmp(" << samplerReference
|
||||
<< ", ";
|
||||
break;
|
||||
case TextureFunction::LOD0:
|
||||
out << "" << textureReference << ".SampleCmpLevelZero("
|
||||
<< samplerReference << ", ";
|
||||
break;
|
||||
case TextureFunction::LOD0BIAS:
|
||||
out << "" << textureReference << ".SampleCmpLevelZero("
|
||||
<< samplerReference << ", ";
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
@ -1101,11 +1153,25 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
{
|
||||
switch(textureFunction->method)
|
||||
{
|
||||
case TextureFunction::IMPLICIT: out << "x.Sample(s, "; break;
|
||||
case TextureFunction::BIAS: out << "x.SampleBias(s, "; break;
|
||||
case TextureFunction::LOD: out << "x.SampleLevel(s, "; break;
|
||||
case TextureFunction::LOD0: out << "x.SampleLevel(s, "; break;
|
||||
case TextureFunction::LOD0BIAS: out << "x.SampleLevel(s, "; break;
|
||||
case TextureFunction::IMPLICIT:
|
||||
out << "" << textureReference << ".Sample(" << samplerReference << ", ";
|
||||
break;
|
||||
case TextureFunction::BIAS:
|
||||
out << "" << textureReference << ".SampleBias(" << samplerReference
|
||||
<< ", ";
|
||||
break;
|
||||
case TextureFunction::LOD:
|
||||
out << "" << textureReference << ".SampleLevel(" << samplerReference
|
||||
<< ", ";
|
||||
break;
|
||||
case TextureFunction::LOD0:
|
||||
out << "" << textureReference << ".SampleLevel(" << samplerReference
|
||||
<< ", ";
|
||||
break;
|
||||
case TextureFunction::LOD0BIAS:
|
||||
out << "" << textureReference << ".SampleLevel(" << samplerReference
|
||||
<< ", ";
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
@ -1175,7 +1241,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
|
||||
out << addressx + ("t.x" + proj) + close + ", " + addressy + ("t.y" + proj) + close;
|
||||
|
||||
if (mOutputType == SH_HLSL9_OUTPUT)
|
||||
if (mOutputType == SH_HLSL_3_0_OUTPUT)
|
||||
{
|
||||
if (hlslCoords >= 3)
|
||||
{
|
||||
|
@ -1203,7 +1269,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
|
|||
|
||||
out << "));\n";
|
||||
}
|
||||
else if (mOutputType == SH_HLSL11_OUTPUT)
|
||||
else if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
|
||||
{
|
||||
if (hlslCoords >= 3)
|
||||
{
|
||||
|
@ -2393,7 +2459,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
|
|||
|
||||
for (TIntermSequence::iterator arg = arguments->begin(); arg != arguments->end(); arg++)
|
||||
{
|
||||
if (mOutputType == SH_HLSL11_OUTPUT && IsSampler((*arg)->getAsTyped()->getBasicType()))
|
||||
if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT &&
|
||||
IsSampler((*arg)->getAsTyped()->getBasicType()))
|
||||
{
|
||||
out << "texture_";
|
||||
(*arg)->traverse(this);
|
||||
|
@ -2727,7 +2794,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
|
|||
|
||||
TInfoSinkBase &out = getInfoSink();
|
||||
|
||||
if (mOutputType == SH_HLSL9_OUTPUT)
|
||||
if (mOutputType == SH_HLSL_3_0_OUTPUT)
|
||||
{
|
||||
if (handleExcessiveLoop(out, node))
|
||||
{
|
||||
|
@ -3154,11 +3221,21 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
|
|||
nameStr = DecorateIfNeeded(name);
|
||||
}
|
||||
|
||||
if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType()))
|
||||
if (IsSampler(type.getBasicType()))
|
||||
{
|
||||
return QualifierString(qualifier) + " " + TextureString(type) + " texture_" + nameStr +
|
||||
ArrayString(type) + ", " + QualifierString(qualifier) + " " + SamplerString(type) +
|
||||
" sampler_" + nameStr + ArrayString(type);
|
||||
if (mOutputType == SH_HLSL_4_1_OUTPUT)
|
||||
{
|
||||
// Samplers are passed as indices to the sampler array.
|
||||
ASSERT(qualifier != EvqOut && qualifier != EvqInOut);
|
||||
return "const uint " + nameStr + ArrayString(type);
|
||||
}
|
||||
if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
|
||||
{
|
||||
return QualifierString(qualifier) + " " + TextureString(type.getBasicType()) +
|
||||
" texture_" + nameStr + ArrayString(type) + ", " + QualifierString(qualifier) +
|
||||
" " + SamplerString(type.getBasicType()) + " sampler_" + nameStr +
|
||||
ArrayString(type);
|
||||
}
|
||||
}
|
||||
|
||||
return QualifierString(qualifier) + " " + TypeString(type) + " " + nameStr + ArrayString(type);
|
||||
|
|
|
@ -1925,6 +1925,84 @@ void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
|
|||
}
|
||||
}
|
||||
|
||||
TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &function,
|
||||
const TSourceLoc &location)
|
||||
{
|
||||
// Note: symbolTableFunction could be the same as function if this is the first declaration.
|
||||
// Either way the instance in the symbol table is used to track whether the function is declared
|
||||
// multiple times.
|
||||
TFunction *symbolTableFunction =
|
||||
static_cast<TFunction *>(symbolTable.find(function.getMangledName(), getShaderVersion()));
|
||||
if (symbolTableFunction->hasPrototypeDeclaration() && mShaderVersion == 100)
|
||||
{
|
||||
// ESSL 1.00.17 section 4.2.7.
|
||||
// Doesn't apply to ESSL 3.00.4: see section 4.2.3.
|
||||
error(location, "duplicate function prototype declarations are not allowed", "function");
|
||||
recover();
|
||||
}
|
||||
symbolTableFunction->setHasPrototypeDeclaration();
|
||||
|
||||
TIntermAggregate *prototype = new TIntermAggregate;
|
||||
prototype->setType(function.getReturnType());
|
||||
prototype->setName(function.getMangledName());
|
||||
prototype->setFunctionId(function.getUniqueId());
|
||||
|
||||
for (size_t i = 0; i < function.getParamCount(); i++)
|
||||
{
|
||||
const TConstParameter ¶m = function.getParam(i);
|
||||
if (param.name != 0)
|
||||
{
|
||||
TVariable variable(param.name, *param.type);
|
||||
|
||||
TIntermSymbol *paramSymbol = intermediate.addSymbol(
|
||||
variable.getUniqueId(), variable.getName(), variable.getType(), location);
|
||||
prototype = intermediate.growAggregate(prototype, paramSymbol, location);
|
||||
}
|
||||
else
|
||||
{
|
||||
TIntermSymbol *paramSymbol = intermediate.addSymbol(0, "", *param.type, location);
|
||||
prototype = intermediate.growAggregate(prototype, paramSymbol, location);
|
||||
}
|
||||
}
|
||||
|
||||
prototype->setOp(EOpPrototype);
|
||||
|
||||
symbolTable.pop();
|
||||
|
||||
if (!symbolTable.atGlobalLevel())
|
||||
{
|
||||
// ESSL 3.00.4 section 4.2.4.
|
||||
error(location, "local function prototype declarations are not allowed", "function");
|
||||
recover();
|
||||
}
|
||||
|
||||
return prototype;
|
||||
}
|
||||
|
||||
TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function,
|
||||
TIntermAggregate *functionPrototype,
|
||||
TIntermAggregate *functionBody,
|
||||
const TSourceLoc &location)
|
||||
{
|
||||
//?? Check that all paths return a value if return type != void ?
|
||||
// May be best done as post process phase on intermediate code
|
||||
if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
|
||||
{
|
||||
error(location, "function does not return a value:", "", function.getName().c_str());
|
||||
recover();
|
||||
}
|
||||
|
||||
TIntermAggregate *aggregate =
|
||||
intermediate.growAggregate(functionPrototype, functionBody, location);
|
||||
intermediate.setAggregateOperator(aggregate, EOpFunction, location);
|
||||
aggregate->setName(function.getMangledName().c_str());
|
||||
aggregate->setType(function.getReturnType());
|
||||
aggregate->setFunctionId(function.getUniqueId());
|
||||
|
||||
symbolTable.pop();
|
||||
return aggregate;
|
||||
}
|
||||
|
||||
void TParseContext::parseFunctionPrototype(const TSourceLoc &location,
|
||||
TFunction *function,
|
||||
TIntermAggregate **aggregateOut)
|
||||
|
@ -1978,8 +2056,8 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location,
|
|||
//
|
||||
// Remember the return type for later checking for RETURN statements.
|
||||
//
|
||||
setCurrentFunctionType(&(prevDec->getReturnType()));
|
||||
setFunctionReturnsValue(false);
|
||||
mCurrentFunctionType = &(prevDec->getReturnType());
|
||||
mFunctionReturnsValue = false;
|
||||
|
||||
//
|
||||
// Insert parameters into the symbol table.
|
||||
|
@ -2030,12 +2108,12 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location,
|
|||
TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
|
||||
{
|
||||
//
|
||||
// Multiple declarations of the same function are allowed.
|
||||
// We don't know at this point whether this is a function definition or a prototype.
|
||||
// The definition production code will check for redefinitions.
|
||||
// In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
|
||||
//
|
||||
// If this is a definition, the definition production code will check for redefinitions
|
||||
// (we don't know at this point if it's a definition or not).
|
||||
//
|
||||
// Redeclarations are allowed. But, return types and parameter qualifiers must match.
|
||||
// Return types and parameter qualifiers must match in all redeclarations, so those are checked
|
||||
// here.
|
||||
//
|
||||
TFunction *prevDec =
|
||||
static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
|
||||
|
|
|
@ -57,6 +57,7 @@ class TParseContext : angle::NonCopyable
|
|||
mDirectiveHandler(ext,
|
||||
mDiagnostics,
|
||||
mShaderVersion,
|
||||
mShaderType,
|
||||
resources.WEBGL_debug_shader_precision == 1),
|
||||
mPreprocessor(&mDiagnostics, &mDirectiveHandler),
|
||||
mScanner(nullptr),
|
||||
|
@ -102,23 +103,11 @@ class TParseContext : angle::NonCopyable
|
|||
mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
|
||||
}
|
||||
|
||||
bool getFunctionReturnsValue() const { return mFunctionReturnsValue; }
|
||||
void setFunctionReturnsValue(bool functionReturnsValue)
|
||||
{
|
||||
mFunctionReturnsValue = functionReturnsValue;
|
||||
}
|
||||
|
||||
void setLoopNestingLevel(int loopNestintLevel)
|
||||
{
|
||||
mLoopNestingLevel = loopNestintLevel;
|
||||
}
|
||||
|
||||
const TType *getCurrentFunctionType() const { return mCurrentFunctionType; }
|
||||
void setCurrentFunctionType(const TType *currentFunctionType)
|
||||
{
|
||||
mCurrentFunctionType = currentFunctionType;
|
||||
}
|
||||
|
||||
void incrLoopNestingLevel() { ++mLoopNestingLevel; }
|
||||
void decrLoopNestingLevel() { --mLoopNestingLevel; }
|
||||
|
||||
|
@ -244,6 +233,12 @@ class TParseContext : angle::NonCopyable
|
|||
TIntermTyped *initializer);
|
||||
|
||||
void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
|
||||
TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &function,
|
||||
const TSourceLoc &location);
|
||||
TIntermAggregate *addFunctionDefinition(const TFunction &function,
|
||||
TIntermAggregate *functionPrototype,
|
||||
TIntermAggregate *functionBody,
|
||||
const TSourceLoc &location);
|
||||
void parseFunctionPrototype(const TSourceLoc &location,
|
||||
TFunction *function,
|
||||
TIntermAggregate **aggregateOut);
|
||||
|
|
|
@ -189,9 +189,16 @@ ShHandle ShConstructCompiler(sh::GLenum type, ShShaderSpec spec,
|
|||
const ShBuiltInResources* resources)
|
||||
{
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
if (base == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Generate built-in symbol table.
|
||||
if (!compiler->Init(*resources)) {
|
||||
|
|
|
@ -393,4 +393,9 @@ InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
std::string InterfaceBlock::fieldPrefix() const
|
||||
{
|
||||
return instanceName.empty() ? "" : name;
|
||||
}
|
||||
|
||||
} // namespace sh
|
||||
|
|
|
@ -197,12 +197,16 @@ struct TParameter
|
|||
class TFunction : public TSymbol
|
||||
{
|
||||
public:
|
||||
TFunction(const TString *name, const TType *retType, TOperator tOp = EOpNull, const char *ext = "")
|
||||
TFunction(const TString *name,
|
||||
const TType *retType,
|
||||
TOperator tOp = EOpNull,
|
||||
const char *ext = "")
|
||||
: TSymbol(name),
|
||||
returnType(retType),
|
||||
mangledName(nullptr),
|
||||
op(tOp),
|
||||
defined(false)
|
||||
defined(false),
|
||||
mHasPrototypeDeclaration(false)
|
||||
{
|
||||
relateToExtension(ext);
|
||||
}
|
||||
|
@ -242,14 +246,10 @@ class TFunction : public TSymbol
|
|||
return op;
|
||||
}
|
||||
|
||||
void setDefined()
|
||||
{
|
||||
defined = true;
|
||||
}
|
||||
bool isDefined()
|
||||
{
|
||||
return defined;
|
||||
}
|
||||
void setDefined() { defined = true; }
|
||||
bool isDefined() { return defined; }
|
||||
void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
|
||||
bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
|
||||
|
||||
size_t getParamCount() const
|
||||
{
|
||||
|
@ -269,6 +269,7 @@ class TFunction : public TSymbol
|
|||
mutable const TString *mangledName;
|
||||
TOperator op;
|
||||
bool defined;
|
||||
bool mHasPrototypeDeclaration;
|
||||
};
|
||||
|
||||
// Interface block name sub-symbol
|
||||
|
|
|
@ -47,7 +47,7 @@ void TranslatorHLSL::translate(TIntermNode *root, int compileOptions)
|
|||
|
||||
// Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
|
||||
// use a vertex attribute as a condition, and some related computation in the else block.
|
||||
if (getOutputType() == SH_HLSL9_OUTPUT && getShaderType() == GL_VERTEX_SHADER)
|
||||
if (getOutputType() == SH_HLSL_3_0_OUTPUT && getShaderType() == GL_VERTEX_SHADER)
|
||||
{
|
||||
sh::RewriteElseBlocks(root, getTemporaryIndex());
|
||||
}
|
||||
|
|
|
@ -93,7 +93,9 @@ const Uniform *UniformHLSL::findUniformByName(const TString &name) const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name)
|
||||
unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type,
|
||||
const TString &name,
|
||||
unsigned int *registerCount)
|
||||
{
|
||||
unsigned int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister);
|
||||
|
||||
|
@ -102,43 +104,119 @@ unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, con
|
|||
|
||||
mUniformRegisterMap[uniform->name] = registerIndex;
|
||||
|
||||
unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);
|
||||
ASSERT(registerCount);
|
||||
*registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);
|
||||
|
||||
if (gl::IsSamplerType(uniform->type))
|
||||
{
|
||||
mSamplerRegister += registerCount;
|
||||
mSamplerRegister += *registerCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
mUniformRegister += registerCount;
|
||||
mUniformRegister += *registerCount;
|
||||
}
|
||||
|
||||
return registerIndex;
|
||||
}
|
||||
|
||||
TString UniformHLSL::uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms)
|
||||
unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name)
|
||||
{
|
||||
TString uniforms;
|
||||
unsigned int registerCount;
|
||||
return declareUniformAndAssignRegister(type, name, ®isterCount);
|
||||
}
|
||||
|
||||
for (ReferencedSymbols::const_iterator uniformIt = referencedUniforms.begin();
|
||||
uniformIt != referencedUniforms.end(); uniformIt++)
|
||||
void UniformHLSL::outputHLSLSamplerUniformGroup(TInfoSinkBase &out,
|
||||
const HLSLTextureSamplerGroup textureGroup,
|
||||
const TVector<const TIntermSymbol *> &group,
|
||||
unsigned int *groupTextureRegisterIndex)
|
||||
{
|
||||
if (group.empty())
|
||||
{
|
||||
const TIntermSymbol &uniform = *uniformIt->second;
|
||||
const TType &type = uniform.getType();
|
||||
const TString &name = uniform.getSymbol();
|
||||
|
||||
unsigned int registerIndex = declareUniformAndAssignRegister(type, name);
|
||||
|
||||
if (outputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) // Also declare the texture
|
||||
return;
|
||||
}
|
||||
unsigned int groupRegisterCount = 0;
|
||||
for (const TIntermSymbol *uniform : group)
|
||||
{
|
||||
const TType &type = uniform->getType();
|
||||
const TString &name = uniform->getSymbol();
|
||||
unsigned int registerCount;
|
||||
unsigned int samplerArrayIndex =
|
||||
declareUniformAndAssignRegister(type, name, ®isterCount);
|
||||
groupRegisterCount += registerCount;
|
||||
if (type.isArray())
|
||||
{
|
||||
uniforms += "uniform " + SamplerString(type) + " sampler_" + DecorateUniform(name, type) + ArrayString(type) +
|
||||
" : register(s" + str(registerIndex) + ");\n";
|
||||
|
||||
uniforms += "uniform " + TextureString(type) + " texture_" + DecorateUniform(name, type) + ArrayString(type) +
|
||||
" : register(t" + str(registerIndex) + ");\n";
|
||||
out << "static const uint " << DecorateIfNeeded(uniform->getName()) << ArrayString(type)
|
||||
<< " = {";
|
||||
for (int i = 0; i < type.getArraySize(); ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
out << ", ";
|
||||
out << (samplerArrayIndex + i);
|
||||
}
|
||||
out << "};\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "static const uint " << DecorateIfNeeded(uniform->getName()) << " = "
|
||||
<< samplerArrayIndex << ";\n";
|
||||
}
|
||||
}
|
||||
TString suffix = TextureGroupSuffix(textureGroup);
|
||||
// Since HLSL_TEXTURE_2D is the first group, it has a fixed offset of zero.
|
||||
if (textureGroup != HLSL_TEXTURE_2D)
|
||||
{
|
||||
out << "static const uint textureIndexOffset" << suffix << " = "
|
||||
<< (*groupTextureRegisterIndex) << ";\n";
|
||||
out << "static const uint samplerIndexOffset" << suffix << " = "
|
||||
<< (*groupTextureRegisterIndex) << ";\n";
|
||||
}
|
||||
out << "uniform " << TextureString(textureGroup) << " textures" << suffix << "["
|
||||
<< groupRegisterCount << "]"
|
||||
<< " : register(t" << (*groupTextureRegisterIndex) << ");\n";
|
||||
out << "uniform " << SamplerString(textureGroup) << " samplers" << suffix << "["
|
||||
<< groupRegisterCount << "]"
|
||||
<< " : register(s" << (*groupTextureRegisterIndex) << ");\n";
|
||||
*groupTextureRegisterIndex += groupRegisterCount;
|
||||
}
|
||||
|
||||
void UniformHLSL::uniformsHeader(TInfoSinkBase &out,
|
||||
ShShaderOutput outputType,
|
||||
const ReferencedSymbols &referencedUniforms)
|
||||
{
|
||||
if (!referencedUniforms.empty())
|
||||
{
|
||||
out << "// Uniforms\n\n";
|
||||
}
|
||||
// In the case of HLSL 4, sampler uniforms need to be grouped by type before the code is
|
||||
// written. They are grouped based on the combination of the HLSL texture type and
|
||||
// HLSL sampler type, enumerated in HLSLTextureSamplerGroup.
|
||||
TVector<TVector<const TIntermSymbol *>> groupedSamplerUniforms;
|
||||
groupedSamplerUniforms.resize(HLSL_TEXTURE_MAX + 1);
|
||||
for (auto &uniformIt : referencedUniforms)
|
||||
{
|
||||
// Output regular uniforms. Group sampler uniforms by type.
|
||||
const TIntermSymbol &uniform = *uniformIt.second;
|
||||
const TType &type = uniform.getType();
|
||||
const TString &name = uniform.getSymbol();
|
||||
|
||||
if (outputType == SH_HLSL_4_1_OUTPUT && IsSampler(type.getBasicType()))
|
||||
{
|
||||
HLSLTextureSamplerGroup group = TextureGroup(type.getBasicType());
|
||||
groupedSamplerUniforms[group].push_back(&uniform);
|
||||
}
|
||||
else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(type.getBasicType()))
|
||||
{
|
||||
unsigned int registerIndex = declareUniformAndAssignRegister(type, name);
|
||||
out << "uniform " << SamplerString(type.getBasicType()) << " sampler_"
|
||||
<< DecorateUniform(name, type) << ArrayString(type) << " : register(s"
|
||||
<< str(registerIndex) << ");\n";
|
||||
out << "uniform " << TextureString(type.getBasicType()) << " texture_"
|
||||
<< DecorateUniform(name, type) << ArrayString(type) << " : register(t"
|
||||
<< str(registerIndex) << ");\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int registerIndex = declareUniformAndAssignRegister(type, name);
|
||||
const TStructure *structure = type.getStruct();
|
||||
// If this is a nameless struct, we need to use its full definition, rather than its (empty) name.
|
||||
// TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for
|
||||
|
@ -149,11 +227,23 @@ TString UniformHLSL::uniformsHeader(ShShaderOutput outputType, const ReferencedS
|
|||
|
||||
const TString ®isterString = TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")";
|
||||
|
||||
uniforms += "uniform " + typeName + " " + DecorateUniform(name, type) + ArrayString(type) + " : " + registerString + ";\n";
|
||||
out << "uniform " << typeName << " " << DecorateUniform(name, type) << ArrayString(type)
|
||||
<< " : " << registerString << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
return (uniforms.empty() ? "" : ("// Uniforms\n\n" + uniforms));
|
||||
if (outputType == SH_HLSL_4_1_OUTPUT)
|
||||
{
|
||||
unsigned int groupTextureRegisterIndex = 0;
|
||||
// TEXTURE_2D is special, index offset is assumed to be 0 and omitted in that case.
|
||||
ASSERT(HLSL_TEXTURE_MIN == HLSL_TEXTURE_2D);
|
||||
for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId)
|
||||
{
|
||||
outputHLSLSamplerUniformGroup(out, HLSLTextureSamplerGroup(groupId),
|
||||
groupedSamplerUniforms[groupId],
|
||||
&groupTextureRegisterIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define COMPILER_TRANSLATOR_UNIFORMHLSL_H_
|
||||
|
||||
#include "compiler/translator/OutputHLSL.h"
|
||||
#include "compiler/translator/UtilsHLSL.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
@ -23,7 +24,13 @@ class UniformHLSL : angle::NonCopyable
|
|||
|
||||
void reserveUniformRegisters(unsigned int registerCount);
|
||||
void reserveInterfaceBlockRegisters(unsigned int registerCount);
|
||||
TString uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms);
|
||||
void outputHLSLSamplerUniformGroup(TInfoSinkBase &out,
|
||||
const HLSLTextureSamplerGroup textureGroup,
|
||||
const TVector<const TIntermSymbol *> &group,
|
||||
unsigned int *groupTextureRegisterIndex);
|
||||
void uniformsHeader(TInfoSinkBase &out,
|
||||
ShShaderOutput outputType,
|
||||
const ReferencedSymbols &referencedUniforms);
|
||||
TString interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks);
|
||||
|
||||
// Used for direct index references
|
||||
|
@ -45,6 +52,9 @@ class UniformHLSL : angle::NonCopyable
|
|||
const Uniform *findUniformByName(const TString &name) const;
|
||||
|
||||
// Returns the uniform's register index
|
||||
unsigned int declareUniformAndAssignRegister(const TType &type,
|
||||
const TString &name,
|
||||
unsigned int *registerCount);
|
||||
unsigned int declareUniformAndAssignRegister(const TType &type, const TString &name);
|
||||
|
||||
unsigned int mUniformRegister;
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
namespace sh
|
||||
{
|
||||
|
||||
TString SamplerString(const TType &type)
|
||||
TString SamplerString(const TBasicType type)
|
||||
{
|
||||
if (IsShadowSampler(type.getBasicType()))
|
||||
if (IsShadowSampler(type))
|
||||
{
|
||||
return "SamplerComparisonState";
|
||||
}
|
||||
|
@ -27,32 +27,158 @@ TString SamplerString(const TType &type)
|
|||
}
|
||||
}
|
||||
|
||||
TString TextureString(const TType &type)
|
||||
TString SamplerString(HLSLTextureSamplerGroup type)
|
||||
{
|
||||
switch (type.getBasicType())
|
||||
if (type >= HLSL_COMPARISON_SAMPLER_GROUP_BEGIN && type <= HLSL_COMPARISON_SAMPLER_GROUP_END)
|
||||
{
|
||||
case EbtSampler2D: return "Texture2D";
|
||||
case EbtSamplerCube: return "TextureCube";
|
||||
case EbtSamplerExternalOES: return "Texture2D";
|
||||
case EbtSampler2DArray: return "Texture2DArray";
|
||||
case EbtSampler3D: return "Texture3D";
|
||||
case EbtISampler2D: return "Texture2D<int4>";
|
||||
case EbtISampler3D: return "Texture3D<int4>";
|
||||
case EbtISamplerCube: return "Texture2DArray<int4>";
|
||||
case EbtISampler2DArray: return "Texture2DArray<int4>";
|
||||
case EbtUSampler2D: return "Texture2D<uint4>";
|
||||
case EbtUSampler3D: return "Texture3D<uint4>";
|
||||
case EbtUSamplerCube: return "Texture2DArray<uint4>";
|
||||
case EbtUSampler2DArray: return "Texture2DArray<uint4>";
|
||||
case EbtSampler2DShadow: return "Texture2D";
|
||||
case EbtSamplerCubeShadow: return "TextureCube";
|
||||
case EbtSampler2DArrayShadow: return "Texture2DArray";
|
||||
default: UNREACHABLE();
|
||||
return "SamplerComparisonState";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "SamplerState";
|
||||
}
|
||||
}
|
||||
|
||||
HLSLTextureSamplerGroup TextureGroup(const TBasicType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EbtSampler2D:
|
||||
return HLSL_TEXTURE_2D;
|
||||
case EbtSamplerCube:
|
||||
return HLSL_TEXTURE_CUBE;
|
||||
case EbtSamplerExternalOES:
|
||||
return HLSL_TEXTURE_2D;
|
||||
case EbtSampler2DArray:
|
||||
return HLSL_TEXTURE_2D_ARRAY;
|
||||
case EbtSampler3D:
|
||||
return HLSL_TEXTURE_3D;
|
||||
case EbtISampler2D:
|
||||
return HLSL_TEXTURE_2D_INT4;
|
||||
case EbtISampler3D:
|
||||
return HLSL_TEXTURE_3D_INT4;
|
||||
case EbtISamplerCube:
|
||||
return HLSL_TEXTURE_2D_ARRAY_INT4;
|
||||
case EbtISampler2DArray:
|
||||
return HLSL_TEXTURE_2D_ARRAY_INT4;
|
||||
case EbtUSampler2D:
|
||||
return HLSL_TEXTURE_2D_UINT4;
|
||||
case EbtUSampler3D:
|
||||
return HLSL_TEXTURE_3D_UINT4;
|
||||
case EbtUSamplerCube:
|
||||
return HLSL_TEXTURE_2D_ARRAY_UINT4;
|
||||
case EbtUSampler2DArray:
|
||||
return HLSL_TEXTURE_2D_ARRAY_UINT4;
|
||||
case EbtSampler2DShadow:
|
||||
return HLSL_TEXTURE_2D_COMPARISON;
|
||||
case EbtSamplerCubeShadow:
|
||||
return HLSL_TEXTURE_CUBE_COMPARISON;
|
||||
case EbtSampler2DArrayShadow:
|
||||
return HLSL_TEXTURE_2D_ARRAY_COMPARISON;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
return HLSL_TEXTURE_UNKNOWN;
|
||||
}
|
||||
|
||||
TString TextureString(const HLSLTextureSamplerGroup type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case HLSL_TEXTURE_2D:
|
||||
return "Texture2D";
|
||||
case HLSL_TEXTURE_CUBE:
|
||||
return "TextureCube";
|
||||
case HLSL_TEXTURE_2D_ARRAY:
|
||||
return "Texture2DArray";
|
||||
case HLSL_TEXTURE_3D:
|
||||
return "Texture3D";
|
||||
case HLSL_TEXTURE_2D_INT4:
|
||||
return "Texture2D<int4>";
|
||||
case HLSL_TEXTURE_3D_INT4:
|
||||
return "Texture3D<int4>";
|
||||
case HLSL_TEXTURE_2D_ARRAY_INT4:
|
||||
return "Texture2DArray<int4>";
|
||||
case HLSL_TEXTURE_2D_UINT4:
|
||||
return "Texture2D<uint4>";
|
||||
case HLSL_TEXTURE_3D_UINT4:
|
||||
return "Texture3D<uint4>";
|
||||
case HLSL_TEXTURE_2D_ARRAY_UINT4:
|
||||
return "Texture2DArray<uint4>";
|
||||
case HLSL_TEXTURE_2D_COMPARISON:
|
||||
return "Texture2D";
|
||||
case HLSL_TEXTURE_CUBE_COMPARISON:
|
||||
return "TextureCube";
|
||||
case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
|
||||
return "Texture2DArray";
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return "<unknown texture type>";
|
||||
}
|
||||
|
||||
TString TextureString(const TBasicType type)
|
||||
{
|
||||
return TextureString(TextureGroup(type));
|
||||
}
|
||||
|
||||
TString TextureGroupSuffix(const HLSLTextureSamplerGroup type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case HLSL_TEXTURE_2D:
|
||||
return "2D";
|
||||
case HLSL_TEXTURE_CUBE:
|
||||
return "Cube";
|
||||
case HLSL_TEXTURE_2D_ARRAY:
|
||||
return "2DArray";
|
||||
case HLSL_TEXTURE_3D:
|
||||
return "3D";
|
||||
case HLSL_TEXTURE_2D_INT4:
|
||||
return "2D_int4_";
|
||||
case HLSL_TEXTURE_3D_INT4:
|
||||
return "3D_int4_";
|
||||
case HLSL_TEXTURE_2D_ARRAY_INT4:
|
||||
return "2DArray_int4_";
|
||||
case HLSL_TEXTURE_2D_UINT4:
|
||||
return "2D_uint4_";
|
||||
case HLSL_TEXTURE_3D_UINT4:
|
||||
return "3D_uint4_";
|
||||
case HLSL_TEXTURE_2D_ARRAY_UINT4:
|
||||
return "2DArray_uint4_";
|
||||
case HLSL_TEXTURE_2D_COMPARISON:
|
||||
return "2D_comparison";
|
||||
case HLSL_TEXTURE_CUBE_COMPARISON:
|
||||
return "Cube_comparison";
|
||||
case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
|
||||
return "2DArray_comparison";
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return "<unknown texture type>";
|
||||
}
|
||||
|
||||
TString TextureGroupSuffix(const TBasicType type)
|
||||
{
|
||||
return TextureGroupSuffix(TextureGroup(type));
|
||||
}
|
||||
|
||||
TString TextureTypeSuffix(const TBasicType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EbtISamplerCube:
|
||||
return "Cube_int4_";
|
||||
case EbtUSamplerCube:
|
||||
return "Cube_uint4_";
|
||||
default:
|
||||
// All other types are identified by their group suffix
|
||||
return TextureGroupSuffix(type);
|
||||
}
|
||||
}
|
||||
|
||||
TString DecorateUniform(const TString &string, const TType &type)
|
||||
{
|
||||
if (type.getBasicType() == EbtSamplerExternalOES)
|
||||
|
@ -270,4 +396,43 @@ TString QualifierString(TQualifier qualifier)
|
|||
return "";
|
||||
}
|
||||
|
||||
int HLSLTextureCoordsCount(const TBasicType samplerType)
|
||||
{
|
||||
switch (samplerType)
|
||||
{
|
||||
case EbtSampler2D:
|
||||
return 2;
|
||||
case EbtSampler3D:
|
||||
return 3;
|
||||
case EbtSamplerCube:
|
||||
return 3;
|
||||
case EbtSampler2DArray:
|
||||
return 3;
|
||||
case EbtISampler2D:
|
||||
return 2;
|
||||
case EbtISampler3D:
|
||||
return 3;
|
||||
case EbtISamplerCube:
|
||||
return 3;
|
||||
case EbtISampler2DArray:
|
||||
return 3;
|
||||
case EbtUSampler2D:
|
||||
return 2;
|
||||
case EbtUSampler3D:
|
||||
return 3;
|
||||
case EbtUSamplerCube:
|
||||
return 3;
|
||||
case EbtUSampler2DArray:
|
||||
return 3;
|
||||
case EbtSampler2DShadow:
|
||||
return 2;
|
||||
case EbtSamplerCubeShadow:
|
||||
return 3;
|
||||
case EbtSampler2DArrayShadow:
|
||||
return 3;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,44 @@ class TName;
|
|||
namespace sh
|
||||
{
|
||||
|
||||
TString TextureString(const TType &type);
|
||||
TString SamplerString(const TType &type);
|
||||
// Unique combinations of HLSL Texture type and HLSL Sampler type.
|
||||
enum HLSLTextureSamplerGroup
|
||||
{
|
||||
// Regular samplers
|
||||
HLSL_TEXTURE_2D,
|
||||
HLSL_TEXTURE_MIN = HLSL_TEXTURE_2D,
|
||||
|
||||
HLSL_TEXTURE_CUBE,
|
||||
HLSL_TEXTURE_2D_ARRAY,
|
||||
HLSL_TEXTURE_3D,
|
||||
HLSL_TEXTURE_2D_INT4,
|
||||
HLSL_TEXTURE_3D_INT4,
|
||||
HLSL_TEXTURE_2D_ARRAY_INT4,
|
||||
HLSL_TEXTURE_2D_UINT4,
|
||||
HLSL_TEXTURE_3D_UINT4,
|
||||
HLSL_TEXTURE_2D_ARRAY_UINT4,
|
||||
|
||||
// Comparison samplers
|
||||
|
||||
HLSL_TEXTURE_2D_COMPARISON,
|
||||
HLSL_TEXTURE_CUBE_COMPARISON,
|
||||
HLSL_TEXTURE_2D_ARRAY_COMPARISON,
|
||||
|
||||
HLSL_COMPARISON_SAMPLER_GROUP_BEGIN = HLSL_TEXTURE_2D_COMPARISON,
|
||||
HLSL_COMPARISON_SAMPLER_GROUP_END = HLSL_TEXTURE_2D_ARRAY_COMPARISON,
|
||||
|
||||
HLSL_TEXTURE_UNKNOWN,
|
||||
HLSL_TEXTURE_MAX = HLSL_TEXTURE_UNKNOWN
|
||||
};
|
||||
|
||||
HLSLTextureSamplerGroup TextureGroup(const TBasicType type);
|
||||
TString TextureString(const HLSLTextureSamplerGroup type);
|
||||
TString TextureString(const TBasicType type);
|
||||
TString TextureGroupSuffix(const HLSLTextureSamplerGroup type);
|
||||
TString TextureGroupSuffix(const TBasicType type);
|
||||
TString TextureTypeSuffix(const TBasicType type);
|
||||
TString SamplerString(const TBasicType type);
|
||||
TString SamplerString(HLSLTextureSamplerGroup type);
|
||||
// Prepends an underscore to avoid naming clashes
|
||||
TString Decorate(const TString &string);
|
||||
TString DecorateIfNeeded(const TName &name);
|
||||
|
@ -36,7 +72,7 @@ TString QualifiedStructNameString(const TStructure &structure, bool useHLSLRowMa
|
|||
bool useStd140Packing);
|
||||
TString InterpolationString(TQualifier qualifier);
|
||||
TString QualifierString(TQualifier qualifier);
|
||||
|
||||
int HLSLTextureCoordsCount(const TBasicType samplerType);
|
||||
}
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_UTILSHLSL_H_
|
||||
|
|
|
@ -16,18 +16,6 @@ namespace sh
|
|||
namespace
|
||||
{
|
||||
|
||||
TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
|
||||
{
|
||||
if (interfaceBlock.hasInstanceName())
|
||||
{
|
||||
return interfaceBlock.name() + "." + field.name();
|
||||
}
|
||||
else
|
||||
{
|
||||
return field.name();
|
||||
}
|
||||
}
|
||||
|
||||
BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
|
||||
{
|
||||
switch (blockStorage)
|
||||
|
@ -559,16 +547,12 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable,
|
|||
interfaceBlock.layout = GetBlockLayoutType(blockType->blockStorage());
|
||||
|
||||
// Gather field information
|
||||
const TFieldList &fieldList = blockType->fields();
|
||||
|
||||
for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
|
||||
for (const TField *field : blockType->fields())
|
||||
{
|
||||
const TField &field = *fieldList[fieldIndex];
|
||||
const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
|
||||
const TType &fieldType = *field.type();
|
||||
const TType &fieldType = *field->type();
|
||||
|
||||
NameHashingTraverser traverser(mHashFunction, mSymbolTable);
|
||||
traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
|
||||
traverser.traverse(fieldType, field->name(), &interfaceBlock.fields);
|
||||
|
||||
interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
|
||||
}
|
||||
|
|
|
@ -55,8 +55,6 @@ class COMPILER_EXPORT BlockLayoutEncoder
|
|||
BlockMemberInfo encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
|
||||
|
||||
size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
|
||||
size_t getCurrentRegister() const { return mCurrentOffset / ComponentsPerRegister; }
|
||||
size_t getCurrentElement() const { return mCurrentOffset % ComponentsPerRegister; }
|
||||
|
||||
virtual void enterAggregateType() = 0;
|
||||
virtual void exitAggregateType() = 0;
|
||||
|
|
|
@ -113,9 +113,14 @@ HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(ShSh
|
|||
{
|
||||
switch (outputType)
|
||||
{
|
||||
case SH_HLSL9_OUTPUT: return ENCODE_LOOSE;
|
||||
case SH_HLSL11_OUTPUT: return ENCODE_PACKED;
|
||||
default: UNREACHABLE(); return ENCODE_PACKED;
|
||||
case SH_HLSL_3_0_OUTPUT:
|
||||
return ENCODE_LOOSE;
|
||||
case SH_HLSL_4_1_OUTPUT:
|
||||
case SH_HLSL_4_0_FL9_3_OUTPUT:
|
||||
return ENCODE_PACKED;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return ENCODE_PACKED;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,27 +142,11 @@ class TDependencyGraph {
|
|||
public:
|
||||
TDependencyGraph(TIntermNode* intermNode);
|
||||
~TDependencyGraph();
|
||||
TGraphNodeVector::const_iterator begin() const { return mAllNodes.begin(); }
|
||||
TGraphNodeVector::const_iterator end() const { return mAllNodes.end(); }
|
||||
|
||||
TGraphSymbolVector::const_iterator beginSamplerSymbols() const
|
||||
const TGraphNodeVector &allNodes() const { return mAllNodes; }
|
||||
const TGraphSymbolVector &samplerSymbols() const { return mSamplerSymbols; }
|
||||
const TFunctionCallVector &userDefinedFunctionCalls() const
|
||||
{
|
||||
return mSamplerSymbols.begin();
|
||||
}
|
||||
|
||||
TGraphSymbolVector::const_iterator endSamplerSymbols() const
|
||||
{
|
||||
return mSamplerSymbols.end();
|
||||
}
|
||||
|
||||
TFunctionCallVector::const_iterator beginUserDefinedFunctionCalls() const
|
||||
{
|
||||
return mUserDefinedFunctionCalls.begin();
|
||||
}
|
||||
|
||||
TFunctionCallVector::const_iterator endUserDefinedFunctionCalls() const
|
||||
{
|
||||
return mUserDefinedFunctionCalls.end();
|
||||
return mUserDefinedFunctionCalls;
|
||||
}
|
||||
|
||||
TGraphArgument* createArgument(TIntermAggregate* intermFunctionCall, int argumentNumber);
|
||||
|
|
|
@ -54,9 +54,8 @@ void TDependencyGraphOutput::outputAllSpanningTrees(TDependencyGraph& graph)
|
|||
{
|
||||
mSink << "\n";
|
||||
|
||||
for (TGraphNodeVector::const_iterator iter = graph.begin(); iter != graph.end(); ++iter)
|
||||
for (auto symbol : graph.allNodes())
|
||||
{
|
||||
TGraphNode* symbol = *iter;
|
||||
mSink << "--- Dependency graph spanning tree ---\n";
|
||||
clearVisited();
|
||||
symbol->traverse(this);
|
||||
|
|
|
@ -7,22 +7,23 @@
|
|||
|
||||
run_flex()
|
||||
{
|
||||
input_file=$script_dir/$1.l
|
||||
output_source=$script_dir/$1_lex.cpp
|
||||
input_file=./$1.l
|
||||
output_source=./$1_lex.cpp
|
||||
flex --noline --nounistd --outfile=$output_source $input_file
|
||||
}
|
||||
|
||||
run_bison()
|
||||
{
|
||||
input_file=$script_dir/$1.y
|
||||
output_header=$script_dir/$1_tab.h
|
||||
output_source=$script_dir/$1_tab.cpp
|
||||
input_file=./$1.y
|
||||
output_header=./$1_tab.h
|
||||
output_source=./$1_tab.cpp
|
||||
bison --no-lines --skeleton=yacc.c --defines=$output_header --output=$output_source $input_file
|
||||
}
|
||||
|
||||
script_dir=$(dirname $0)
|
||||
|
||||
# Generate Parser
|
||||
cd $script_dir
|
||||
run_flex glslang
|
||||
run_bison glslang
|
||||
patch --silent --forward < 64bit-lexer-safety.patch
|
||||
|
|
|
@ -178,10 +178,10 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
|
|||
|
||||
%type <interm.intermNode> translation_unit function_definition
|
||||
%type <interm.intermNode> statement simple_statement
|
||||
%type <interm.intermAggregate> statement_list compound_statement
|
||||
%type <interm.intermAggregate> statement_list compound_statement compound_statement_no_new_scope
|
||||
%type <interm.intermNode> declaration_statement selection_statement expression_statement
|
||||
%type <interm.intermNode> declaration external_declaration
|
||||
%type <interm.intermNode> for_init_statement compound_statement_no_new_scope
|
||||
%type <interm.intermNode> for_init_statement
|
||||
%type <interm.nodePair> selection_rest_statement for_rest_statement
|
||||
%type <interm.intermSwitch> switch_statement
|
||||
%type <interm.intermCase> case_label
|
||||
|
@ -580,33 +580,8 @@ enter_struct
|
|||
;
|
||||
|
||||
declaration
|
||||
: function_prototype SEMICOLON {
|
||||
TFunction &function = *($1.function);
|
||||
|
||||
TIntermAggregate *prototype = new TIntermAggregate;
|
||||
prototype->setType(function.getReturnType());
|
||||
prototype->setName(function.getMangledName());
|
||||
prototype->setFunctionId(function.getUniqueId());
|
||||
|
||||
for (size_t i = 0; i < function.getParamCount(); i++)
|
||||
{
|
||||
const TConstParameter ¶m = function.getParam(i);
|
||||
if (param.name != 0)
|
||||
{
|
||||
TVariable variable(param.name, *param.type);
|
||||
|
||||
prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), @1), @1);
|
||||
}
|
||||
else
|
||||
{
|
||||
prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, @1), @1);
|
||||
}
|
||||
}
|
||||
|
||||
prototype->setOp(EOpPrototype);
|
||||
$$ = prototype;
|
||||
|
||||
context->symbolTable.pop();
|
||||
: function_prototype SEMICOLON {
|
||||
$$ = context->addFunctionPrototypeDeclaration(*($1.function), @1);
|
||||
}
|
||||
| init_declarator_list SEMICOLON {
|
||||
TIntermAggregate *aggNode = $1.intermAggregate;
|
||||
|
@ -1599,20 +1574,7 @@ function_definition
|
|||
context->parseFunctionPrototype(@1, $1.function, &$1.intermAggregate);
|
||||
}
|
||||
compound_statement_no_new_scope {
|
||||
//?? Check that all paths return a value if return type != void ?
|
||||
// May be best done as post process phase on intermediate code
|
||||
if (context->getCurrentFunctionType()->getBasicType() != EbtVoid && !context->getFunctionReturnsValue()) {
|
||||
context->error(@1, "function does not return a value:", "", $1.function->getName().c_str());
|
||||
context->recover();
|
||||
}
|
||||
|
||||
$$ = context->intermediate.growAggregate($1.intermAggregate, $3, @$);
|
||||
context->intermediate.setAggregateOperator($$, EOpFunction, @1);
|
||||
$$->getAsAggregate()->setName($1.function->getMangledName().c_str());
|
||||
$$->getAsAggregate()->setType($1.function->getReturnType());
|
||||
$$->getAsAggregate()->setFunctionId($1.function->getUniqueId());
|
||||
|
||||
context->symbolTable.pop();
|
||||
$$ = context->addFunctionDefinition(*($1.function), $1.intermAggregate, $3, @1);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -702,26 +702,26 @@ static const yytype_uint16 yyrline[] =
|
|||
440, 443, 446, 449, 455, 456, 459, 465, 466, 473,
|
||||
474, 481, 482, 489, 490, 496, 497, 503, 504, 510,
|
||||
511, 517, 518, 526, 527, 528, 529, 533, 534, 535,
|
||||
539, 543, 547, 551, 558, 561, 567, 575, 583, 611,
|
||||
617, 628, 632, 636, 640, 647, 653, 656, 663, 671,
|
||||
692, 719, 729, 757, 762, 772, 777, 787, 790, 793,
|
||||
796, 802, 809, 812, 816, 820, 825, 830, 837, 841,
|
||||
845, 849, 854, 859, 863, 870, 880, 886, 889, 895,
|
||||
901, 908, 917, 927, 935, 938, 945, 949, 953, 958,
|
||||
966, 969, 973, 977, 986, 995, 1003, 1013, 1025, 1028,
|
||||
1031, 1037, 1044, 1047, 1053, 1056, 1059, 1065, 1068, 1073,
|
||||
1088, 1092, 1096, 1100, 1104, 1108, 1113, 1118, 1123, 1128,
|
||||
1133, 1138, 1143, 1148, 1153, 1158, 1163, 1168, 1173, 1178,
|
||||
1183, 1188, 1193, 1198, 1203, 1208, 1213, 1217, 1221, 1225,
|
||||
1229, 1233, 1237, 1241, 1245, 1249, 1253, 1257, 1261, 1265,
|
||||
1269, 1273, 1281, 1289, 1293, 1306, 1306, 1309, 1309, 1315,
|
||||
1318, 1334, 1337, 1346, 1350, 1356, 1363, 1378, 1382, 1386,
|
||||
1387, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1403, 1404,
|
||||
1404, 1404, 1414, 1415, 1419, 1419, 1420, 1420, 1425, 1428,
|
||||
1438, 1441, 1447, 1448, 1452, 1460, 1464, 1471, 1471, 1478,
|
||||
1481, 1488, 1493, 1508, 1508, 1513, 1513, 1520, 1520, 1528,
|
||||
1531, 1537, 1540, 1546, 1550, 1557, 1560, 1563, 1566, 1569,
|
||||
1578, 1582, 1589, 1592, 1598, 1598
|
||||
539, 543, 547, 551, 558, 561, 567, 575, 583, 586,
|
||||
592, 603, 607, 611, 615, 622, 628, 631, 638, 646,
|
||||
667, 694, 704, 732, 737, 747, 752, 762, 765, 768,
|
||||
771, 777, 784, 787, 791, 795, 800, 805, 812, 816,
|
||||
820, 824, 829, 834, 838, 845, 855, 861, 864, 870,
|
||||
876, 883, 892, 902, 910, 913, 920, 924, 928, 933,
|
||||
941, 944, 948, 952, 961, 970, 978, 988, 1000, 1003,
|
||||
1006, 1012, 1019, 1022, 1028, 1031, 1034, 1040, 1043, 1048,
|
||||
1063, 1067, 1071, 1075, 1079, 1083, 1088, 1093, 1098, 1103,
|
||||
1108, 1113, 1118, 1123, 1128, 1133, 1138, 1143, 1148, 1153,
|
||||
1158, 1163, 1168, 1173, 1178, 1183, 1188, 1192, 1196, 1200,
|
||||
1204, 1208, 1212, 1216, 1220, 1224, 1228, 1232, 1236, 1240,
|
||||
1244, 1248, 1256, 1264, 1268, 1281, 1281, 1284, 1284, 1290,
|
||||
1293, 1309, 1312, 1321, 1325, 1331, 1338, 1353, 1357, 1361,
|
||||
1362, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1378, 1379,
|
||||
1379, 1379, 1389, 1390, 1394, 1394, 1395, 1395, 1400, 1403,
|
||||
1413, 1416, 1422, 1423, 1427, 1435, 1439, 1446, 1446, 1453,
|
||||
1456, 1463, 1468, 1483, 1483, 1488, 1488, 1495, 1495, 1503,
|
||||
1506, 1512, 1515, 1521, 1525, 1532, 1535, 1538, 1541, 1544,
|
||||
1553, 1557, 1564, 1567, 1573, 1573
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -3048,32 +3048,7 @@ yyreduce:
|
|||
case 88:
|
||||
|
||||
{
|
||||
TFunction &function = *((yyvsp[-1].interm).function);
|
||||
|
||||
TIntermAggregate *prototype = new TIntermAggregate;
|
||||
prototype->setType(function.getReturnType());
|
||||
prototype->setName(function.getMangledName());
|
||||
prototype->setFunctionId(function.getUniqueId());
|
||||
|
||||
for (size_t i = 0; i < function.getParamCount(); i++)
|
||||
{
|
||||
const TConstParameter ¶m = function.getParam(i);
|
||||
if (param.name != 0)
|
||||
{
|
||||
TVariable variable(param.name, *param.type);
|
||||
|
||||
prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), (yylsp[-1])), (yylsp[-1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, (yylsp[-1])), (yylsp[-1]));
|
||||
}
|
||||
}
|
||||
|
||||
prototype->setOp(EOpPrototype);
|
||||
(yyval.interm.intermNode) = prototype;
|
||||
|
||||
context->symbolTable.pop();
|
||||
(yyval.interm.intermNode) = context->addFunctionPrototypeDeclaration(*((yyvsp[-1].interm).function), (yylsp[-1]));
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -4488,7 +4463,7 @@ yyreduce:
|
|||
|
||||
case 232:
|
||||
|
||||
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
|
||||
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
|
||||
|
||||
break;
|
||||
|
||||
|
@ -4506,7 +4481,7 @@ yyreduce:
|
|||
|
||||
case 235:
|
||||
|
||||
{ context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
|
||||
{ context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
|
||||
|
||||
break;
|
||||
|
||||
|
@ -4525,7 +4500,7 @@ yyreduce:
|
|||
case 238:
|
||||
|
||||
{
|
||||
(yyval.interm.intermNode) = 0;
|
||||
(yyval.interm.intermAggregate) = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -4537,7 +4512,7 @@ yyreduce:
|
|||
(yyvsp[-1].interm.intermAggregate)->setOp(EOpSequence);
|
||||
(yyvsp[-1].interm.intermAggregate)->setLine((yyloc));
|
||||
}
|
||||
(yyval.interm.intermNode) = (yyvsp[-1].interm.intermAggregate);
|
||||
(yyval.interm.intermAggregate) = (yyvsp[-1].interm.intermAggregate);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -4842,20 +4817,7 @@ yyreduce:
|
|||
case 275:
|
||||
|
||||
{
|
||||
//?? Check that all paths return a value if return type != void ?
|
||||
// May be best done as post process phase on intermediate code
|
||||
if (context->getCurrentFunctionType()->getBasicType() != EbtVoid && !context->getFunctionReturnsValue()) {
|
||||
context->error((yylsp[-2]), "function does not return a value:", "", (yyvsp[-2].interm).function->getName().c_str());
|
||||
context->recover();
|
||||
}
|
||||
|
||||
(yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermNode), (yyloc));
|
||||
context->intermediate.setAggregateOperator((yyval.interm.intermNode), EOpFunction, (yylsp[-2]));
|
||||
(yyval.interm.intermNode)->getAsAggregate()->setName((yyvsp[-2].interm).function->getMangledName().c_str());
|
||||
(yyval.interm.intermNode)->getAsAggregate()->setType((yyvsp[-2].interm).function->getReturnType());
|
||||
(yyval.interm.intermNode)->getAsAggregate()->setFunctionId((yyvsp[-2].interm).function->getUniqueId());
|
||||
|
||||
context->symbolTable.pop();
|
||||
(yyval.interm.intermNode) = context->addFunctionDefinition(*((yyvsp[-2].interm).function), (yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermAggregate), (yylsp[-2]));
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -54,11 +54,8 @@ void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph& g
|
|||
|
||||
// Starting from each sampler, traverse the dependency graph and generate an error each time we
|
||||
// hit a node where sampler dependent values are not allowed.
|
||||
for (TGraphSymbolVector::const_iterator iter = graph.beginSamplerSymbols();
|
||||
iter != graph.endSamplerSymbols();
|
||||
++iter)
|
||||
for (auto samplerSymbol : graph.samplerSymbols())
|
||||
{
|
||||
TGraphSymbol* samplerSymbol = *iter;
|
||||
clearVisited();
|
||||
samplerSymbol->traverse(this);
|
||||
}
|
||||
|
@ -66,11 +63,8 @@ void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph& g
|
|||
|
||||
void RestrictFragmentShaderTiming::validateUserDefinedFunctionCallUsage(const TDependencyGraph& graph)
|
||||
{
|
||||
for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
|
||||
iter != graph.endUserDefinedFunctionCalls();
|
||||
++iter)
|
||||
for (const auto* functionCall : graph.userDefinedFunctionCalls())
|
||||
{
|
||||
TGraphFunctionCall* functionCall = *iter;
|
||||
beginError(functionCall->getIntermFunctionCall());
|
||||
mSink << "A call to a user defined function is not permitted.\n";
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace gl
|
|||
Buffer::Buffer(rx::BufferImpl *impl, GLuint id)
|
||||
: RefCountObject(id),
|
||||
mBuffer(impl),
|
||||
mLabel(),
|
||||
mUsage(GL_STATIC_DRAW),
|
||||
mSize(0),
|
||||
mAccessFlags(0),
|
||||
|
@ -34,6 +35,16 @@ Buffer::~Buffer()
|
|||
SafeDelete(mBuffer);
|
||||
}
|
||||
|
||||
void Buffer::setLabel(const std::string &label)
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &Buffer::getLabel() const
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
|
||||
{
|
||||
gl::Error error = mBuffer->setData(data, size, usage);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define LIBANGLE_BUFFER_H_
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/Error.h"
|
||||
#include "libANGLE/IndexRangeCache.h"
|
||||
#include "libANGLE/RefCountObject.h"
|
||||
|
@ -24,13 +25,15 @@ class BufferImpl;
|
|||
namespace gl
|
||||
{
|
||||
|
||||
class Buffer : public RefCountObject
|
||||
class Buffer final : public RefCountObject, public LabeledObject
|
||||
{
|
||||
public:
|
||||
Buffer(rx::BufferImpl *impl, GLuint id);
|
||||
|
||||
virtual ~Buffer();
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
Error bufferData(const void *data, GLsizeiptr size, GLenum usage);
|
||||
Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
|
||||
Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
|
||||
|
@ -61,6 +64,8 @@ class Buffer : public RefCountObject
|
|||
private:
|
||||
rx::BufferImpl *mBuffer;
|
||||
|
||||
std::string mLabel;
|
||||
|
||||
GLenum mUsage;
|
||||
GLint64 mSize;
|
||||
GLbitfield mAccessFlags;
|
||||
|
|
|
@ -102,6 +102,7 @@ Extensions::Extensions()
|
|||
pixelBufferObject(false),
|
||||
mapBuffer(false),
|
||||
mapBufferRange(false),
|
||||
colorBufferHalfFloat(false),
|
||||
textureHalfFloat(false),
|
||||
textureHalfFloatLinear(false),
|
||||
textureFloat(false),
|
||||
|
@ -123,6 +124,9 @@ Extensions::Extensions()
|
|||
occlusionQueryBoolean(false),
|
||||
fence(false),
|
||||
timerQuery(false),
|
||||
disjointTimerQuery(false),
|
||||
queryCounterBitsTimeElapsed(0),
|
||||
queryCounterBitsTimestamp(0),
|
||||
robustness(false),
|
||||
blendMinMax(false),
|
||||
framebufferBlit(false),
|
||||
|
@ -146,6 +150,13 @@ Extensions::Extensions()
|
|||
unpackSubimage(false),
|
||||
packSubimage(false),
|
||||
vertexArrayObject(false),
|
||||
debug(false),
|
||||
maxDebugMessageLength(0),
|
||||
maxDebugLoggedMessages(0),
|
||||
maxDebugGroupStackDepth(0),
|
||||
maxLabelLength(0),
|
||||
noError(false),
|
||||
lossyETCDecode(false),
|
||||
colorBufferFloat(false)
|
||||
{
|
||||
}
|
||||
|
@ -165,6 +176,7 @@ std::vector<std::string> Extensions::getStrings() const
|
|||
InsertExtensionString("GL_NV_pixel_buffer_object", pixelBufferObject, &extensionStrings);
|
||||
InsertExtensionString("GL_OES_mapbuffer", mapBuffer, &extensionStrings);
|
||||
InsertExtensionString("GL_EXT_map_buffer_range", mapBufferRange, &extensionStrings);
|
||||
InsertExtensionString("GL_EXT_color_buffer_half_float", colorBufferHalfFloat, &extensionStrings);
|
||||
InsertExtensionString("GL_OES_texture_half_float", textureHalfFloat, &extensionStrings);
|
||||
InsertExtensionString("GL_OES_texture_half_float_linear", textureHalfFloatLinear, &extensionStrings);
|
||||
InsertExtensionString("GL_OES_texture_float", textureFloat, &extensionStrings);
|
||||
|
@ -186,6 +198,7 @@ std::vector<std::string> Extensions::getStrings() const
|
|||
InsertExtensionString("GL_EXT_occlusion_query_boolean", occlusionQueryBoolean, &extensionStrings);
|
||||
InsertExtensionString("GL_NV_fence", fence, &extensionStrings);
|
||||
InsertExtensionString("GL_ANGLE_timer_query", timerQuery, &extensionStrings);
|
||||
InsertExtensionString("GL_EXT_disjoint_timer_query", disjointTimerQuery, &extensionStrings);
|
||||
InsertExtensionString("GL_EXT_robustness", robustness, &extensionStrings);
|
||||
InsertExtensionString("GL_EXT_blend_minmax", blendMinMax, &extensionStrings);
|
||||
InsertExtensionString("GL_ANGLE_framebuffer_blit", framebufferBlit, &extensionStrings);
|
||||
|
@ -210,6 +223,11 @@ std::vector<std::string> Extensions::getStrings() const
|
|||
InsertExtensionString("GL_NV_pack_subimage", packSubimage, &extensionStrings);
|
||||
InsertExtensionString("GL_EXT_color_buffer_float", colorBufferFloat, &extensionStrings);
|
||||
InsertExtensionString("GL_OES_vertex_array_object", vertexArrayObject, &extensionStrings);
|
||||
InsertExtensionString("GL_KHR_debug", debug, &extensionStrings);
|
||||
// TODO(jmadill): Enable this when complete.
|
||||
//InsertExtensionString("GL_KHR_no_error", noError, &extensionStrings);
|
||||
|
||||
InsertExtensionString("GL_ANGLE_lossy_etc_decode", lossyETCDecode, &extensionStrings);
|
||||
// clang-format on
|
||||
|
||||
return extensionStrings;
|
||||
|
@ -279,6 +297,18 @@ static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps)
|
|||
return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
|
||||
}
|
||||
|
||||
// Checks for GL_OES_color_buffer_half_float support
|
||||
static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCaps)
|
||||
{
|
||||
std::vector<GLenum> requiredFormats;
|
||||
requiredFormats.push_back(GL_RGBA16F);
|
||||
requiredFormats.push_back(GL_RGB16F);
|
||||
requiredFormats.push_back(GL_RG16F);
|
||||
requiredFormats.push_back(GL_R16F);
|
||||
|
||||
return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
|
||||
}
|
||||
|
||||
// Checks for GL_OES_texture_half_float support
|
||||
static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
|
||||
{
|
||||
|
@ -296,7 +326,8 @@ static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &text
|
|||
requiredFormats.push_back(GL_RGB16F);
|
||||
requiredFormats.push_back(GL_RGBA16F);
|
||||
|
||||
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
|
||||
return DetermineHalfFloatTextureSupport(textureCaps) &&
|
||||
GetFormatSupport(textureCaps, requiredFormats, true, true, false);
|
||||
}
|
||||
|
||||
// Checks for GL_OES_texture_float support
|
||||
|
@ -316,7 +347,8 @@ static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureC
|
|||
requiredFormats.push_back(GL_RGB32F);
|
||||
requiredFormats.push_back(GL_RGBA32F);
|
||||
|
||||
return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
|
||||
return DetermineFloatTextureSupport(textureCaps) &&
|
||||
GetFormatSupport(textureCaps, requiredFormats, true, true, false);
|
||||
}
|
||||
|
||||
// Checks for GL_EXT_texture_rg support
|
||||
|
@ -466,6 +498,7 @@ void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
|
|||
packedDepthStencil = DeterminePackedDepthStencilSupport(textureCaps);
|
||||
rgb8rgba8 = DetermineRGB8AndRGBA8TextureSupport(textureCaps);
|
||||
textureFormatBGRA8888 = DetermineBGRA8TextureSupport(textureCaps);
|
||||
colorBufferHalfFloat = DetermineColorBufferHalfFloatSupport(textureCaps);
|
||||
textureHalfFloat = DetermineHalfFloatTextureSupport(textureCaps);
|
||||
textureHalfFloatLinear = DetermineHalfFloatTextureFilteringSupport(textureCaps);
|
||||
textureFloat = DetermineFloatTextureSupport(textureCaps);
|
||||
|
@ -588,6 +621,7 @@ DisplayExtensions::DisplayExtensions()
|
|||
querySurfacePointer(false),
|
||||
windowFixedSize(false),
|
||||
keyedMutex(false),
|
||||
surfaceOrientation(false),
|
||||
postSubBuffer(false),
|
||||
createContext(false),
|
||||
deviceQuery(false),
|
||||
|
@ -598,7 +632,10 @@ DisplayExtensions::DisplayExtensions()
|
|||
glTextureCubemapImage(false),
|
||||
glTexture3DImage(false),
|
||||
glRenderbufferImage(false),
|
||||
getAllProcAddresses(false)
|
||||
getAllProcAddresses(false),
|
||||
flexibleSurfaceCompatibility(false),
|
||||
directComposition(false),
|
||||
createContextNoError(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -614,6 +651,8 @@ std::vector<std::string> DisplayExtensions::getStrings() const
|
|||
InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANGLE_surface_orientation", surfaceOrientation, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANGLE_direct_composition", directComposition, &extensionStrings);
|
||||
InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings);
|
||||
InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings);
|
||||
InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings);
|
||||
|
@ -625,6 +664,9 @@ std::vector<std::string> DisplayExtensions::getStrings() const
|
|||
InsertExtensionString("EGL_KHR_gl_texture_3D_image", glTexture3DImage, &extensionStrings);
|
||||
InsertExtensionString("EGL_KHR_gl_renderbuffer_image", glRenderbufferImage, &extensionStrings);
|
||||
InsertExtensionString("EGL_KHR_get_all_proc_addresses", getAllProcAddresses, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility", flexibleSurfaceCompatibility, &extensionStrings);
|
||||
// TODO(jmadill): Enable this when complete.
|
||||
//InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
|
||||
// clang-format on
|
||||
|
||||
return extensionStrings;
|
||||
|
@ -655,6 +697,7 @@ ClientExtensions::ClientExtensions()
|
|||
deviceCreation(false),
|
||||
deviceCreationD3D11(false),
|
||||
x11Visual(false),
|
||||
experimentalPresentPath(false),
|
||||
clientGetAllProcAddresses(false)
|
||||
{
|
||||
}
|
||||
|
@ -674,6 +717,7 @@ std::vector<std::string> ClientExtensions::getStrings() const
|
|||
InsertExtensionString("EGL_ANGLE_device_creation", deviceCreation, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANGLE_device_creation_d3d11", deviceCreationD3D11, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANGLE_x11_visual", x11Visual, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANGLE_experimental_present_path", experimentalPresentPath, &extensionStrings);
|
||||
InsertExtensionString("EGL_KHR_client_get_all_proc_addresses", clientGetAllProcAddresses, &extensionStrings);
|
||||
// clang-format on
|
||||
|
||||
|
|
|
@ -76,10 +76,12 @@ struct Extensions
|
|||
// GL_OES_packed_depth_stencil
|
||||
// GL_OES_rgb8_rgba8
|
||||
// GL_EXT_texture_format_BGRA8888
|
||||
// GL_EXT_color_buffer_half_float,
|
||||
// GL_OES_texture_half_float, GL_OES_texture_half_float_linear
|
||||
// GL_OES_texture_float, GL_OES_texture_float_linear
|
||||
// GL_EXT_texture_rg
|
||||
// GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3, GL_ANGLE_texture_compression_dxt5
|
||||
// GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3,
|
||||
// GL_ANGLE_texture_compression_dxt5
|
||||
// GL_KHR_texture_compression_astc_hdr, GL_KHR_texture_compression_astc_ldr
|
||||
// GL_OES_compressed_ETC1_RGB8_texture
|
||||
// GL_EXT_sRGB
|
||||
|
@ -116,6 +118,11 @@ struct Extensions
|
|||
bool mapBuffer;
|
||||
bool mapBufferRange;
|
||||
|
||||
// GL_EXT_color_buffer_half_float
|
||||
// Together with GL_OES_texture_half_float in a GLES 2.0 context, implies that half-float
|
||||
// textures are renderable.
|
||||
bool colorBufferHalfFloat;
|
||||
|
||||
// GL_OES_texture_half_float and GL_OES_texture_half_float_linear
|
||||
// Implies that TextureCaps for GL_RGB16F, GL_RGBA16F, GL_ALPHA32F_EXT, GL_LUMINANCE32F_EXT and
|
||||
// GL_LUMINANCE_ALPHA32F_EXT exist
|
||||
|
@ -184,6 +191,11 @@ struct Extensions
|
|||
// GL_ANGLE_timer_query
|
||||
bool timerQuery;
|
||||
|
||||
// GL_EXT_disjoint_timer_query
|
||||
bool disjointTimerQuery;
|
||||
GLuint queryCounterBitsTimeElapsed;
|
||||
GLuint queryCounterBitsTimestamp;
|
||||
|
||||
// GL_EXT_robustness
|
||||
bool robustness;
|
||||
|
||||
|
@ -253,6 +265,19 @@ struct Extensions
|
|||
// GL_OES_vertex_array_object
|
||||
bool vertexArrayObject;
|
||||
|
||||
// GL_KHR_debug
|
||||
bool debug;
|
||||
GLuint maxDebugMessageLength;
|
||||
GLuint maxDebugLoggedMessages;
|
||||
GLuint maxDebugGroupStackDepth;
|
||||
GLuint maxLabelLength;
|
||||
|
||||
// KHR_no_error
|
||||
bool noError;
|
||||
|
||||
// GL_ANGLE_lossy_etc_decode
|
||||
bool lossyETCDecode;
|
||||
|
||||
// ES3 Extension support
|
||||
|
||||
// GL_EXT_color_buffer_float
|
||||
|
@ -413,6 +438,9 @@ struct DisplayExtensions
|
|||
// EGL_ANGLE_keyed_mutex
|
||||
bool keyedMutex;
|
||||
|
||||
// EGL_ANGLE_surface_orientation
|
||||
bool surfaceOrientation;
|
||||
|
||||
// EGL_NV_post_sub_buffer
|
||||
bool postSubBuffer;
|
||||
|
||||
|
@ -445,6 +473,15 @@ struct DisplayExtensions
|
|||
|
||||
// EGL_KHR_get_all_proc_addresses
|
||||
bool getAllProcAddresses;
|
||||
|
||||
// EGL_ANGLE_flexible_surface_compatibility
|
||||
bool flexibleSurfaceCompatibility;
|
||||
|
||||
// EGL_ANGLE_direct_composition
|
||||
bool directComposition;
|
||||
|
||||
// KHR_create_context_no_error
|
||||
bool createContextNoError;
|
||||
};
|
||||
|
||||
struct DeviceExtensions
|
||||
|
@ -492,6 +529,9 @@ struct ClientExtensions
|
|||
// EGL_ANGLE_x11_visual
|
||||
bool x11Visual;
|
||||
|
||||
// EGL_ANGLE_experimental_present_path
|
||||
bool experimentalPresentPath;
|
||||
|
||||
// EGL_KHR_client_get_all_proc_addresses
|
||||
bool clientGetAllProcAddresses;
|
||||
};
|
||||
|
|
|
@ -57,7 +57,8 @@ Config::Config()
|
|||
transparentType(EGL_NONE),
|
||||
transparentRedValue(0),
|
||||
transparentGreenValue(0),
|
||||
transparentBlueValue(0)
|
||||
transparentBlueValue(0),
|
||||
optimalOrientation(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -251,6 +252,9 @@ std::vector<const Config*> ConfigSet::filter(const AttributeMap &attributeMap) c
|
|||
case EGL_MAX_PBUFFER_WIDTH: match = config.maxPBufferWidth >= attributeValue; break;
|
||||
case EGL_MAX_PBUFFER_HEIGHT: match = config.maxPBufferHeight >= attributeValue; break;
|
||||
case EGL_MAX_PBUFFER_PIXELS: match = config.maxPBufferPixels >= attributeValue; break;
|
||||
case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
|
||||
match = config.optimalOrientation == attributeValue;
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ struct Config
|
|||
EGLint transparentRedValue; // Transparent red value
|
||||
EGLint transparentGreenValue; // Transparent green value
|
||||
EGLint transparentBlueValue; // Transparent blue value
|
||||
EGLint optimalOrientation; // Optimal window surface orientation
|
||||
};
|
||||
|
||||
class ConfigSet
|
||||
|
|
|
@ -36,6 +36,32 @@
|
|||
namespace
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
|
||||
{
|
||||
gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
|
||||
ASSERT(queryObject != nullptr);
|
||||
|
||||
switch (pname)
|
||||
{
|
||||
case GL_QUERY_RESULT_EXT:
|
||||
return queryObject->getResult(params);
|
||||
case GL_QUERY_RESULT_AVAILABLE_EXT:
|
||||
{
|
||||
bool available;
|
||||
gl::Error error = queryObject->isResultAvailable(&available);
|
||||
if (!error.isError())
|
||||
{
|
||||
*params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
|
||||
}
|
||||
}
|
||||
|
||||
void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
|
||||
{
|
||||
if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
|
||||
|
@ -52,36 +78,79 @@ void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attribute map queries.
|
||||
EGLint GetClientVersion(const egl::AttributeMap &attribs)
|
||||
{
|
||||
return attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1);
|
||||
}
|
||||
|
||||
GLenum GetResetStrategy(const egl::AttributeMap &attribs)
|
||||
{
|
||||
EGLenum attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
|
||||
EGL_NO_RESET_NOTIFICATION_EXT);
|
||||
switch (attrib)
|
||||
{
|
||||
case EGL_NO_RESET_NOTIFICATION:
|
||||
return GL_NO_RESET_NOTIFICATION_EXT;
|
||||
case EGL_LOSE_CONTEXT_ON_RESET:
|
||||
return GL_LOSE_CONTEXT_ON_RESET_EXT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return GL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
bool GetRobustAccess(const egl::AttributeMap &attribs)
|
||||
{
|
||||
return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
|
||||
}
|
||||
|
||||
bool GetDebug(const egl::AttributeMap &attribs)
|
||||
{
|
||||
return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
|
||||
}
|
||||
|
||||
bool GetNoError(const egl::AttributeMap &attribs)
|
||||
{
|
||||
return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
Context::Context(const egl::Config *config,
|
||||
int clientVersion,
|
||||
const Context *shareContext,
|
||||
rx::Renderer *renderer,
|
||||
bool notifyResets,
|
||||
bool robustAccess)
|
||||
: ValidationContext(clientVersion,
|
||||
const egl::AttributeMap &attribs)
|
||||
: ValidationContext(GetClientVersion(attribs),
|
||||
mState,
|
||||
mCaps,
|
||||
mTextureCaps,
|
||||
mExtensions,
|
||||
nullptr,
|
||||
mLimitations),
|
||||
mLimitations,
|
||||
GetNoError(attribs)),
|
||||
mCompiler(nullptr),
|
||||
mRenderer(renderer),
|
||||
mClientVersion(GetClientVersion(attribs)),
|
||||
mConfig(config),
|
||||
mCurrentSurface(nullptr)
|
||||
mClientType(EGL_OPENGL_ES_API),
|
||||
mHasBeenCurrent(false),
|
||||
mContextLost(false),
|
||||
mResetStatus(GL_NO_ERROR),
|
||||
mResetStrategy(GetResetStrategy(attribs)),
|
||||
mRobustAccess(GetRobustAccess(attribs)),
|
||||
mCurrentSurface(nullptr),
|
||||
mResourceManager(nullptr)
|
||||
{
|
||||
ASSERT(robustAccess == false); // Unimplemented
|
||||
ASSERT(!mRobustAccess); // Unimplemented
|
||||
|
||||
initCaps(clientVersion);
|
||||
mState.initialize(mCaps, clientVersion);
|
||||
initCaps(mClientVersion);
|
||||
|
||||
mClientVersion = clientVersion;
|
||||
|
||||
mClientType = EGL_OPENGL_ES_API;
|
||||
mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
|
||||
|
||||
mFenceNVHandleAllocator.setBaseHandle(0);
|
||||
|
||||
|
@ -147,12 +216,6 @@ Context::Context(const egl::Config *config,
|
|||
bindTransformFeedback(0);
|
||||
}
|
||||
|
||||
mHasBeenCurrent = false;
|
||||
mContextLost = false;
|
||||
mResetStatus = GL_NO_ERROR;
|
||||
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
|
||||
mRobustAccess = robustAccess;
|
||||
|
||||
mCompiler = new Compiler(mRenderer, getData());
|
||||
}
|
||||
|
||||
|
@ -253,6 +316,9 @@ void Context::makeCurrent(egl::Surface *surface)
|
|||
}
|
||||
mFramebufferMap[0] = newDefault;
|
||||
}
|
||||
|
||||
// Notify the renderer of a context switch
|
||||
mRenderer->onMakeCurrent(getData());
|
||||
}
|
||||
|
||||
void Context::releaseSurface()
|
||||
|
@ -503,7 +569,7 @@ void Context::deleteQuery(GLuint query)
|
|||
}
|
||||
}
|
||||
|
||||
Buffer *Context::getBuffer(GLuint handle)
|
||||
Buffer *Context::getBuffer(GLuint handle) const
|
||||
{
|
||||
return mResourceManager->getBuffer(handle);
|
||||
}
|
||||
|
@ -523,7 +589,7 @@ Texture *Context::getTexture(GLuint handle) const
|
|||
return mResourceManager->getTexture(handle);
|
||||
}
|
||||
|
||||
Renderbuffer *Context::getRenderbuffer(GLuint handle)
|
||||
Renderbuffer *Context::getRenderbuffer(GLuint handle) const
|
||||
{
|
||||
return mResourceManager->getRenderbuffer(handle);
|
||||
}
|
||||
|
@ -550,6 +616,41 @@ TransformFeedback *Context::getTransformFeedback(GLuint handle) const
|
|||
return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
|
||||
}
|
||||
|
||||
LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
|
||||
{
|
||||
switch (identifier)
|
||||
{
|
||||
case GL_BUFFER:
|
||||
return getBuffer(name);
|
||||
case GL_SHADER:
|
||||
return getShader(name);
|
||||
case GL_PROGRAM:
|
||||
return getProgram(name);
|
||||
case GL_VERTEX_ARRAY:
|
||||
return getVertexArray(name);
|
||||
case GL_QUERY:
|
||||
return getQuery(name);
|
||||
case GL_TRANSFORM_FEEDBACK:
|
||||
return getTransformFeedback(name);
|
||||
case GL_SAMPLER:
|
||||
return getSampler(name);
|
||||
case GL_TEXTURE:
|
||||
return getTexture(name);
|
||||
case GL_RENDERBUFFER:
|
||||
return getRenderbuffer(name);
|
||||
case GL_FRAMEBUFFER:
|
||||
return getFramebuffer(name);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
|
||||
{
|
||||
return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
|
||||
}
|
||||
|
||||
bool Context::isSampler(GLuint samplerName) const
|
||||
{
|
||||
return mResourceManager->isSampler(samplerName);
|
||||
|
@ -588,24 +689,16 @@ void Context::bindTexture(GLenum target, GLuint handle)
|
|||
mState.setSamplerTexture(target, texture);
|
||||
}
|
||||
|
||||
void Context::bindReadFramebuffer(GLuint framebuffer)
|
||||
void Context::bindReadFramebuffer(GLuint framebufferHandle)
|
||||
{
|
||||
if (!getFramebuffer(framebuffer))
|
||||
{
|
||||
mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer);
|
||||
}
|
||||
|
||||
mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
|
||||
Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
|
||||
mState.setReadFramebufferBinding(framebuffer);
|
||||
}
|
||||
|
||||
void Context::bindDrawFramebuffer(GLuint framebuffer)
|
||||
void Context::bindDrawFramebuffer(GLuint framebufferHandle)
|
||||
{
|
||||
if (!getFramebuffer(framebuffer))
|
||||
{
|
||||
mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer);
|
||||
}
|
||||
|
||||
mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
|
||||
Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
|
||||
mState.setDrawFramebufferBinding(framebuffer);
|
||||
}
|
||||
|
||||
void Context::bindRenderbuffer(GLuint renderbuffer)
|
||||
|
@ -729,18 +822,68 @@ Error Context::endQuery(GLenum target)
|
|||
return error;
|
||||
}
|
||||
|
||||
Error Context::queryCounter(GLuint id, GLenum target)
|
||||
{
|
||||
ASSERT(target == GL_TIMESTAMP_EXT);
|
||||
|
||||
Query *queryObject = getQuery(id, true, target);
|
||||
ASSERT(queryObject);
|
||||
|
||||
return queryObject->queryCounter();
|
||||
}
|
||||
|
||||
void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
|
||||
{
|
||||
switch (pname)
|
||||
{
|
||||
case GL_CURRENT_QUERY_EXT:
|
||||
params[0] = getState().getActiveQueryId(target);
|
||||
break;
|
||||
case GL_QUERY_COUNTER_BITS_EXT:
|
||||
switch (target)
|
||||
{
|
||||
case GL_TIME_ELAPSED_EXT:
|
||||
params[0] = getExtensions().queryCounterBitsTimeElapsed;
|
||||
break;
|
||||
case GL_TIMESTAMP_EXT:
|
||||
params[0] = getExtensions().queryCounterBitsTimestamp;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
params[0] = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
|
||||
{
|
||||
return GetQueryObjectParameter(this, id, pname, params);
|
||||
}
|
||||
|
||||
Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
|
||||
{
|
||||
return GetQueryObjectParameter(this, id, pname, params);
|
||||
}
|
||||
|
||||
Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
|
||||
{
|
||||
return GetQueryObjectParameter(this, id, pname, params);
|
||||
}
|
||||
|
||||
Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
|
||||
{
|
||||
return GetQueryObjectParameter(this, id, pname, params);
|
||||
}
|
||||
|
||||
Framebuffer *Context::getFramebuffer(unsigned int handle) const
|
||||
{
|
||||
FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
|
||||
|
||||
if (framebuffer == mFramebufferMap.end())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return framebuffer->second;
|
||||
}
|
||||
auto framebufferIt = mFramebufferMap.find(handle);
|
||||
return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
|
||||
}
|
||||
|
||||
FenceNV *Context::getFenceNV(unsigned int handle)
|
||||
|
@ -776,11 +919,16 @@ Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
|
|||
}
|
||||
}
|
||||
|
||||
Query *Context::getQuery(GLuint handle) const
|
||||
{
|
||||
auto iter = mQueryMap.find(handle);
|
||||
return (iter != mQueryMap.end()) ? iter->second : nullptr;
|
||||
}
|
||||
|
||||
Texture *Context::getTargetTexture(GLenum target) const
|
||||
{
|
||||
ASSERT(ValidTextureTarget(this, target));
|
||||
|
||||
return getSamplerTexture(mState.getActiveSampler(), target);
|
||||
return mState.getTargetTexture(target);
|
||||
}
|
||||
|
||||
Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
|
||||
|
@ -905,6 +1053,26 @@ void Context::getIntegerv(GLenum pname, GLint *params)
|
|||
case GL_NUM_EXTENSIONS:
|
||||
*params = static_cast<GLint>(mExtensionStrings.size());
|
||||
break;
|
||||
|
||||
// GL_KHR_debug
|
||||
case GL_MAX_DEBUG_MESSAGE_LENGTH:
|
||||
*params = mExtensions.maxDebugMessageLength;
|
||||
break;
|
||||
case GL_MAX_DEBUG_LOGGED_MESSAGES:
|
||||
*params = mExtensions.maxDebugLoggedMessages;
|
||||
break;
|
||||
case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
|
||||
*params = mExtensions.maxDebugGroupStackDepth;
|
||||
break;
|
||||
case GL_MAX_LABEL_LENGTH:
|
||||
*params = mExtensions.maxLabelLength;
|
||||
break;
|
||||
|
||||
// GL_EXT_disjoint_timer_query
|
||||
case GL_GPU_DISJOINT_EXT:
|
||||
*params = mRenderer->getGPUDisjoint();
|
||||
break;
|
||||
|
||||
default:
|
||||
mState.getIntegerv(getData(), pname, params);
|
||||
break;
|
||||
|
@ -932,12 +1100,22 @@ void Context::getInteger64v(GLenum pname, GLint64 *params)
|
|||
case GL_MAX_SERVER_WAIT_TIMEOUT:
|
||||
*params = mCaps.maxServerWaitTimeout;
|
||||
break;
|
||||
|
||||
// GL_EXT_disjoint_timer_query
|
||||
case GL_TIMESTAMP_EXT:
|
||||
*params = mRenderer->getTimestamp();
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Context::getPointerv(GLenum pname, void **params) const
|
||||
{
|
||||
mState.getPointerv(pname, params);
|
||||
}
|
||||
|
||||
bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
|
||||
{
|
||||
// Queries about context capabilities and maximums are answered by Context.
|
||||
|
@ -1147,6 +1325,45 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
|
|||
*type = GL_FLOAT;
|
||||
*numParams = 1;
|
||||
return true;
|
||||
case GL_TIMESTAMP_EXT:
|
||||
if (!mExtensions.disjointTimerQuery)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*type = GL_INT_64_ANGLEX;
|
||||
*numParams = 1;
|
||||
return true;
|
||||
case GL_GPU_DISJOINT_EXT:
|
||||
if (!mExtensions.disjointTimerQuery)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*type = GL_INT;
|
||||
*numParams = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mExtensions.debug)
|
||||
{
|
||||
switch (pname)
|
||||
{
|
||||
case GL_DEBUG_LOGGED_MESSAGES:
|
||||
case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
|
||||
case GL_DEBUG_GROUP_STACK_DEPTH:
|
||||
case GL_MAX_DEBUG_MESSAGE_LENGTH:
|
||||
case GL_MAX_DEBUG_LOGGED_MESSAGES:
|
||||
case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
|
||||
case GL_MAX_LABEL_LENGTH:
|
||||
*type = GL_INT;
|
||||
*numParams = 1;
|
||||
return true;
|
||||
|
||||
case GL_DEBUG_OUTPUT_SYNCHRONOUS:
|
||||
case GL_DEBUG_OUTPUT:
|
||||
*type = GL_BOOL;
|
||||
*numParams = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for ES3.0+ parameter names which are also exposed as ES2 extensions
|
||||
|
@ -1393,6 +1610,13 @@ void Context::recordError(const Error &error)
|
|||
if (error.isError())
|
||||
{
|
||||
mErrors.insert(error.getCode());
|
||||
|
||||
if (!error.getMessage().empty())
|
||||
{
|
||||
auto &debug = mState.getDebug();
|
||||
debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
|
||||
GL_DEBUG_SEVERITY_HIGH, error.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1474,6 +1698,7 @@ EGLenum Context::getRenderBuffer() const
|
|||
|
||||
void Context::checkVertexArrayAllocation(GLuint vertexArray)
|
||||
{
|
||||
// Only called after a prior call to Gen.
|
||||
if (!getVertexArray(vertexArray))
|
||||
{
|
||||
VertexArray *vertexArrayObject =
|
||||
|
@ -1484,6 +1709,7 @@ void Context::checkVertexArrayAllocation(GLuint vertexArray)
|
|||
|
||||
void Context::checkTransformFeedbackAllocation(GLuint transformFeedback)
|
||||
{
|
||||
// Only called after a prior call to Gen.
|
||||
if (!getTransformFeedback(transformFeedback))
|
||||
{
|
||||
TransformFeedback *transformFeedbackObject =
|
||||
|
@ -1493,6 +1719,27 @@ void Context::checkTransformFeedbackAllocation(GLuint transformFeedback)
|
|||
}
|
||||
}
|
||||
|
||||
Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
|
||||
{
|
||||
// Can be called from Bind without a prior call to Gen.
|
||||
auto framebufferIt = mFramebufferMap.find(framebuffer);
|
||||
bool neverCreated = framebufferIt == mFramebufferMap.end();
|
||||
if (neverCreated || framebufferIt->second == nullptr)
|
||||
{
|
||||
Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
|
||||
if (neverCreated)
|
||||
{
|
||||
mFramebufferHandleAllocator.reserve(framebuffer);
|
||||
mFramebufferMap[framebuffer] = newFBO;
|
||||
return newFBO;
|
||||
}
|
||||
|
||||
framebufferIt->second = newFBO;
|
||||
}
|
||||
|
||||
return framebufferIt->second;
|
||||
}
|
||||
|
||||
bool Context::isVertexArrayGenerated(GLuint vertexArray)
|
||||
{
|
||||
return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
|
||||
|
@ -1740,6 +1987,13 @@ void Context::initCaps(GLuint clientVersion)
|
|||
//mExtensions.sRGB = false;
|
||||
}
|
||||
|
||||
// Explicitly enable GL_KHR_debug
|
||||
mExtensions.debug = true;
|
||||
mExtensions.maxDebugMessageLength = 1024;
|
||||
mExtensions.maxDebugLoggedMessages = 1024;
|
||||
mExtensions.maxDebugGroupStackDepth = 1024;
|
||||
mExtensions.maxLabelLength = 1024;
|
||||
|
||||
// Apply implementation limits
|
||||
mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
|
||||
mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
|
||||
|
@ -1785,20 +2039,386 @@ void Context::initCaps(GLuint clientVersion)
|
|||
void Context::syncRendererState()
|
||||
{
|
||||
const State::DirtyBits &dirtyBits = mState.getDirtyBits();
|
||||
if (dirtyBits.any())
|
||||
{
|
||||
mRenderer->syncState(mState, dirtyBits);
|
||||
mState.clearDirtyBits();
|
||||
}
|
||||
mRenderer->syncState(mState, dirtyBits);
|
||||
mState.clearDirtyBits();
|
||||
mState.syncDirtyObjects();
|
||||
}
|
||||
|
||||
void Context::syncRendererState(const State::DirtyBits &bitMask)
|
||||
{
|
||||
const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
|
||||
if (dirtyBits.any())
|
||||
mRenderer->syncState(mState, dirtyBits);
|
||||
mState.clearDirtyBits(dirtyBits);
|
||||
|
||||
// TODO(jmadill): Filter objects by bitMask somehow?
|
||||
mState.syncDirtyObjects();
|
||||
}
|
||||
|
||||
void Context::blitFramebuffer(GLint srcX0,
|
||||
GLint srcY0,
|
||||
GLint srcX1,
|
||||
GLint srcY1,
|
||||
GLint dstX0,
|
||||
GLint dstY0,
|
||||
GLint dstX1,
|
||||
GLint dstY1,
|
||||
GLbitfield mask,
|
||||
GLenum filter)
|
||||
{
|
||||
Framebuffer *readFramebuffer = mState.getReadFramebuffer();
|
||||
ASSERT(readFramebuffer);
|
||||
|
||||
Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
|
||||
ASSERT(drawFramebuffer);
|
||||
|
||||
Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
|
||||
Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
|
||||
|
||||
syncRendererState(mState.blitStateBitMask());
|
||||
|
||||
Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
|
||||
if (error.isError())
|
||||
{
|
||||
mRenderer->syncState(mState, dirtyBits);
|
||||
mState.clearDirtyBits(dirtyBits);
|
||||
recordError(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Context::clear(GLbitfield mask)
|
||||
{
|
||||
// Sync the clear state
|
||||
syncRendererState(mState.clearStateBitMask());
|
||||
|
||||
Error error = mState.getDrawFramebuffer()->clear(mData, mask);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
|
||||
{
|
||||
// Sync the clear state
|
||||
syncRendererState(mState.clearStateBitMask());
|
||||
|
||||
Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
|
||||
{
|
||||
// Sync the clear state
|
||||
syncRendererState(mState.clearStateBitMask());
|
||||
|
||||
Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
|
||||
{
|
||||
// Sync the clear state
|
||||
syncRendererState(mState.clearStateBitMask());
|
||||
|
||||
Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
|
||||
{
|
||||
Framebuffer *framebufferObject = mState.getDrawFramebuffer();
|
||||
ASSERT(framebufferObject);
|
||||
|
||||
// If a buffer is not present, the clear has no effect
|
||||
if (framebufferObject->getDepthbuffer() == nullptr &&
|
||||
framebufferObject->getStencilbuffer() == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Sync the clear state
|
||||
syncRendererState(mState.clearStateBitMask());
|
||||
|
||||
Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::readPixels(GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
GLvoid *pixels)
|
||||
{
|
||||
// Sync pack state
|
||||
syncRendererState(mState.packStateBitMask());
|
||||
|
||||
Framebuffer *framebufferObject = mState.getReadFramebuffer();
|
||||
ASSERT(framebufferObject);
|
||||
|
||||
Rectangle area(x, y, width, height);
|
||||
Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::copyTexImage2D(GLenum target,
|
||||
GLint level,
|
||||
GLenum internalformat,
|
||||
GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLint border)
|
||||
{
|
||||
// Only sync the read FBO
|
||||
mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
|
||||
|
||||
Rectangle sourceArea(x, y, width, height);
|
||||
|
||||
const Framebuffer *framebuffer = mState.getReadFramebuffer();
|
||||
Texture *texture =
|
||||
getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
|
||||
Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::copyTexSubImage2D(GLenum target,
|
||||
GLint level,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height)
|
||||
{
|
||||
// Only sync the read FBO
|
||||
mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
|
||||
|
||||
Offset destOffset(xoffset, yoffset, 0);
|
||||
Rectangle sourceArea(x, y, width, height);
|
||||
|
||||
const Framebuffer *framebuffer = mState.getReadFramebuffer();
|
||||
Texture *texture =
|
||||
getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
|
||||
Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::copyTexSubImage3D(GLenum target,
|
||||
GLint level,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLint zoffset,
|
||||
GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height)
|
||||
{
|
||||
// Only sync the read FBO
|
||||
mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
|
||||
|
||||
Offset destOffset(xoffset, yoffset, zoffset);
|
||||
Rectangle sourceArea(x, y, width, height);
|
||||
|
||||
const Framebuffer *framebuffer = mState.getReadFramebuffer();
|
||||
Texture *texture = getTargetTexture(target);
|
||||
Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::framebufferTexture2D(GLenum target,
|
||||
GLenum attachment,
|
||||
GLenum textarget,
|
||||
GLuint texture,
|
||||
GLint level)
|
||||
{
|
||||
Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
|
||||
ASSERT(framebuffer);
|
||||
|
||||
if (texture != 0)
|
||||
{
|
||||
Texture *textureObj = getTexture(texture);
|
||||
|
||||
ImageIndex index = ImageIndex::MakeInvalid();
|
||||
|
||||
if (textarget == GL_TEXTURE_2D)
|
||||
{
|
||||
index = ImageIndex::Make2D(level);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(IsCubeMapTextureTarget(textarget));
|
||||
index = ImageIndex::MakeCube(textarget, level);
|
||||
}
|
||||
|
||||
framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
framebuffer->resetAttachment(attachment);
|
||||
}
|
||||
|
||||
mState.setObjectDirty(target);
|
||||
}
|
||||
|
||||
void Context::framebufferRenderbuffer(GLenum target,
|
||||
GLenum attachment,
|
||||
GLenum renderbuffertarget,
|
||||
GLuint renderbuffer)
|
||||
{
|
||||
Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
|
||||
ASSERT(framebuffer);
|
||||
|
||||
if (renderbuffer != 0)
|
||||
{
|
||||
Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
|
||||
framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
|
||||
renderbufferObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
framebuffer->resetAttachment(attachment);
|
||||
}
|
||||
|
||||
mState.setObjectDirty(target);
|
||||
}
|
||||
|
||||
void Context::framebufferTextureLayer(GLenum target,
|
||||
GLenum attachment,
|
||||
GLuint texture,
|
||||
GLint level,
|
||||
GLint layer)
|
||||
{
|
||||
Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
|
||||
ASSERT(framebuffer);
|
||||
|
||||
if (texture != 0)
|
||||
{
|
||||
Texture *textureObject = getTexture(texture);
|
||||
|
||||
ImageIndex index = ImageIndex::MakeInvalid();
|
||||
|
||||
if (textureObject->getTarget() == GL_TEXTURE_3D)
|
||||
{
|
||||
index = ImageIndex::Make3D(level, layer);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
|
||||
index = ImageIndex::Make2DArray(level, layer);
|
||||
}
|
||||
|
||||
framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
framebuffer->resetAttachment(attachment);
|
||||
}
|
||||
|
||||
mState.setObjectDirty(target);
|
||||
}
|
||||
|
||||
void Context::drawBuffers(GLsizei n, const GLenum *bufs)
|
||||
{
|
||||
Framebuffer *framebuffer = mState.getDrawFramebuffer();
|
||||
ASSERT(framebuffer);
|
||||
framebuffer->setDrawBuffers(n, bufs);
|
||||
mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
|
||||
}
|
||||
|
||||
void Context::readBuffer(GLenum mode)
|
||||
{
|
||||
Framebuffer *readFBO = mState.getReadFramebuffer();
|
||||
readFBO->setReadBuffer(mode);
|
||||
mState.setObjectDirty(GL_READ_FRAMEBUFFER);
|
||||
}
|
||||
|
||||
void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
|
||||
{
|
||||
// Only sync the FBO
|
||||
mState.syncDirtyObject(target);
|
||||
|
||||
Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
|
||||
ASSERT(framebuffer);
|
||||
|
||||
// The specification isn't clear what should be done when the framebuffer isn't complete.
|
||||
// We leave it up to the framebuffer implementation to decide what to do.
|
||||
Error error = framebuffer->discard(numAttachments, attachments);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::invalidateFramebuffer(GLenum target,
|
||||
GLsizei numAttachments,
|
||||
const GLenum *attachments)
|
||||
{
|
||||
// Only sync the FBO
|
||||
mState.syncDirtyObject(target);
|
||||
|
||||
Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
|
||||
ASSERT(framebuffer);
|
||||
|
||||
if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
Error error = framebuffer->invalidate(numAttachments, attachments);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Context::invalidateSubFramebuffer(GLenum target,
|
||||
GLsizei numAttachments,
|
||||
const GLenum *attachments,
|
||||
GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height)
|
||||
{
|
||||
// Only sync the FBO
|
||||
mState.syncDirtyObject(target);
|
||||
|
||||
Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
|
||||
ASSERT(framebuffer);
|
||||
|
||||
if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
Rectangle area(x, y, width, height);
|
||||
Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
|
|
|
@ -33,6 +33,7 @@ class Renderer;
|
|||
|
||||
namespace egl
|
||||
{
|
||||
class AttributeMap;
|
||||
class Surface;
|
||||
struct Config;
|
||||
}
|
||||
|
@ -58,7 +59,10 @@ class TransformFeedback;
|
|||
class Context final : public ValidationContext
|
||||
{
|
||||
public:
|
||||
Context(const egl::Config *config, int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
|
||||
Context(const egl::Config *config,
|
||||
const Context *shareContext,
|
||||
rx::Renderer *renderer,
|
||||
const egl::AttributeMap &attribs);
|
||||
|
||||
virtual ~Context();
|
||||
|
||||
|
@ -107,8 +111,8 @@ class Context final : public ValidationContext
|
|||
void bindArrayBuffer(GLuint buffer);
|
||||
void bindElementArrayBuffer(GLuint buffer);
|
||||
void bindTexture(GLenum target, GLuint handle);
|
||||
void bindReadFramebuffer(GLuint framebuffer);
|
||||
void bindDrawFramebuffer(GLuint framebuffer);
|
||||
void bindReadFramebuffer(GLuint framebufferHandle);
|
||||
void bindDrawFramebuffer(GLuint framebufferHandle);
|
||||
void bindRenderbuffer(GLuint renderbuffer);
|
||||
void bindVertexArray(GLuint vertexArray);
|
||||
void bindSampler(GLuint textureUnit, GLuint sampler);
|
||||
|
@ -125,6 +129,12 @@ class Context final : public ValidationContext
|
|||
|
||||
Error beginQuery(GLenum target, GLuint query);
|
||||
Error endQuery(GLenum target);
|
||||
Error queryCounter(GLuint id, GLenum target);
|
||||
void getQueryiv(GLenum target, GLenum pname, GLint *params);
|
||||
Error getQueryObjectiv(GLuint id, GLenum pname, GLint *params);
|
||||
Error getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params);
|
||||
Error getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params);
|
||||
Error getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params);
|
||||
|
||||
void setVertexAttribDivisor(GLuint index, GLuint divisor);
|
||||
|
||||
|
@ -133,18 +143,21 @@ class Context final : public ValidationContext
|
|||
GLint getSamplerParameteri(GLuint sampler, GLenum pname);
|
||||
GLfloat getSamplerParameterf(GLuint sampler, GLenum pname);
|
||||
|
||||
Buffer *getBuffer(GLuint handle);
|
||||
Buffer *getBuffer(GLuint handle) const;
|
||||
FenceNV *getFenceNV(GLuint handle);
|
||||
FenceSync *getFenceSync(GLsync handle) const;
|
||||
Shader *getShader(GLuint handle) const;
|
||||
Program *getProgram(GLuint handle) const;
|
||||
Texture *getTexture(GLuint handle) const;
|
||||
Framebuffer *getFramebuffer(GLuint handle) const;
|
||||
Renderbuffer *getRenderbuffer(GLuint handle);
|
||||
Renderbuffer *getRenderbuffer(GLuint handle) const;
|
||||
VertexArray *getVertexArray(GLuint handle) const;
|
||||
Sampler *getSampler(GLuint handle) const;
|
||||
Query *getQuery(GLuint handle, bool create, GLenum type);
|
||||
Query *getQuery(GLuint handle) const;
|
||||
TransformFeedback *getTransformFeedback(GLuint handle) const;
|
||||
LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const;
|
||||
LabeledObject *getLabeledObjectFromPtr(const void *ptr) const;
|
||||
|
||||
Texture *getTargetTexture(GLenum target) const;
|
||||
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
|
||||
|
@ -160,6 +173,7 @@ class Context final : public ValidationContext
|
|||
void getFloatv(GLenum pname, GLfloat *params);
|
||||
void getIntegerv(GLenum pname, GLint *params);
|
||||
void getInteger64v(GLenum pname, GLint64 *params);
|
||||
void getPointerv(GLenum pname, void **params) const;
|
||||
|
||||
bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data);
|
||||
bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data);
|
||||
|
@ -167,6 +181,12 @@ class Context final : public ValidationContext
|
|||
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
|
||||
bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
|
||||
|
||||
void clear(GLbitfield mask);
|
||||
void clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values);
|
||||
void clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values);
|
||||
void clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values);
|
||||
void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||
|
||||
Error drawArrays(GLenum mode, GLint first, GLsizei count);
|
||||
Error drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
|
||||
|
||||
|
@ -189,6 +209,83 @@ class Context final : public ValidationContext
|
|||
const GLvoid *indices,
|
||||
const IndexRange &indexRange);
|
||||
|
||||
void blitFramebuffer(GLint srcX0,
|
||||
GLint srcY0,
|
||||
GLint srcX1,
|
||||
GLint srcY1,
|
||||
GLint dstX0,
|
||||
GLint dstY0,
|
||||
GLint dstX1,
|
||||
GLint dstY1,
|
||||
GLbitfield mask,
|
||||
GLenum filter);
|
||||
|
||||
void readPixels(GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
GLvoid *pixels);
|
||||
|
||||
void copyTexImage2D(GLenum target,
|
||||
GLint level,
|
||||
GLenum internalformat,
|
||||
GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLint border);
|
||||
|
||||
void copyTexSubImage2D(GLenum target,
|
||||
GLint level,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height);
|
||||
|
||||
void copyTexSubImage3D(GLenum target,
|
||||
GLint level,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLint zoffset,
|
||||
GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height);
|
||||
|
||||
void framebufferTexture2D(GLenum target,
|
||||
GLenum attachment,
|
||||
GLenum textarget,
|
||||
GLuint texture,
|
||||
GLint level);
|
||||
|
||||
void framebufferRenderbuffer(GLenum target,
|
||||
GLenum attachment,
|
||||
GLenum renderbuffertarget,
|
||||
GLuint renderbuffer);
|
||||
|
||||
void framebufferTextureLayer(GLenum target,
|
||||
GLenum attachment,
|
||||
GLuint texture,
|
||||
GLint level,
|
||||
GLint layer);
|
||||
|
||||
void drawBuffers(GLsizei n, const GLenum *bufs);
|
||||
void readBuffer(GLenum mode);
|
||||
|
||||
void discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments);
|
||||
void invalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments);
|
||||
void invalidateSubFramebuffer(GLenum target,
|
||||
GLsizei numAttachments,
|
||||
const GLenum *attachments,
|
||||
GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height);
|
||||
|
||||
Error flush();
|
||||
Error finish();
|
||||
|
||||
|
@ -222,6 +319,7 @@ class Context final : public ValidationContext
|
|||
private:
|
||||
void checkVertexArrayAllocation(GLuint vertexArray);
|
||||
void checkTransformFeedbackAllocation(GLuint transformFeedback);
|
||||
Framebuffer *checkFramebufferAllocation(GLuint framebufferHandle);
|
||||
|
||||
void detachBuffer(GLuint buffer);
|
||||
void detachTexture(GLuint texture);
|
||||
|
@ -294,6 +392,6 @@ class Context final : public ValidationContext
|
|||
ResourceManager *mResourceManager;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace gl
|
||||
|
||||
#endif // LIBANGLE_CONTEXT_H_
|
||||
|
|
|
@ -40,7 +40,8 @@ ValidationContext::ValidationContext(GLint clientVersion,
|
|||
const TextureCapsMap &textureCaps,
|
||||
const Extensions &extensions,
|
||||
const ResourceManager *resourceManager,
|
||||
const Limitations &limitations)
|
||||
const Limitations &limitations,
|
||||
bool skipValidation)
|
||||
: mData(reinterpret_cast<uintptr_t>(this),
|
||||
clientVersion,
|
||||
state,
|
||||
|
@ -48,7 +49,8 @@ ValidationContext::ValidationContext(GLint clientVersion,
|
|||
textureCaps,
|
||||
extensions,
|
||||
resourceManager,
|
||||
limitations)
|
||||
limitations),
|
||||
mSkipValidation(skipValidation)
|
||||
{
|
||||
}
|
||||
}
|
||||
} // namespace gl
|
||||
|
|
|
@ -47,7 +47,8 @@ class ValidationContext : angle::NonCopyable
|
|||
const TextureCapsMap &textureCaps,
|
||||
const Extensions &extensions,
|
||||
const ResourceManager *resourceManager,
|
||||
const Limitations &limitations);
|
||||
const Limitations &limitations,
|
||||
bool skipValidation);
|
||||
virtual ~ValidationContext() {}
|
||||
|
||||
virtual void recordError(const Error &error) = 0;
|
||||
|
@ -59,9 +60,11 @@ class ValidationContext : angle::NonCopyable
|
|||
const TextureCapsMap &getTextureCaps() const { return *mData.textureCaps; }
|
||||
const Extensions &getExtensions() const { return *mData.extensions; }
|
||||
const Limitations &getLimitations() const { return *mData.limitations; }
|
||||
bool skipValidation() const { return mSkipValidation; }
|
||||
|
||||
protected:
|
||||
Data mData;
|
||||
bool mSkipValidation;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
//
|
||||
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Debug.cpp: Defines debug state used for GL_KHR_debug
|
||||
|
||||
#include "libANGLE/Debug.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <tuple>
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
Debug::Debug()
|
||||
: mOutputEnabled(false),
|
||||
mCallbackFunction(nullptr),
|
||||
mCallbackUserParam(nullptr),
|
||||
mMessages(),
|
||||
mMaxLoggedMessages(0),
|
||||
mOutputSynchronous(false),
|
||||
mGroups()
|
||||
{
|
||||
pushDefaultGroup();
|
||||
}
|
||||
|
||||
void Debug::setMaxLoggedMessages(GLuint maxLoggedMessages)
|
||||
{
|
||||
mMaxLoggedMessages = maxLoggedMessages;
|
||||
}
|
||||
|
||||
void Debug::setOutputEnabled(bool enabled)
|
||||
{
|
||||
mOutputEnabled = enabled;
|
||||
}
|
||||
|
||||
bool Debug::isOutputEnabled() const
|
||||
{
|
||||
return mOutputEnabled;
|
||||
}
|
||||
|
||||
void Debug::setOutputSynchronous(bool synchronous)
|
||||
{
|
||||
mOutputSynchronous = synchronous;
|
||||
}
|
||||
|
||||
bool Debug::isOutputSynchronous() const
|
||||
{
|
||||
return mOutputSynchronous;
|
||||
}
|
||||
|
||||
void Debug::setCallback(GLDEBUGPROCKHR callback, const void *userParam)
|
||||
{
|
||||
mCallbackFunction = callback;
|
||||
mCallbackUserParam = userParam;
|
||||
}
|
||||
|
||||
GLDEBUGPROCKHR Debug::getCallback() const
|
||||
{
|
||||
return mCallbackFunction;
|
||||
}
|
||||
|
||||
const void *Debug::getUserParam() const
|
||||
{
|
||||
return mCallbackUserParam;
|
||||
}
|
||||
|
||||
void Debug::insertMessage(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
const std::string &message)
|
||||
{
|
||||
std::string messageCopy(message);
|
||||
insertMessage(source, type, id, severity, std::move(messageCopy));
|
||||
}
|
||||
|
||||
void Debug::insertMessage(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
std::string &&message)
|
||||
{
|
||||
if (!isMessageEnabled(source, type, id, severity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCallbackFunction != nullptr)
|
||||
{
|
||||
// TODO(geofflang) Check the synchronous flag and potentially flush messages from another
|
||||
// thread.
|
||||
mCallbackFunction(source, type, id, severity, static_cast<GLsizei>(message.length()),
|
||||
message.c_str(), mCallbackUserParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mMessages.size() >= mMaxLoggedMessages)
|
||||
{
|
||||
// Drop messages over the limit
|
||||
return;
|
||||
}
|
||||
|
||||
Message m;
|
||||
m.source = source;
|
||||
m.type = type;
|
||||
m.id = id;
|
||||
m.severity = severity;
|
||||
m.message = std::move(message);
|
||||
|
||||
mMessages.push_back(std::move(m));
|
||||
}
|
||||
}
|
||||
|
||||
size_t Debug::getMessages(GLuint count,
|
||||
GLsizei bufSize,
|
||||
GLenum *sources,
|
||||
GLenum *types,
|
||||
GLuint *ids,
|
||||
GLenum *severities,
|
||||
GLsizei *lengths,
|
||||
GLchar *messageLog)
|
||||
{
|
||||
size_t messageCount = 0;
|
||||
size_t messageStringIndex = 0;
|
||||
while (messageCount <= count && !mMessages.empty())
|
||||
{
|
||||
const Message &m = mMessages.front();
|
||||
|
||||
if (messageLog != nullptr)
|
||||
{
|
||||
// Check that this message can fit in the message buffer
|
||||
if (messageStringIndex + m.message.length() + 1 > static_cast<size_t>(bufSize))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
std::copy(m.message.begin(), m.message.end(), messageLog + messageStringIndex);
|
||||
messageStringIndex += m.message.length();
|
||||
|
||||
messageLog[messageStringIndex] = '\0';
|
||||
messageStringIndex += 1;
|
||||
}
|
||||
|
||||
if (sources != nullptr)
|
||||
{
|
||||
sources[messageCount] = m.source;
|
||||
}
|
||||
|
||||
if (types != nullptr)
|
||||
{
|
||||
types[messageCount] = m.type;
|
||||
}
|
||||
|
||||
if (ids != nullptr)
|
||||
{
|
||||
ids[messageCount] = m.id;
|
||||
}
|
||||
|
||||
if (severities != nullptr)
|
||||
{
|
||||
severities[messageCount] = m.severity;
|
||||
}
|
||||
|
||||
if (lengths != nullptr)
|
||||
{
|
||||
lengths[messageCount] = static_cast<GLsizei>(m.message.length());
|
||||
}
|
||||
|
||||
mMessages.pop_front();
|
||||
|
||||
messageCount++;
|
||||
}
|
||||
|
||||
return messageCount;
|
||||
}
|
||||
|
||||
size_t Debug::getNextMessageLength() const
|
||||
{
|
||||
return mMessages.empty() ? 0 : mMessages.front().message.length();
|
||||
}
|
||||
|
||||
size_t Debug::getMessageCount() const
|
||||
{
|
||||
return mMessages.size();
|
||||
}
|
||||
|
||||
void Debug::setMessageControl(GLenum source,
|
||||
GLenum type,
|
||||
GLenum severity,
|
||||
std::vector<GLuint> &&ids,
|
||||
bool enabled)
|
||||
{
|
||||
Control c;
|
||||
c.source = source;
|
||||
c.type = type;
|
||||
c.severity = severity;
|
||||
c.ids = std::move(ids);
|
||||
c.enabled = enabled;
|
||||
|
||||
auto &controls = mGroups.back().controls;
|
||||
controls.push_back(std::move(c));
|
||||
}
|
||||
|
||||
void Debug::pushGroup(GLenum source, GLuint id, std::string &&message)
|
||||
{
|
||||
insertMessage(source, GL_DEBUG_TYPE_PUSH_GROUP, id, GL_DEBUG_SEVERITY_NOTIFICATION,
|
||||
std::string(message));
|
||||
|
||||
Group g;
|
||||
g.source = source;
|
||||
g.id = id;
|
||||
g.message = std::move(message);
|
||||
mGroups.push_back(std::move(g));
|
||||
}
|
||||
|
||||
void Debug::popGroup()
|
||||
{
|
||||
// Make sure the default group is not about to be popped
|
||||
ASSERT(mGroups.size() > 1);
|
||||
|
||||
Group g = mGroups.back();
|
||||
mGroups.pop_back();
|
||||
|
||||
insertMessage(g.source, GL_DEBUG_TYPE_POP_GROUP, g.id, GL_DEBUG_SEVERITY_NOTIFICATION,
|
||||
g.message);
|
||||
}
|
||||
|
||||
size_t Debug::getGroupStackDepth() const
|
||||
{
|
||||
return mGroups.size();
|
||||
}
|
||||
|
||||
bool Debug::isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const
|
||||
{
|
||||
if (!mOutputEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto groupIter = mGroups.rbegin(); groupIter != mGroups.rend(); groupIter++)
|
||||
{
|
||||
const auto &controls = groupIter->controls;
|
||||
for (auto controlIter = controls.rbegin(); controlIter != controls.rend(); controlIter++)
|
||||
{
|
||||
const auto &control = *controlIter;
|
||||
|
||||
if (control.source != GL_DONT_CARE && control.source != source)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (control.type != GL_DONT_CARE && control.type != type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (control.severity != GL_DONT_CARE && control.severity != severity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!control.ids.empty() &&
|
||||
std::find(control.ids.begin(), control.ids.end(), id) == control.ids.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return control.enabled;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Debug::pushDefaultGroup()
|
||||
{
|
||||
Group g;
|
||||
g.source = GL_NONE;
|
||||
g.id = 0;
|
||||
g.message = "";
|
||||
|
||||
Control c0;
|
||||
c0.source = GL_DONT_CARE;
|
||||
c0.type = GL_DONT_CARE;
|
||||
c0.severity = GL_DONT_CARE;
|
||||
c0.enabled = true;
|
||||
g.controls.push_back(std::move(c0));
|
||||
|
||||
Control c1;
|
||||
c1.source = GL_DONT_CARE;
|
||||
c1.type = GL_DONT_CARE;
|
||||
c1.severity = GL_DEBUG_SEVERITY_LOW;
|
||||
c1.enabled = false;
|
||||
g.controls.push_back(std::move(c1));
|
||||
|
||||
mGroups.push_back(std::move(g));
|
||||
}
|
||||
} // namespace gl
|
|
@ -0,0 +1,120 @@
|
|||
//
|
||||
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Debug.h: Defines debug state used for GL_KHR_debug
|
||||
|
||||
#ifndef LIBANGLE_DEBUG_H_
|
||||
#define LIBANGLE_DEBUG_H_
|
||||
|
||||
#include "angle_gl.h"
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
class LabeledObject
|
||||
{
|
||||
public:
|
||||
virtual ~LabeledObject() {}
|
||||
virtual void setLabel(const std::string &label) = 0;
|
||||
virtual const std::string &getLabel() const = 0;
|
||||
};
|
||||
|
||||
class Debug : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
Debug();
|
||||
|
||||
void setMaxLoggedMessages(GLuint maxLoggedMessages);
|
||||
|
||||
void setOutputEnabled(bool enabled);
|
||||
bool isOutputEnabled() const;
|
||||
|
||||
void setOutputSynchronous(bool synchronous);
|
||||
bool isOutputSynchronous() const;
|
||||
|
||||
void setCallback(GLDEBUGPROCKHR callback, const void *userParam);
|
||||
GLDEBUGPROCKHR getCallback() const;
|
||||
const void *getUserParam() const;
|
||||
|
||||
void insertMessage(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
const std::string &message);
|
||||
void insertMessage(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
std::string &&message);
|
||||
|
||||
void setMessageControl(GLenum source,
|
||||
GLenum type,
|
||||
GLenum severity,
|
||||
std::vector<GLuint> &&ids,
|
||||
bool enabled);
|
||||
size_t getMessages(GLuint count,
|
||||
GLsizei bufSize,
|
||||
GLenum *sources,
|
||||
GLenum *types,
|
||||
GLuint *ids,
|
||||
GLenum *severities,
|
||||
GLsizei *lengths,
|
||||
GLchar *messageLog);
|
||||
size_t getNextMessageLength() const;
|
||||
size_t getMessageCount() const;
|
||||
|
||||
void pushGroup(GLenum source, GLuint id, std::string &&message);
|
||||
void popGroup();
|
||||
size_t getGroupStackDepth() const;
|
||||
|
||||
private:
|
||||
bool isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const;
|
||||
|
||||
void pushDefaultGroup();
|
||||
|
||||
struct Message
|
||||
{
|
||||
GLenum source;
|
||||
GLenum type;
|
||||
GLuint id;
|
||||
GLenum severity;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
struct Control
|
||||
{
|
||||
GLenum source;
|
||||
GLenum type;
|
||||
GLenum severity;
|
||||
std::vector<GLuint> ids;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct Group
|
||||
{
|
||||
GLenum source;
|
||||
GLuint id;
|
||||
std::string message;
|
||||
|
||||
std::vector<Control> controls;
|
||||
};
|
||||
|
||||
bool mOutputEnabled;
|
||||
GLDEBUGPROCKHR mCallbackFunction;
|
||||
const void *mCallbackUserParam;
|
||||
std::deque<Message> mMessages;
|
||||
GLuint mMaxLoggedMessages;
|
||||
bool mOutputSynchronous;
|
||||
std::vector<Group> mGroups;
|
||||
};
|
||||
} // namespace gl
|
||||
|
||||
#endif // LIBANGLE_DEBUG_H_
|
|
@ -176,12 +176,24 @@ rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap)
|
|||
#endif
|
||||
break;
|
||||
|
||||
#if defined(ANGLE_ENABLE_OPENGL)
|
||||
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
|
||||
#if defined(ANGLE_PLATFORM_WINDOWS)
|
||||
impl = new rx::DisplayWGL();
|
||||
#elif defined(ANGLE_USE_X11)
|
||||
impl = new rx::DisplayGLX();
|
||||
#else
|
||||
// No GLES support on this platform, fail display creation.
|
||||
impl = nullptr;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT(impl != nullptr);
|
||||
return impl;
|
||||
}
|
||||
|
||||
|
@ -194,7 +206,7 @@ Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap
|
|||
|
||||
Display *display = nullptr;
|
||||
|
||||
EGLNativeDisplayType displayId = static_cast<EGLNativeDisplayType>(native_display);
|
||||
EGLNativeDisplayType displayId = reinterpret_cast<EGLNativeDisplayType>(native_display);
|
||||
|
||||
ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
|
||||
ANGLEPlatformDisplayMap::const_iterator iter = displays->find(displayId);
|
||||
|
@ -219,6 +231,12 @@ Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap
|
|||
if (!display->isInitialized())
|
||||
{
|
||||
rx::DisplayImpl *impl = CreateDisplayFromAttribs(attribMap);
|
||||
if (impl == nullptr)
|
||||
{
|
||||
// No valid display implementation for these attributes
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
display->setAttributes(impl, attribMap);
|
||||
}
|
||||
|
||||
|
@ -483,6 +501,15 @@ bool Display::getConfigAttrib(const Config *configuration, EGLint attribute, EGL
|
|||
case EGL_MAX_PBUFFER_WIDTH: *value = configuration->maxPBufferWidth; break;
|
||||
case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->maxPBufferHeight; break;
|
||||
case EGL_MAX_PBUFFER_PIXELS: *value = configuration->maxPBufferPixels; break;
|
||||
|
||||
case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
|
||||
if (!getExtensions().surfaceOrientation)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*value = configuration->optimalOrientation;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -686,12 +713,8 @@ Error Display::createContext(const Config *configuration, gl::Context *shareCont
|
|||
}
|
||||
}
|
||||
|
||||
gl::Context *context = nullptr;
|
||||
Error error = mImplementation->createContext(configuration, shareContext, attribs, &context);
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
gl::Context *context = *outContext =
|
||||
mImplementation->createContext(configuration, shareContext, attribs);
|
||||
|
||||
ASSERT(context != nullptr);
|
||||
mContextSet.insert(context);
|
||||
|
@ -791,6 +814,16 @@ void Display::notifyDeviceLost()
|
|||
}
|
||||
}
|
||||
|
||||
Error Display::waitClient() const
|
||||
{
|
||||
return mImplementation->waitClient();
|
||||
}
|
||||
|
||||
Error Display::waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const
|
||||
{
|
||||
return mImplementation->waitNative(engine, drawSurface, readSurface);
|
||||
}
|
||||
|
||||
const Caps &Display::getCaps() const
|
||||
{
|
||||
return mCaps;
|
||||
|
@ -849,6 +882,7 @@ static ClientExtensions GenerateClientExtensions()
|
|||
#if defined(ANGLE_ENABLE_D3D11)
|
||||
extensions.deviceCreation = true;
|
||||
extensions.deviceCreationD3D11 = true;
|
||||
extensions.experimentalPresentPath = true;
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_USE_X11)
|
||||
|
|
|
@ -91,6 +91,9 @@ class Display final : angle::NonCopyable
|
|||
bool testDeviceLost();
|
||||
void notifyDeviceLost();
|
||||
|
||||
Error waitClient() const;
|
||||
Error waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const;
|
||||
|
||||
const Caps &getCaps() const;
|
||||
|
||||
const DisplayExtensions &getExtensions() const;
|
||||
|
|
|
@ -16,9 +16,16 @@
|
|||
namespace gl
|
||||
{
|
||||
|
||||
Error::Error(GLenum errorCode, const char *msg, ...)
|
||||
: mCode(errorCode),
|
||||
mMessage(nullptr)
|
||||
Error::Error(GLenum errorCode, const char *msg, ...) : mCode(errorCode), mID(errorCode)
|
||||
{
|
||||
va_list vararg;
|
||||
va_start(vararg, msg);
|
||||
createMessageString();
|
||||
*mMessage = FormatString(msg, vararg);
|
||||
va_end(vararg);
|
||||
}
|
||||
|
||||
Error::Error(GLenum errorCode, GLuint id, const char *msg, ...) : mCode(errorCode), mID(id)
|
||||
{
|
||||
va_list vararg;
|
||||
va_start(vararg, msg);
|
||||
|
@ -29,9 +36,9 @@ Error::Error(GLenum errorCode, const char *msg, ...)
|
|||
|
||||
void Error::createMessageString() const
|
||||
{
|
||||
if (mMessage == nullptr)
|
||||
if (!mMessage)
|
||||
{
|
||||
mMessage = new std::string();
|
||||
mMessage.reset(new std::string);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,8 +54,7 @@ bool Error::operator==(const Error &other) const
|
|||
return false;
|
||||
|
||||
// TODO(jmadill): Compare extended error codes instead of strings.
|
||||
if ((mMessage == nullptr || other.mMessage == nullptr) &&
|
||||
((mMessage == nullptr) != (other.mMessage == nullptr)))
|
||||
if ((!mMessage || !other.mMessage) && (!mMessage != !other.mMessage))
|
||||
return false;
|
||||
|
||||
return (*mMessage == *other.mMessage);
|
||||
|
@ -63,10 +69,7 @@ bool Error::operator!=(const Error &other) const
|
|||
namespace egl
|
||||
{
|
||||
|
||||
Error::Error(EGLint errorCode, const char *msg, ...)
|
||||
: mCode(errorCode),
|
||||
mID(0),
|
||||
mMessage(nullptr)
|
||||
Error::Error(EGLint errorCode, const char *msg, ...) : mCode(errorCode), mID(0)
|
||||
{
|
||||
va_list vararg;
|
||||
va_start(vararg, msg);
|
||||
|
@ -75,10 +78,7 @@ Error::Error(EGLint errorCode, const char *msg, ...)
|
|||
va_end(vararg);
|
||||
}
|
||||
|
||||
Error::Error(EGLint errorCode, EGLint id, const char *msg, ...)
|
||||
: mCode(errorCode),
|
||||
mID(id),
|
||||
mMessage(nullptr)
|
||||
Error::Error(EGLint errorCode, EGLint id, const char *msg, ...) : mCode(errorCode), mID(id)
|
||||
{
|
||||
va_list vararg;
|
||||
va_start(vararg, msg);
|
||||
|
@ -86,11 +86,12 @@ Error::Error(EGLint errorCode, EGLint id, const char *msg, ...)
|
|||
*mMessage = FormatString(msg, vararg);
|
||||
va_end(vararg);
|
||||
}
|
||||
|
||||
void Error::createMessageString() const
|
||||
{
|
||||
if (mMessage == nullptr)
|
||||
if (!mMessage)
|
||||
{
|
||||
mMessage = new std::string();
|
||||
mMessage.reset(new std::string);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <EGL/egl.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
@ -22,15 +23,15 @@ class Error final
|
|||
public:
|
||||
explicit inline Error(GLenum errorCode);
|
||||
Error(GLenum errorCode, const char *msg, ...);
|
||||
Error(GLenum errorCode, GLuint id, const char *msg, ...);
|
||||
inline Error(const Error &other);
|
||||
inline Error(Error &&other);
|
||||
|
||||
inline ~Error();
|
||||
|
||||
inline Error &operator=(const Error &other);
|
||||
inline Error &operator=(Error &&other);
|
||||
|
||||
inline GLenum getCode() const;
|
||||
inline GLuint getID() const;
|
||||
inline bool isError() const;
|
||||
|
||||
const std::string &getMessage() const;
|
||||
|
@ -43,10 +44,27 @@ class Error final
|
|||
void createMessageString() const;
|
||||
|
||||
GLenum mCode;
|
||||
mutable std::string *mMessage;
|
||||
GLuint mID;
|
||||
mutable std::unique_ptr<std::string> mMessage;
|
||||
};
|
||||
|
||||
}
|
||||
template <typename T>
|
||||
class ErrorOrResult
|
||||
{
|
||||
public:
|
||||
ErrorOrResult(const gl::Error &error) : mError(error) {}
|
||||
ErrorOrResult(T &&result) : mError(GL_NO_ERROR), mResult(std::move(result)) {}
|
||||
|
||||
bool isError() const { return mError.isError(); }
|
||||
const gl::Error &getError() const { return mError; }
|
||||
T &&getResult() { return std::move(mResult); }
|
||||
|
||||
private:
|
||||
Error mError;
|
||||
T mResult;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
@ -60,8 +78,6 @@ class Error final
|
|||
inline Error(const Error &other);
|
||||
inline Error(Error &&other);
|
||||
|
||||
inline ~Error();
|
||||
|
||||
inline Error &operator=(const Error &other);
|
||||
inline Error &operator=(Error &&other);
|
||||
|
||||
|
@ -76,10 +92,10 @@ class Error final
|
|||
|
||||
EGLint mCode;
|
||||
EGLint mID;
|
||||
mutable std::string *mMessage;
|
||||
mutable std::unique_ptr<std::string> mMessage;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace egl
|
||||
|
||||
#include "Error.inl"
|
||||
|
||||
|
|
|
@ -15,15 +15,15 @@ namespace gl
|
|||
|
||||
Error::Error(GLenum errorCode)
|
||||
: mCode(errorCode),
|
||||
mMessage(nullptr)
|
||||
mID(errorCode)
|
||||
{
|
||||
}
|
||||
|
||||
Error::Error(const Error &other)
|
||||
: mCode(other.mCode),
|
||||
mMessage(nullptr)
|
||||
mID(other.mID)
|
||||
{
|
||||
if (other.mMessage != nullptr)
|
||||
if (other.mMessage)
|
||||
{
|
||||
createMessageString();
|
||||
*mMessage = *(other.mMessage);
|
||||
|
@ -32,28 +32,24 @@ Error::Error(const Error &other)
|
|||
|
||||
Error::Error(Error &&other)
|
||||
: mCode(other.mCode),
|
||||
mMessage(other.mMessage)
|
||||
mID(other.mID),
|
||||
mMessage(std::move(other.mMessage))
|
||||
{
|
||||
other.mMessage = nullptr;
|
||||
}
|
||||
|
||||
Error::~Error()
|
||||
{
|
||||
SafeDelete(mMessage);
|
||||
}
|
||||
|
||||
Error &Error::operator=(const Error &other)
|
||||
{
|
||||
mCode = other.mCode;
|
||||
mID = other.mID;
|
||||
|
||||
if (other.mMessage != nullptr)
|
||||
if (other.mMessage)
|
||||
{
|
||||
createMessageString();
|
||||
*mMessage = *(other.mMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
SafeDelete(mMessage);
|
||||
mMessage.release();
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
@ -61,10 +57,12 @@ Error &Error::operator=(const Error &other)
|
|||
|
||||
Error &Error::operator=(Error &&other)
|
||||
{
|
||||
mCode = other.mCode;
|
||||
mMessage = other.mMessage;
|
||||
|
||||
other.mMessage = nullptr;
|
||||
if (this != &other)
|
||||
{
|
||||
mCode = other.mCode;
|
||||
mID = other.mID;
|
||||
mMessage = std::move(other.mMessage);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -74,6 +72,11 @@ GLenum Error::getCode() const
|
|||
return mCode;
|
||||
}
|
||||
|
||||
GLuint Error::getID() const
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
bool Error::isError() const
|
||||
{
|
||||
return (mCode != GL_NO_ERROR);
|
||||
|
@ -86,17 +89,15 @@ namespace egl
|
|||
|
||||
Error::Error(EGLint errorCode)
|
||||
: mCode(errorCode),
|
||||
mID(0),
|
||||
mMessage(nullptr)
|
||||
mID(0)
|
||||
{
|
||||
}
|
||||
|
||||
Error::Error(const Error &other)
|
||||
: mCode(other.mCode),
|
||||
mID(other.mID),
|
||||
mMessage(nullptr)
|
||||
mID(other.mID)
|
||||
{
|
||||
if (other.mMessage != nullptr)
|
||||
if (other.mMessage)
|
||||
{
|
||||
createMessageString();
|
||||
*mMessage = *(other.mMessage);
|
||||
|
@ -106,14 +107,8 @@ Error::Error(const Error &other)
|
|||
Error::Error(Error &&other)
|
||||
: mCode(other.mCode),
|
||||
mID(other.mID),
|
||||
mMessage(other.mMessage)
|
||||
mMessage(std::move(other.mMessage))
|
||||
{
|
||||
other.mMessage = nullptr;
|
||||
}
|
||||
|
||||
Error::~Error()
|
||||
{
|
||||
SafeDelete(mMessage);
|
||||
}
|
||||
|
||||
Error &Error::operator=(const Error &other)
|
||||
|
@ -121,14 +116,14 @@ Error &Error::operator=(const Error &other)
|
|||
mCode = other.mCode;
|
||||
mID = other.mID;
|
||||
|
||||
if (other.mMessage != nullptr)
|
||||
if (other.mMessage)
|
||||
{
|
||||
createMessageString();
|
||||
*mMessage = *(other.mMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
SafeDelete(mMessage);
|
||||
mMessage.release();
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
@ -136,11 +131,12 @@ Error &Error::operator=(const Error &other)
|
|||
|
||||
Error &Error::operator=(Error &&other)
|
||||
{
|
||||
mCode = other.mCode;
|
||||
mID = other.mID;
|
||||
mMessage = other.mMessage;
|
||||
|
||||
other.mMessage = nullptr;
|
||||
if (this != &other)
|
||||
{
|
||||
mCode = other.mCode;
|
||||
mID = other.mID;
|
||||
mMessage = std::move(other.mMessage);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -76,10 +76,7 @@ Error FenceNV::finish()
|
|||
}
|
||||
|
||||
FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id)
|
||||
: RefCountObject(id),
|
||||
mFence(impl),
|
||||
mCondition(GL_NONE),
|
||||
mFlags(0)
|
||||
: RefCountObject(id), mFence(impl), mLabel(), mCondition(GL_NONE), mFlags(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -88,6 +85,16 @@ FenceSync::~FenceSync()
|
|||
SafeDelete(mFence);
|
||||
}
|
||||
|
||||
void FenceSync::setLabel(const std::string &label)
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &FenceSync::getLabel() const
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
Error FenceSync::set(GLenum condition, GLbitfield flags)
|
||||
{
|
||||
Error error = mFence->set(condition, flags);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef LIBANGLE_FENCE_H_
|
||||
#define LIBANGLE_FENCE_H_
|
||||
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/Error.h"
|
||||
#include "libANGLE/RefCountObject.h"
|
||||
|
||||
|
@ -47,12 +48,15 @@ class FenceNV final : angle::NonCopyable
|
|||
GLenum mCondition;
|
||||
};
|
||||
|
||||
class FenceSync final : public RefCountObject
|
||||
class FenceSync final : public RefCountObject, public LabeledObject
|
||||
{
|
||||
public:
|
||||
explicit FenceSync(rx::FenceSyncImpl *impl, GLuint id);
|
||||
FenceSync(rx::FenceSyncImpl *impl, GLuint id);
|
||||
virtual ~FenceSync();
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
Error set(GLenum condition, GLbitfield flags);
|
||||
Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult);
|
||||
Error serverWait(GLbitfield flags, GLuint64 timeout);
|
||||
|
@ -64,6 +68,8 @@ class FenceSync final : public RefCountObject
|
|||
private:
|
||||
rx::FenceSyncImpl *mFence;
|
||||
|
||||
std::string mLabel;
|
||||
|
||||
GLenum mCondition;
|
||||
GLbitfield mFlags;
|
||||
};
|
||||
|
|
|
@ -40,7 +40,8 @@ void DetachMatchingAttachment(FramebufferAttachment *attachment, GLenum matchTyp
|
|||
}
|
||||
|
||||
Framebuffer::Data::Data()
|
||||
: mColorAttachments(1),
|
||||
: mLabel(),
|
||||
mColorAttachments(1),
|
||||
mDrawBufferStates(1, GL_NONE),
|
||||
mReadBufferState(GL_COLOR_ATTACHMENT0_EXT)
|
||||
{
|
||||
|
@ -48,10 +49,12 @@ Framebuffer::Data::Data()
|
|||
}
|
||||
|
||||
Framebuffer::Data::Data(const Caps &caps)
|
||||
: mColorAttachments(caps.maxColorAttachments),
|
||||
: mLabel(),
|
||||
mColorAttachments(caps.maxColorAttachments),
|
||||
mDrawBufferStates(caps.maxDrawBuffers, GL_NONE),
|
||||
mReadBufferState(GL_COLOR_ATTACHMENT0_EXT)
|
||||
{
|
||||
ASSERT(mDrawBufferStates.size() > 0);
|
||||
mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
|
||||
}
|
||||
|
||||
|
@ -59,6 +62,11 @@ Framebuffer::Data::~Data()
|
|||
{
|
||||
}
|
||||
|
||||
const std::string &Framebuffer::Data::getLabel()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
const FramebufferAttachment *Framebuffer::Data::getReadAttachment() const
|
||||
{
|
||||
ASSERT(mReadBufferState == GL_BACK || (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15));
|
||||
|
@ -179,6 +187,16 @@ Framebuffer::~Framebuffer()
|
|||
SafeDelete(mImpl);
|
||||
}
|
||||
|
||||
void Framebuffer::setLabel(const std::string &label)
|
||||
{
|
||||
mData.mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &Framebuffer::getLabel() const
|
||||
{
|
||||
return mData.mLabel;
|
||||
}
|
||||
|
||||
void Framebuffer::detachTexture(GLuint textureId)
|
||||
{
|
||||
detachResourceById(GL_TEXTURE, textureId);
|
||||
|
@ -270,10 +288,15 @@ const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
|
|||
}
|
||||
}
|
||||
|
||||
GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
|
||||
size_t Framebuffer::getDrawbufferStateCount() const
|
||||
{
|
||||
ASSERT(colorAttachment < mData.mDrawBufferStates.size());
|
||||
return mData.mDrawBufferStates[colorAttachment];
|
||||
return mData.mDrawBufferStates.size();
|
||||
}
|
||||
|
||||
GLenum Framebuffer::getDrawBufferState(size_t drawBuffer) const
|
||||
{
|
||||
ASSERT(drawBuffer < mData.mDrawBufferStates.size());
|
||||
return mData.mDrawBufferStates[drawBuffer];
|
||||
}
|
||||
|
||||
void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers)
|
||||
|
@ -283,7 +306,37 @@ void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers)
|
|||
ASSERT(count <= drawStates.size());
|
||||
std::copy(buffers, buffers + count, drawStates.begin());
|
||||
std::fill(drawStates.begin() + count, drawStates.end(), GL_NONE);
|
||||
mImpl->setDrawBuffers(count, buffers);
|
||||
mDirtyBits.set(DIRTY_BIT_DRAW_BUFFERS);
|
||||
}
|
||||
|
||||
const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const
|
||||
{
|
||||
ASSERT(drawBuffer < mData.mDrawBufferStates.size());
|
||||
if (mData.mDrawBufferStates[drawBuffer] != GL_NONE)
|
||||
{
|
||||
// ES3 spec: "If the GL is bound to a draw framebuffer object, the ith buffer listed in bufs
|
||||
// must be COLOR_ATTACHMENTi or NONE"
|
||||
ASSERT(mData.mDrawBufferStates[drawBuffer] == GL_COLOR_ATTACHMENT0 + drawBuffer ||
|
||||
(drawBuffer == 0 && mData.mDrawBufferStates[drawBuffer] == GL_BACK));
|
||||
return getAttachment(mData.mDrawBufferStates[drawBuffer]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Framebuffer::hasEnabledDrawBuffer() const
|
||||
{
|
||||
for (size_t drawbufferIdx = 0; drawbufferIdx < mData.mDrawBufferStates.size(); ++drawbufferIdx)
|
||||
{
|
||||
if (getDrawBuffer(drawbufferIdx) != nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
GLenum Framebuffer::getReadBufferState() const
|
||||
|
@ -297,27 +350,7 @@ void Framebuffer::setReadBuffer(GLenum buffer)
|
|||
(buffer >= GL_COLOR_ATTACHMENT0 &&
|
||||
(buffer - GL_COLOR_ATTACHMENT0) < mData.mColorAttachments.size()));
|
||||
mData.mReadBufferState = buffer;
|
||||
mImpl->setReadBuffer(buffer);
|
||||
}
|
||||
|
||||
bool Framebuffer::isEnabledColorAttachment(size_t colorAttachment) const
|
||||
{
|
||||
ASSERT(colorAttachment < mData.mColorAttachments.size());
|
||||
return (mData.mColorAttachments[colorAttachment].isAttached() &&
|
||||
mData.mDrawBufferStates[colorAttachment] != GL_NONE);
|
||||
}
|
||||
|
||||
bool Framebuffer::hasEnabledColorAttachment() const
|
||||
{
|
||||
for (size_t colorAttachment = 0; colorAttachment < mData.mColorAttachments.size(); ++colorAttachment)
|
||||
{
|
||||
if (isEnabledColorAttachment(static_cast<unsigned int>(colorAttachment)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
mDirtyBits.set(DIRTY_BIT_READ_BUFFER);
|
||||
}
|
||||
|
||||
size_t Framebuffer::getNumColorBuffers() const
|
||||
|
@ -337,9 +370,9 @@ bool Framebuffer::hasStencil() const
|
|||
|
||||
bool Framebuffer::usingExtendedDrawBuffers() const
|
||||
{
|
||||
for (size_t colorAttachment = 1; colorAttachment < mData.mColorAttachments.size(); ++colorAttachment)
|
||||
for (size_t drawbufferIdx = 1; drawbufferIdx < mData.mDrawBufferStates.size(); ++drawbufferIdx)
|
||||
{
|
||||
if (isEnabledColorAttachment(static_cast<unsigned int>(colorAttachment)))
|
||||
if (getDrawBuffer(drawbufferIdx) != nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -390,6 +423,17 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
|
|||
{
|
||||
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
|
||||
}
|
||||
|
||||
// ES3 specifies that cube map texture attachments must be cube complete.
|
||||
// This language is missing from the ES2 spec, but we enforce it here because some
|
||||
// desktop OpenGL drivers also enforce this validation.
|
||||
// TODO(jmadill): Check if OpenGL ES2 drivers enforce cube completeness.
|
||||
const Texture *texture = colorAttachment.getTexture();
|
||||
ASSERT(texture);
|
||||
if (texture->getTarget() == GL_TEXTURE_CUBE_MAP && !texture->isCubeComplete())
|
||||
{
|
||||
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
|
||||
}
|
||||
}
|
||||
else if (colorAttachment.type() == GL_RENDERBUFFER)
|
||||
{
|
||||
|
@ -539,6 +583,7 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
|
|||
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
|
||||
}
|
||||
|
||||
syncState();
|
||||
if (!mImpl->checkStatus())
|
||||
{
|
||||
return GL_FRAMEBUFFER_UNSUPPORTED;
|
||||
|
@ -562,81 +607,67 @@ Error Framebuffer::invalidateSub(size_t count, const GLenum *attachments, const
|
|||
return mImpl->invalidateSub(count, attachments, area);
|
||||
}
|
||||
|
||||
Error Framebuffer::clear(Context *context, GLbitfield mask)
|
||||
Error Framebuffer::clear(const gl::Data &data, GLbitfield mask)
|
||||
{
|
||||
if (context->getState().isRasterizerDiscardEnabled())
|
||||
if (data.state->isRasterizerDiscardEnabled())
|
||||
{
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
// Sync the clear state
|
||||
context->syncRendererState(context->getState().clearStateBitMask());
|
||||
|
||||
return mImpl->clear(context->getData(), mask);
|
||||
return mImpl->clear(data, mask);
|
||||
}
|
||||
|
||||
Error Framebuffer::clearBufferfv(Context *context,
|
||||
Error Framebuffer::clearBufferfv(const gl::Data &data,
|
||||
GLenum buffer,
|
||||
GLint drawbuffer,
|
||||
const GLfloat *values)
|
||||
{
|
||||
if (context->getState().isRasterizerDiscardEnabled())
|
||||
if (data.state->isRasterizerDiscardEnabled())
|
||||
{
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
// Sync the clear state
|
||||
context->syncRendererState(context->getState().clearStateBitMask());
|
||||
return mImpl->clearBufferfv(context->getData(), buffer, drawbuffer, values);
|
||||
return mImpl->clearBufferfv(data, buffer, drawbuffer, values);
|
||||
}
|
||||
|
||||
Error Framebuffer::clearBufferuiv(Context *context,
|
||||
Error Framebuffer::clearBufferuiv(const gl::Data &data,
|
||||
GLenum buffer,
|
||||
GLint drawbuffer,
|
||||
const GLuint *values)
|
||||
{
|
||||
if (context->getState().isRasterizerDiscardEnabled())
|
||||
if (data.state->isRasterizerDiscardEnabled())
|
||||
{
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
// Sync the clear state
|
||||
context->syncRendererState(context->getState().clearStateBitMask());
|
||||
|
||||
return mImpl->clearBufferuiv(context->getData(), buffer, drawbuffer, values);
|
||||
return mImpl->clearBufferuiv(data, buffer, drawbuffer, values);
|
||||
}
|
||||
|
||||
Error Framebuffer::clearBufferiv(Context *context,
|
||||
Error Framebuffer::clearBufferiv(const gl::Data &data,
|
||||
GLenum buffer,
|
||||
GLint drawbuffer,
|
||||
const GLint *values)
|
||||
{
|
||||
if (context->getState().isRasterizerDiscardEnabled())
|
||||
if (data.state->isRasterizerDiscardEnabled())
|
||||
{
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
// Sync the clear state
|
||||
context->syncRendererState(context->getState().clearStateBitMask());
|
||||
|
||||
return mImpl->clearBufferiv(context->getData(), buffer, drawbuffer, values);
|
||||
return mImpl->clearBufferiv(data, buffer, drawbuffer, values);
|
||||
}
|
||||
|
||||
Error Framebuffer::clearBufferfi(Context *context,
|
||||
Error Framebuffer::clearBufferfi(const gl::Data &data,
|
||||
GLenum buffer,
|
||||
GLint drawbuffer,
|
||||
GLfloat depth,
|
||||
GLint stencil)
|
||||
{
|
||||
if (context->getState().isRasterizerDiscardEnabled())
|
||||
if (data.state->isRasterizerDiscardEnabled())
|
||||
{
|
||||
return gl::Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
// Sync the clear state
|
||||
context->syncRendererState(context->getState().clearStateBitMask());
|
||||
|
||||
return mImpl->clearBufferfi(context->getData(), buffer, drawbuffer, depth, stencil);
|
||||
return mImpl->clearBufferfi(data, buffer, drawbuffer, depth, stencil);
|
||||
}
|
||||
|
||||
GLenum Framebuffer::getImplementationColorReadFormat() const
|
||||
|
@ -649,17 +680,12 @@ GLenum Framebuffer::getImplementationColorReadType() const
|
|||
return mImpl->getImplementationColorReadType();
|
||||
}
|
||||
|
||||
Error Framebuffer::readPixels(Context *context,
|
||||
const gl::Rectangle &area,
|
||||
Error Framebuffer::readPixels(const State &state,
|
||||
const Rectangle &area,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
GLvoid *pixels) const
|
||||
{
|
||||
const State &state = context->getState();
|
||||
|
||||
// Sync pack state
|
||||
context->syncRendererState(state.packStateBitMask());
|
||||
|
||||
Error error = mImpl->readPixels(state, area, format, type, pixels);
|
||||
if (error.isError())
|
||||
{
|
||||
|
@ -675,17 +701,13 @@ Error Framebuffer::readPixels(Context *context,
|
|||
return Error(GL_NO_ERROR);
|
||||
}
|
||||
|
||||
Error Framebuffer::blit(Context *context,
|
||||
const gl::Rectangle &sourceArea,
|
||||
const gl::Rectangle &destArea,
|
||||
Error Framebuffer::blit(const State &state,
|
||||
const Rectangle &sourceArea,
|
||||
const Rectangle &destArea,
|
||||
GLbitfield mask,
|
||||
GLenum filter,
|
||||
const gl::Framebuffer *sourceFramebuffer)
|
||||
const Framebuffer *sourceFramebuffer)
|
||||
{
|
||||
// Sync blit state
|
||||
const State &state = context->getState();
|
||||
context->syncRendererState(state.blitStateBitMask());
|
||||
|
||||
return mImpl->blit(state, sourceArea, destArea, mask, filter, sourceFramebuffer);
|
||||
}
|
||||
|
||||
|
@ -735,32 +757,33 @@ void Framebuffer::setAttachment(GLenum type,
|
|||
|
||||
mData.mDepthAttachment.attach(type, binding, textureIndex, attachmentObj);
|
||||
mData.mStencilAttachment.attach(type, binding, textureIndex, attachmentObj);
|
||||
mImpl->onUpdateDepthStencilAttachment();
|
||||
mDirtyBits.set(DIRTY_BIT_DEPTH_ATTACHMENT);
|
||||
mDirtyBits.set(DIRTY_BIT_STENCIL_ATTACHMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (binding)
|
||||
{
|
||||
case GL_DEPTH:
|
||||
case GL_DEPTH_ATTACHMENT:
|
||||
mData.mDepthAttachment.attach(type, binding, textureIndex, resource);
|
||||
mImpl->onUpdateDepthAttachment();
|
||||
case GL_DEPTH:
|
||||
case GL_DEPTH_ATTACHMENT:
|
||||
mData.mDepthAttachment.attach(type, binding, textureIndex, resource);
|
||||
mDirtyBits.set(DIRTY_BIT_DEPTH_ATTACHMENT);
|
||||
break;
|
||||
case GL_STENCIL:
|
||||
case GL_STENCIL_ATTACHMENT:
|
||||
mData.mStencilAttachment.attach(type, binding, textureIndex, resource);
|
||||
mImpl->onUpdateStencilAttachment();
|
||||
case GL_STENCIL:
|
||||
case GL_STENCIL_ATTACHMENT:
|
||||
mData.mStencilAttachment.attach(type, binding, textureIndex, resource);
|
||||
mDirtyBits.set(DIRTY_BIT_STENCIL_ATTACHMENT);
|
||||
break;
|
||||
case GL_BACK:
|
||||
mData.mColorAttachments[0].attach(type, binding, textureIndex, resource);
|
||||
mImpl->onUpdateColorAttachment(0);
|
||||
case GL_BACK:
|
||||
mData.mColorAttachments[0].attach(type, binding, textureIndex, resource);
|
||||
mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0);
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
{
|
||||
size_t colorIndex = binding - GL_COLOR_ATTACHMENT0;
|
||||
ASSERT(colorIndex < mData.mColorAttachments.size());
|
||||
mData.mColorAttachments[colorIndex].attach(type, binding, textureIndex, resource);
|
||||
mImpl->onUpdateColorAttachment(colorIndex);
|
||||
mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -772,4 +795,13 @@ void Framebuffer::resetAttachment(GLenum binding)
|
|||
setAttachment(GL_NONE, binding, ImageIndex::MakeInvalid(), nullptr);
|
||||
}
|
||||
|
||||
void Framebuffer::syncState() const
|
||||
{
|
||||
if (mDirtyBits.any())
|
||||
{
|
||||
mImpl->syncState(mDirtyBits);
|
||||
mDirtyBits.reset();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "common/angleutils.h"
|
||||
#include "libANGLE/Constants.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/Error.h"
|
||||
#include "libANGLE/FramebufferAttachment.h"
|
||||
#include "libANGLE/RefCountObject.h"
|
||||
|
@ -44,7 +45,7 @@ struct Extensions;
|
|||
struct ImageIndex;
|
||||
struct Rectangle;
|
||||
|
||||
class Framebuffer
|
||||
class Framebuffer final : public LabeledObject
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -55,6 +56,8 @@ class Framebuffer
|
|||
explicit Data(const Caps &caps);
|
||||
~Data();
|
||||
|
||||
const std::string &getLabel();
|
||||
|
||||
const FramebufferAttachment *getReadAttachment() const;
|
||||
const FramebufferAttachment *getFirstColorAttachment() const;
|
||||
const FramebufferAttachment *getDepthOrStencilAttachment() const;
|
||||
|
@ -64,6 +67,7 @@ class Framebuffer
|
|||
const FramebufferAttachment *getDepthStencilAttachment() const;
|
||||
|
||||
const std::vector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; }
|
||||
GLenum getReadBufferState() const { return mReadBufferState; }
|
||||
const std::vector<FramebufferAttachment> &getColorAttachments() const { return mColorAttachments; }
|
||||
|
||||
bool attachmentsHaveSameDimensions() const;
|
||||
|
@ -71,6 +75,8 @@ class Framebuffer
|
|||
private:
|
||||
friend class Framebuffer;
|
||||
|
||||
std::string mLabel;
|
||||
|
||||
std::vector<FramebufferAttachment> mColorAttachments;
|
||||
FramebufferAttachment mDepthAttachment;
|
||||
FramebufferAttachment mStencilAttachment;
|
||||
|
@ -83,6 +89,9 @@ class Framebuffer
|
|||
Framebuffer(rx::SurfaceImpl *surface);
|
||||
virtual ~Framebuffer();
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
const rx::FramebufferImpl *getImplementation() const { return mImpl; }
|
||||
rx::FramebufferImpl *getImplementation() { return mImpl; }
|
||||
|
||||
|
@ -108,14 +117,15 @@ class Framebuffer
|
|||
|
||||
const FramebufferAttachment *getAttachment(GLenum attachment) const;
|
||||
|
||||
GLenum getDrawBufferState(unsigned int colorAttachment) const;
|
||||
size_t getDrawbufferStateCount() const;
|
||||
GLenum getDrawBufferState(size_t drawBuffer) const;
|
||||
void setDrawBuffers(size_t count, const GLenum *buffers);
|
||||
const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const;
|
||||
bool hasEnabledDrawBuffer() const;
|
||||
|
||||
GLenum getReadBufferState() const;
|
||||
void setReadBuffer(GLenum buffer);
|
||||
|
||||
bool isEnabledColorAttachment(size_t colorAttachment) const;
|
||||
bool hasEnabledColorAttachment() const;
|
||||
size_t getNumColorBuffers() const;
|
||||
bool hasDepth() const;
|
||||
bool hasStencil() const;
|
||||
|
@ -129,11 +139,17 @@ class Framebuffer
|
|||
Error invalidate(size_t count, const GLenum *attachments);
|
||||
Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area);
|
||||
|
||||
Error clear(Context *context, GLbitfield mask);
|
||||
Error clearBufferfv(Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *values);
|
||||
Error clearBufferuiv(Context *context, GLenum buffer, GLint drawbuffer, const GLuint *values);
|
||||
Error clearBufferiv(Context *context, GLenum buffer, GLint drawbuffer, const GLint *values);
|
||||
Error clearBufferfi(Context *context,
|
||||
Error clear(const gl::Data &data, GLbitfield mask);
|
||||
Error clearBufferfv(const gl::Data &data,
|
||||
GLenum buffer,
|
||||
GLint drawbuffer,
|
||||
const GLfloat *values);
|
||||
Error clearBufferuiv(const gl::Data &data,
|
||||
GLenum buffer,
|
||||
GLint drawbuffer,
|
||||
const GLuint *values);
|
||||
Error clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values);
|
||||
Error clearBufferfi(const gl::Data &data,
|
||||
GLenum buffer,
|
||||
GLint drawbuffer,
|
||||
GLfloat depth,
|
||||
|
@ -141,18 +157,36 @@ class Framebuffer
|
|||
|
||||
GLenum getImplementationColorReadFormat() const;
|
||||
GLenum getImplementationColorReadType() const;
|
||||
Error readPixels(Context *context,
|
||||
Error readPixels(const gl::State &state,
|
||||
const gl::Rectangle &area,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
GLvoid *pixels) const;
|
||||
|
||||
Error blit(Context *context,
|
||||
const gl::Rectangle &sourceArea,
|
||||
const gl::Rectangle &destArea,
|
||||
Error blit(const State &state,
|
||||
const Rectangle &sourceArea,
|
||||
const Rectangle &destArea,
|
||||
GLbitfield mask,
|
||||
GLenum filter,
|
||||
const gl::Framebuffer *sourceFramebuffer);
|
||||
const Framebuffer *sourceFramebuffer);
|
||||
|
||||
enum DirtyBitType
|
||||
{
|
||||
DIRTY_BIT_COLOR_ATTACHMENT_0,
|
||||
DIRTY_BIT_COLOR_ATTACHMENT_MAX =
|
||||
DIRTY_BIT_COLOR_ATTACHMENT_0 + gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS,
|
||||
DIRTY_BIT_DEPTH_ATTACHMENT = DIRTY_BIT_COLOR_ATTACHMENT_MAX,
|
||||
DIRTY_BIT_STENCIL_ATTACHMENT,
|
||||
DIRTY_BIT_DRAW_BUFFERS,
|
||||
DIRTY_BIT_READ_BUFFER,
|
||||
DIRTY_BIT_UNKNOWN,
|
||||
DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN,
|
||||
};
|
||||
|
||||
typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
|
||||
bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
|
||||
|
||||
void syncState() const;
|
||||
|
||||
protected:
|
||||
void detachResourceById(GLenum resourceType, GLuint resourceId);
|
||||
|
@ -160,6 +194,9 @@ class Framebuffer
|
|||
Data mData;
|
||||
rx::FramebufferImpl *mImpl;
|
||||
GLuint mId;
|
||||
|
||||
// TODO(jmadill): See if we can make this non-mutable.
|
||||
mutable DirtyBits mDirtyBits;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -126,8 +126,9 @@ void HandleAllocator::reserve(GLuint handle)
|
|||
}
|
||||
if (begin != handle)
|
||||
{
|
||||
ASSERT(begin < handle);
|
||||
mUnallocatedList.insert(placementIt, HandleRange(begin, handle));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace gl
|
||||
|
|
|
@ -58,6 +58,6 @@ class HandleAllocator final : angle::NonCopyable
|
|||
std::vector<GLuint> mReleasedList;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace gl
|
||||
|
||||
#endif // LIBANGLE_HANDLEALLOCATOR_H_
|
||||
|
|
|
@ -223,7 +223,8 @@ VariableLocation::VariableLocation(const std::string &name, unsigned int element
|
|||
}
|
||||
|
||||
Program::Data::Data()
|
||||
: mAttachedFragmentShader(nullptr),
|
||||
: mLabel(),
|
||||
mAttachedFragmentShader(nullptr),
|
||||
mAttachedVertexShader(nullptr),
|
||||
mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS),
|
||||
mBinaryRetrieveableHint(false)
|
||||
|
@ -243,6 +244,11 @@ Program::Data::~Data()
|
|||
}
|
||||
}
|
||||
|
||||
const std::string &Program::Data::getLabel()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
const LinkedUniform *Program::Data::getUniformByName(const std::string &name) const
|
||||
{
|
||||
for (const LinkedUniform &linkedUniform : mUniforms)
|
||||
|
@ -328,6 +334,16 @@ Program::~Program()
|
|||
SafeDelete(mProgram);
|
||||
}
|
||||
|
||||
void Program::setLabel(const std::string &label)
|
||||
{
|
||||
mData.mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &Program::getLabel() const
|
||||
{
|
||||
return mData.mLabel;
|
||||
}
|
||||
|
||||
bool Program::attachShader(Shader *shader)
|
||||
{
|
||||
if (shader->getType() == GL_VERTEX_SHADER)
|
||||
|
@ -2361,7 +2377,7 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu
|
|||
// Track the first and last uniform index to determine the range of active uniforms in the
|
||||
// block.
|
||||
size_t firstBlockUniformIndex = mData.mUniforms.size();
|
||||
defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex);
|
||||
defineUniformBlockMembers(interfaceBlock.fields, interfaceBlock.fieldPrefix(), blockIndex);
|
||||
size_t lastBlockUniformIndex = mData.mUniforms.size();
|
||||
|
||||
std::vector<unsigned int> blockUniformIndexes;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "libANGLE/angletypes.h"
|
||||
#include "libANGLE/Constants.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/Error.h"
|
||||
#include "libANGLE/RefCountObject.h"
|
||||
|
||||
|
@ -143,7 +144,7 @@ struct VariableLocation
|
|||
unsigned int index;
|
||||
};
|
||||
|
||||
class Program : angle::NonCopyable
|
||||
class Program final : angle::NonCopyable, public LabeledObject
|
||||
{
|
||||
public:
|
||||
class Data final : angle::NonCopyable
|
||||
|
@ -152,6 +153,8 @@ class Program : angle::NonCopyable
|
|||
Data();
|
||||
~Data();
|
||||
|
||||
const std::string &getLabel();
|
||||
|
||||
const Shader *getAttachedVertexShader() const { return mAttachedVertexShader; }
|
||||
const Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; }
|
||||
const std::vector<std::string> &getTransformFeedbackVaryingNames() const
|
||||
|
@ -191,6 +194,8 @@ class Program : angle::NonCopyable
|
|||
private:
|
||||
friend class Program;
|
||||
|
||||
std::string mLabel;
|
||||
|
||||
Shader *mAttachedFragmentShader;
|
||||
Shader *mAttachedVertexShader;
|
||||
|
||||
|
@ -224,6 +229,9 @@ class Program : angle::NonCopyable
|
|||
|
||||
GLuint id() const { return mHandle; }
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
rx::ProgramImpl *getImplementation() { return mProgram; }
|
||||
const rx::ProgramImpl *getImplementation() const { return mProgram; }
|
||||
|
||||
|
|
|
@ -11,9 +11,7 @@
|
|||
|
||||
namespace gl
|
||||
{
|
||||
Query::Query(rx::QueryImpl *impl, GLuint id)
|
||||
: RefCountObject(id),
|
||||
mQuery(impl)
|
||||
Query::Query(rx::QueryImpl *impl, GLuint id) : RefCountObject(id), mQuery(impl), mLabel()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -22,6 +20,16 @@ Query::~Query()
|
|||
SafeDelete(mQuery);
|
||||
}
|
||||
|
||||
void Query::setLabel(const std::string &label)
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &Query::getLabel() const
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
Error Query::begin()
|
||||
{
|
||||
return mQuery->begin();
|
||||
|
@ -32,12 +40,32 @@ Error Query::end()
|
|||
return mQuery->end();
|
||||
}
|
||||
|
||||
Error Query::queryCounter()
|
||||
{
|
||||
return mQuery->queryCounter();
|
||||
}
|
||||
|
||||
Error Query::getResult(GLint *params)
|
||||
{
|
||||
return mQuery->getResult(params);
|
||||
}
|
||||
|
||||
Error Query::getResult(GLuint *params)
|
||||
{
|
||||
return mQuery->getResult(params);
|
||||
}
|
||||
|
||||
Error Query::isResultAvailable(GLuint *available)
|
||||
Error Query::getResult(GLint64 *params)
|
||||
{
|
||||
return mQuery->getResult(params);
|
||||
}
|
||||
|
||||
Error Query::getResult(GLuint64 *params)
|
||||
{
|
||||
return mQuery->getResult(params);
|
||||
}
|
||||
|
||||
Error Query::isResultAvailable(bool *available)
|
||||
{
|
||||
return mQuery->isResultAvailable(available);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef LIBANGLE_QUERY_H_
|
||||
#define LIBANGLE_QUERY_H_
|
||||
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/Error.h"
|
||||
#include "libANGLE/RefCountObject.h"
|
||||
|
||||
|
@ -24,17 +25,23 @@ class QueryImpl;
|
|||
namespace gl
|
||||
{
|
||||
|
||||
class Query : public RefCountObject
|
||||
class Query final : public RefCountObject, public LabeledObject
|
||||
{
|
||||
public:
|
||||
Query(rx::QueryImpl *impl, GLuint id);
|
||||
virtual ~Query();
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
Error begin();
|
||||
Error end();
|
||||
|
||||
Error queryCounter();
|
||||
Error getResult(GLint *params);
|
||||
Error getResult(GLuint *params);
|
||||
Error isResultAvailable(GLuint *available);
|
||||
Error getResult(GLint64 *params);
|
||||
Error getResult(GLuint64 *params);
|
||||
Error isResultAvailable(bool *available);
|
||||
|
||||
GLenum getType() const;
|
||||
|
||||
|
@ -43,6 +50,8 @@ class Query : public RefCountObject
|
|||
|
||||
private:
|
||||
rx::QueryImpl *mQuery;
|
||||
|
||||
std::string mLabel;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// RefCountObject.cpp: Defines the gl::RefCountObject base class that provides
|
||||
// lifecycle support for GL objects using the traditional BindObject scheme, but
|
||||
// that need to be reference counted for correct cross-context deletion.
|
||||
// (Concretely, textures, buffers and renderbuffers.)
|
||||
|
||||
#include "RefCountObject.h"
|
||||
|
||||
RefCountObject::RefCountObject(GLuint id)
|
||||
: mId(id),
|
||||
mRefCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
RefCountObject::~RefCountObject()
|
||||
{
|
||||
ASSERT(mRefCount == 0);
|
||||
}
|
||||
|
||||
void RefCountObject::addRef() const
|
||||
{
|
||||
mRefCount++;
|
||||
}
|
||||
|
||||
void RefCountObject::release() const
|
||||
{
|
||||
ASSERT(mRefCount > 0);
|
||||
|
||||
if (--mRefCount == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
|
@ -21,16 +21,27 @@
|
|||
class RefCountObject : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
explicit RefCountObject(GLuint id);
|
||||
virtual ~RefCountObject();
|
||||
explicit RefCountObject(GLuint id) : mId(id), mRefCount(0) {}
|
||||
|
||||
virtual void addRef() const;
|
||||
virtual void release() const;
|
||||
void addRef() const { ++mRefCount; }
|
||||
|
||||
void release() const
|
||||
{
|
||||
ASSERT(mRefCount > 0);
|
||||
|
||||
if (--mRefCount == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
GLuint id() const { return mId; }
|
||||
|
||||
size_t getRefCount() const { return mRefCount; }
|
||||
|
||||
protected:
|
||||
virtual ~RefCountObject() { ASSERT(mRefCount == 0); }
|
||||
|
||||
private:
|
||||
GLuint mId;
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace gl
|
|||
Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id)
|
||||
: egl::ImageSibling(id),
|
||||
mRenderbuffer(impl),
|
||||
mLabel(),
|
||||
mWidth(0),
|
||||
mHeight(0),
|
||||
mInternalFormat(GL_RGBA4),
|
||||
|
@ -34,6 +35,16 @@ Renderbuffer::~Renderbuffer()
|
|||
SafeDelete(mRenderbuffer);
|
||||
}
|
||||
|
||||
void Renderbuffer::setLabel(const std::string &label)
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &Renderbuffer::getLabel() const
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
Error Renderbuffer::setStorage(GLenum internalformat, size_t width, size_t height)
|
||||
{
|
||||
orphanImages();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "angle_gl.h"
|
||||
#include "common/angleutils.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/Error.h"
|
||||
#include "libANGLE/FramebufferAttachment.h"
|
||||
#include "libANGLE/Image.h"
|
||||
|
@ -25,12 +26,17 @@ namespace gl
|
|||
// FramebufferAttachment and Framebuffer for how they are applied to an FBO via an
|
||||
// attachment point.
|
||||
|
||||
class Renderbuffer : public egl::ImageSibling, public gl::FramebufferAttachmentObject
|
||||
class Renderbuffer final : public egl::ImageSibling,
|
||||
public gl::FramebufferAttachmentObject,
|
||||
public LabeledObject
|
||||
{
|
||||
public:
|
||||
Renderbuffer(rx::RenderbufferImpl *impl, GLuint id);
|
||||
virtual ~Renderbuffer();
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
Error setStorage(GLenum internalformat, size_t width, size_t height);
|
||||
Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height);
|
||||
Error setStorageEGLImageTarget(egl::Image *imageTarget);
|
||||
|
@ -63,6 +69,8 @@ class Renderbuffer : public egl::ImageSibling, public gl::FramebufferAttachmentO
|
|||
|
||||
rx::RenderbufferImpl *mRenderbuffer;
|
||||
|
||||
std::string mLabel;
|
||||
|
||||
GLsizei mWidth;
|
||||
GLsizei mHeight;
|
||||
GLenum mInternalFormat;
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace gl
|
|||
{
|
||||
|
||||
Sampler::Sampler(rx::ImplFactory *factory, GLuint id)
|
||||
: RefCountObject(id), mImpl(factory->createSampler()), mSamplerState()
|
||||
: RefCountObject(id), mImpl(factory->createSampler()), mLabel(), mSamplerState()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,16 @@ Sampler::~Sampler()
|
|||
SafeDelete(mImpl);
|
||||
}
|
||||
|
||||
void Sampler::setLabel(const std::string &label)
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &Sampler::getLabel() const
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
void Sampler::setMinFilter(GLenum minFilter)
|
||||
{
|
||||
mSamplerState.minFilter = minFilter;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define LIBANGLE_SAMPLER_H_
|
||||
|
||||
#include "libANGLE/angletypes.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/RefCountObject.h"
|
||||
|
||||
namespace rx
|
||||
|
@ -22,12 +23,15 @@ class SamplerImpl;
|
|||
namespace gl
|
||||
{
|
||||
|
||||
class Sampler final : public RefCountObject
|
||||
class Sampler final : public RefCountObject, public LabeledObject
|
||||
{
|
||||
public:
|
||||
Sampler(rx::ImplFactory *factory, GLuint id);
|
||||
~Sampler() override;
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
void setMinFilter(GLenum minFilter);
|
||||
GLenum getMinFilter() const;
|
||||
|
||||
|
@ -66,6 +70,8 @@ class Sampler final : public RefCountObject
|
|||
private:
|
||||
rx::SamplerImpl *mImpl;
|
||||
|
||||
std::string mLabel;
|
||||
|
||||
SamplerState mSamplerState;
|
||||
};
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y)
|
|||
return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
|
||||
}
|
||||
|
||||
Shader::Data::Data(GLenum shaderType) : mShaderType(shaderType), mShaderVersion(100)
|
||||
Shader::Data::Data(GLenum shaderType) : mLabel(), mShaderType(shaderType), mShaderVersion(100)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,16 @@ Shader::~Shader()
|
|||
SafeDelete(mImplementation);
|
||||
}
|
||||
|
||||
void Shader::setLabel(const std::string &label)
|
||||
{
|
||||
mData.mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &Shader::getLabel() const
|
||||
{
|
||||
return mData.mLabel;
|
||||
}
|
||||
|
||||
GLuint Shader::getHandle() const
|
||||
{
|
||||
return mHandle;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "common/angleutils.h"
|
||||
#include "libANGLE/angletypes.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
@ -36,7 +37,7 @@ struct Limitations;
|
|||
class ResourceManager;
|
||||
struct Data;
|
||||
|
||||
class Shader : angle::NonCopyable
|
||||
class Shader final : angle::NonCopyable, public LabeledObject
|
||||
{
|
||||
public:
|
||||
class Data final : angle::NonCopyable
|
||||
|
@ -45,6 +46,8 @@ class Shader : angle::NonCopyable
|
|||
Data(GLenum shaderType);
|
||||
~Data();
|
||||
|
||||
const std::string &getLabel() const { return mLabel; }
|
||||
|
||||
const std::string &getSource() const { return mSource; }
|
||||
const std::string &getTranslatedSource() const { return mTranslatedSource; }
|
||||
|
||||
|
@ -66,6 +69,8 @@ class Shader : angle::NonCopyable
|
|||
private:
|
||||
friend class Shader;
|
||||
|
||||
std::string mLabel;
|
||||
|
||||
GLenum mShaderType;
|
||||
int mShaderVersion;
|
||||
std::string mTranslatedSource;
|
||||
|
@ -86,6 +91,9 @@ class Shader : angle::NonCopyable
|
|||
|
||||
virtual ~Shader();
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
GLenum getType() const { return mType; }
|
||||
GLuint getHandle() const;
|
||||
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
|
||||
#include "libANGLE/State.h"
|
||||
|
||||
#include "common/BitSetIterator.h"
|
||||
#include "libANGLE/Context.h"
|
||||
#include "libANGLE/Caps.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/Framebuffer.h"
|
||||
#include "libANGLE/FramebufferAttachment.h"
|
||||
#include "libANGLE/Query.h"
|
||||
|
@ -78,7 +80,10 @@ State::~State()
|
|||
reset();
|
||||
}
|
||||
|
||||
void State::initialize(const Caps &caps, GLuint clientVersion)
|
||||
void State::initialize(const Caps &caps,
|
||||
const Extensions &extensions,
|
||||
GLuint clientVersion,
|
||||
bool debug)
|
||||
{
|
||||
mMaxDrawBuffers = caps.maxDrawBuffers;
|
||||
mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
|
||||
|
@ -175,16 +180,20 @@ void State::initialize(const Caps &caps, GLuint clientVersion)
|
|||
|
||||
mSamplers.resize(caps.maxCombinedTextureImageUnits);
|
||||
|
||||
mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
|
||||
mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
|
||||
mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
|
||||
mActiveQueries[GL_ANY_SAMPLES_PASSED].set(nullptr);
|
||||
mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(nullptr);
|
||||
mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(nullptr);
|
||||
mActiveQueries[GL_TIME_ELAPSED_EXT].set(nullptr);
|
||||
|
||||
mProgram = NULL;
|
||||
mProgram = nullptr;
|
||||
|
||||
mReadFramebuffer = NULL;
|
||||
mDrawFramebuffer = NULL;
|
||||
mReadFramebuffer = nullptr;
|
||||
mDrawFramebuffer = nullptr;
|
||||
|
||||
mPrimitiveRestart = false;
|
||||
|
||||
mDebug.setOutputEnabled(debug);
|
||||
mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
|
||||
}
|
||||
|
||||
void State::reset()
|
||||
|
@ -581,6 +590,12 @@ void State::setEnableFeature(GLenum feature, bool enabled)
|
|||
case GL_DITHER: setDither(enabled); break;
|
||||
case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
|
||||
case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
|
||||
case GL_DEBUG_OUTPUT_SYNCHRONOUS:
|
||||
mDebug.setOutputSynchronous(enabled);
|
||||
break;
|
||||
case GL_DEBUG_OUTPUT:
|
||||
mDebug.setOutputEnabled(enabled);
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
@ -600,6 +615,10 @@ bool State::getEnableFeature(GLenum feature)
|
|||
case GL_DITHER: return isDitherEnabled();
|
||||
case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
|
||||
case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
|
||||
case GL_DEBUG_OUTPUT_SYNCHRONOUS:
|
||||
return mDebug.isOutputSynchronous();
|
||||
case GL_DEBUG_OUTPUT:
|
||||
return mDebug.isOutputEnabled();
|
||||
default: UNREACHABLE(); return false;
|
||||
}
|
||||
}
|
||||
|
@ -659,6 +678,11 @@ void State::setSamplerTexture(GLenum type, Texture *texture)
|
|||
mSamplerTextures[type][mActiveSampler].set(texture);
|
||||
}
|
||||
|
||||
Texture *State::getTargetTexture(GLenum target) const
|
||||
{
|
||||
return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
|
||||
}
|
||||
|
||||
Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
|
||||
{
|
||||
const auto it = mSamplerTextures.find(type);
|
||||
|
@ -812,22 +836,44 @@ void State::detachRenderbuffer(GLuint renderbuffer)
|
|||
|
||||
void State::setReadFramebufferBinding(Framebuffer *framebuffer)
|
||||
{
|
||||
if (mReadFramebuffer == framebuffer)
|
||||
return;
|
||||
|
||||
mReadFramebuffer = framebuffer;
|
||||
mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
|
||||
|
||||
if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
|
||||
{
|
||||
mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
|
||||
{
|
||||
if (mDrawFramebuffer == framebuffer)
|
||||
return;
|
||||
|
||||
mDrawFramebuffer = framebuffer;
|
||||
mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
|
||||
|
||||
if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
|
||||
{
|
||||
mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
Framebuffer *State::getTargetFramebuffer(GLenum target) const
|
||||
{
|
||||
switch (target)
|
||||
{
|
||||
case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
|
||||
case GL_DRAW_FRAMEBUFFER_ANGLE:
|
||||
case GL_FRAMEBUFFER: return mDrawFramebuffer;
|
||||
default: UNREACHABLE(); return NULL;
|
||||
case GL_READ_FRAMEBUFFER_ANGLE:
|
||||
return mReadFramebuffer;
|
||||
case GL_DRAW_FRAMEBUFFER_ANGLE:
|
||||
case GL_FRAMEBUFFER:
|
||||
return mDrawFramebuffer;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -856,7 +902,7 @@ bool State::removeReadFramebufferBinding(GLuint framebuffer)
|
|||
if (mReadFramebuffer != nullptr &&
|
||||
mReadFramebuffer->id() == framebuffer)
|
||||
{
|
||||
mReadFramebuffer = NULL;
|
||||
setReadFramebufferBinding(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -868,7 +914,7 @@ bool State::removeDrawFramebufferBinding(GLuint framebuffer)
|
|||
if (mReadFramebuffer != nullptr &&
|
||||
mDrawFramebuffer->id() == framebuffer)
|
||||
{
|
||||
mDrawFramebuffer = NULL;
|
||||
setDrawFramebufferBinding(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -879,7 +925,11 @@ void State::setVertexArrayBinding(VertexArray *vertexArray)
|
|||
{
|
||||
mVertexArray = vertexArray;
|
||||
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
|
||||
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
|
||||
|
||||
if (mVertexArray && mVertexArray->hasAnyDirtyBit())
|
||||
{
|
||||
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
GLuint State::getVertexArrayId() const
|
||||
|
@ -900,7 +950,7 @@ bool State::removeVertexArrayBinding(GLuint vertexArray)
|
|||
{
|
||||
mVertexArray = NULL;
|
||||
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
|
||||
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
|
||||
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -956,10 +1006,22 @@ void State::detachTransformFeedback(GLuint transformFeedback)
|
|||
|
||||
bool State::isQueryActive() const
|
||||
{
|
||||
for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
|
||||
i != mActiveQueries.end(); i++)
|
||||
for (auto &iter : mActiveQueries)
|
||||
{
|
||||
if (i->second.get() != NULL)
|
||||
if (iter.second.get() != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool State::isQueryActive(Query *query) const
|
||||
{
|
||||
for (auto &iter : mActiveQueries)
|
||||
{
|
||||
if (iter.second.get() == query)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -1076,7 +1138,7 @@ void State::detachBuffer(GLuint bufferName)
|
|||
void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
|
||||
{
|
||||
getVertexArray()->enableAttribute(attribNum, enabled);
|
||||
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
|
||||
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
void State::setVertexAttribf(GLuint index, const GLfloat values[4])
|
||||
|
@ -1110,13 +1172,13 @@ void State::setVertexAttribState(unsigned int attribNum,
|
|||
const void *pointer)
|
||||
{
|
||||
getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
|
||||
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
|
||||
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
|
||||
{
|
||||
getVertexArray()->setVertexAttribDivisor(index, divisor);
|
||||
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
|
||||
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
|
||||
|
@ -1271,6 +1333,16 @@ PixelUnpackState &State::getUnpackState()
|
|||
return mUnpack;
|
||||
}
|
||||
|
||||
const Debug &State::getDebug() const
|
||||
{
|
||||
return mDebug;
|
||||
}
|
||||
|
||||
Debug &State::getDebug()
|
||||
{
|
||||
return mDebug;
|
||||
}
|
||||
|
||||
void State::getBooleanv(GLenum pname, GLboolean *params)
|
||||
{
|
||||
switch (pname)
|
||||
|
@ -1300,6 +1372,12 @@ void State::getBooleanv(GLenum pname, GLboolean *params)
|
|||
case GL_RASTERIZER_DISCARD:
|
||||
*params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
|
||||
break;
|
||||
case GL_DEBUG_OUTPUT_SYNCHRONOUS:
|
||||
*params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
|
||||
break;
|
||||
case GL_DEBUG_OUTPUT:
|
||||
*params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
@ -1557,12 +1635,37 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
|
|||
case GL_PIXEL_UNPACK_BUFFER_BINDING:
|
||||
*params = mUnpack.pixelBuffer.id();
|
||||
break;
|
||||
case GL_DEBUG_LOGGED_MESSAGES:
|
||||
*params = static_cast<GLint>(mDebug.getMessageCount());
|
||||
break;
|
||||
case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
|
||||
*params = static_cast<GLint>(mDebug.getNextMessageLength());
|
||||
break;
|
||||
case GL_DEBUG_GROUP_STACK_DEPTH:
|
||||
*params = static_cast<GLint>(mDebug.getGroupStackDepth());
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void State::getPointerv(GLenum pname, void **params) const
|
||||
{
|
||||
switch (pname)
|
||||
{
|
||||
case GL_DEBUG_CALLBACK_FUNCTION:
|
||||
*params = reinterpret_cast<void *>(mDebug.getCallback());
|
||||
break;
|
||||
case GL_DEBUG_CALLBACK_USER_PARAM:
|
||||
*params = const_cast<void *>(mDebug.getUserParam());
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
|
||||
{
|
||||
switch (target)
|
||||
|
@ -1647,4 +1750,92 @@ bool State::hasMappedBuffer(GLenum target) const
|
|||
}
|
||||
}
|
||||
|
||||
void State::syncDirtyObjects()
|
||||
{
|
||||
if (!mDirtyObjects.any())
|
||||
return;
|
||||
|
||||
syncDirtyObjects(mDirtyObjects);
|
||||
}
|
||||
|
||||
void State::syncDirtyObjects(const DirtyObjects &bitset)
|
||||
{
|
||||
for (auto dirtyObject : angle::IterateBitSet(bitset))
|
||||
{
|
||||
switch (dirtyObject)
|
||||
{
|
||||
case DIRTY_OBJECT_READ_FRAMEBUFFER:
|
||||
ASSERT(mReadFramebuffer);
|
||||
mReadFramebuffer->syncState();
|
||||
break;
|
||||
case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
|
||||
ASSERT(mDrawFramebuffer);
|
||||
mDrawFramebuffer->syncState();
|
||||
break;
|
||||
case DIRTY_OBJECT_VERTEX_ARRAY:
|
||||
ASSERT(mVertexArray);
|
||||
mVertexArray->syncImplState();
|
||||
break;
|
||||
case DIRTY_OBJECT_PROGRAM:
|
||||
// TODO(jmadill): implement this
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mDirtyObjects &= ~bitset;
|
||||
}
|
||||
|
||||
void State::syncDirtyObject(GLenum target)
|
||||
{
|
||||
DirtyObjects localSet;
|
||||
|
||||
switch (target)
|
||||
{
|
||||
case GL_READ_FRAMEBUFFER:
|
||||
localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
|
||||
break;
|
||||
case GL_DRAW_FRAMEBUFFER:
|
||||
localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
|
||||
break;
|
||||
case GL_FRAMEBUFFER:
|
||||
localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
|
||||
localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
|
||||
break;
|
||||
case GL_VERTEX_ARRAY:
|
||||
localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
|
||||
break;
|
||||
case GL_PROGRAM:
|
||||
localSet.set(DIRTY_OBJECT_PROGRAM);
|
||||
break;
|
||||
}
|
||||
|
||||
syncDirtyObjects(localSet);
|
||||
}
|
||||
|
||||
void State::setObjectDirty(GLenum target)
|
||||
{
|
||||
switch (target)
|
||||
{
|
||||
case GL_READ_FRAMEBUFFER:
|
||||
mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
|
||||
break;
|
||||
case GL_DRAW_FRAMEBUFFER:
|
||||
mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
|
||||
break;
|
||||
case GL_FRAMEBUFFER:
|
||||
mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
|
||||
mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
|
||||
break;
|
||||
case GL_VERTEX_ARRAY:
|
||||
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
|
||||
break;
|
||||
case GL_PROGRAM:
|
||||
mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
#define LIBANGLE_STATE_H_
|
||||
|
||||
#include <bitset>
|
||||
#include <memory>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/Program.h"
|
||||
#include "libANGLE/RefCountObject.h"
|
||||
#include "libANGLE/Renderbuffer.h"
|
||||
|
@ -29,7 +31,7 @@ class Context;
|
|||
struct Caps;
|
||||
struct Data;
|
||||
|
||||
typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
|
||||
typedef std::map<GLenum, BindingPointer<Texture>> TextureMap;
|
||||
|
||||
class State : angle::NonCopyable
|
||||
{
|
||||
|
@ -37,7 +39,10 @@ class State : angle::NonCopyable
|
|||
State();
|
||||
~State();
|
||||
|
||||
void initialize(const Caps& caps, GLuint clientVersion);
|
||||
void initialize(const Caps &caps,
|
||||
const Extensions &extensions,
|
||||
GLuint clientVersion,
|
||||
bool debug);
|
||||
void reset();
|
||||
|
||||
// State chunk getters
|
||||
|
@ -144,6 +149,7 @@ class State : angle::NonCopyable
|
|||
void setActiveSampler(unsigned int active);
|
||||
unsigned int getActiveSampler() const;
|
||||
void setSamplerTexture(GLenum type, Texture *texture);
|
||||
Texture *getTargetTexture(GLenum target) const;
|
||||
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
|
||||
GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const;
|
||||
void detachTexture(const TextureMap &zeroTextures, GLuint texture);
|
||||
|
@ -190,6 +196,7 @@ class State : angle::NonCopyable
|
|||
|
||||
// Query binding manipulation
|
||||
bool isQueryActive() const;
|
||||
bool isQueryActive(Query *query) const;
|
||||
void setActiveQuery(GLenum target, Query *query);
|
||||
GLuint getActiveQueryId(GLenum target) const;
|
||||
Query *getActiveQuery(GLenum target) const;
|
||||
|
@ -258,10 +265,15 @@ class State : angle::NonCopyable
|
|||
const PixelUnpackState &getUnpackState() const;
|
||||
PixelUnpackState &getUnpackState();
|
||||
|
||||
// Debug state
|
||||
const Debug &getDebug() const;
|
||||
Debug &getDebug();
|
||||
|
||||
// State query functions
|
||||
void getBooleanv(GLenum pname, GLboolean *params);
|
||||
void getFloatv(GLenum pname, GLfloat *params);
|
||||
void getIntegerv(const gl::Data &data, GLenum pname, GLint *params);
|
||||
void getPointerv(GLenum pname, void **params) const;
|
||||
bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data);
|
||||
bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data);
|
||||
|
||||
|
@ -317,26 +329,41 @@ class State : angle::NonCopyable
|
|||
DIRTY_BIT_GENERATE_MIPMAP_HINT,
|
||||
DIRTY_BIT_SHADER_DERIVATIVE_HINT,
|
||||
DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
|
||||
DIRTY_BIT_READ_FRAMEBUFFER_OBJECT,
|
||||
DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
|
||||
DIRTY_BIT_DRAW_FRAMEBUFFER_OBJECT,
|
||||
DIRTY_BIT_RENDERBUFFER_BINDING,
|
||||
DIRTY_BIT_VERTEX_ARRAY_BINDING,
|
||||
DIRTY_BIT_VERTEX_ARRAY_OBJECT,
|
||||
DIRTY_BIT_PROGRAM_BINDING,
|
||||
DIRTY_BIT_PROGRAM_OBJECT,
|
||||
DIRTY_BIT_CURRENT_VALUE_0,
|
||||
DIRTY_BIT_CURRENT_VALUE_MAX = DIRTY_BIT_CURRENT_VALUE_0 + MAX_VERTEX_ATTRIBS,
|
||||
DIRTY_BIT_INVALID = DIRTY_BIT_CURRENT_VALUE_MAX,
|
||||
DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
|
||||
};
|
||||
|
||||
// TODO(jmadill): Consider storing dirty objects in a list instead of by binding.
|
||||
enum DirtyObjectType
|
||||
{
|
||||
DIRTY_OBJECT_READ_FRAMEBUFFER,
|
||||
DIRTY_OBJECT_DRAW_FRAMEBUFFER,
|
||||
DIRTY_OBJECT_VERTEX_ARRAY,
|
||||
DIRTY_OBJECT_PROGRAM,
|
||||
DIRTY_OBJECT_UNKNOWN,
|
||||
DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
|
||||
};
|
||||
|
||||
typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
|
||||
const DirtyBits &getDirtyBits() const { return mDirtyBits; }
|
||||
void clearDirtyBits() { mDirtyBits.reset(); }
|
||||
void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
|
||||
void setAllDirtyBits() { mDirtyBits.set(); }
|
||||
|
||||
typedef std::bitset<DIRTY_OBJECT_MAX> DirtyObjects;
|
||||
void clearDirtyObjects() { mDirtyObjects.reset(); }
|
||||
void setAllDirtyObjects() { mDirtyObjects.set(); }
|
||||
void syncDirtyObjects();
|
||||
void syncDirtyObjects(const DirtyObjects &bitset);
|
||||
void syncDirtyObject(GLenum target);
|
||||
void setObjectDirty(GLenum target);
|
||||
|
||||
// Dirty bit masks
|
||||
const DirtyBits &unpackStateBitMask() const { return mUnpackStateBitMask; }
|
||||
const DirtyBits &packStateBitMask() const { return mPackStateBitMask; }
|
||||
|
@ -388,18 +415,18 @@ class State : angle::NonCopyable
|
|||
// Texture and sampler bindings
|
||||
size_t mActiveSampler; // Active texture unit selector - GL_TEXTURE0
|
||||
|
||||
typedef std::vector< BindingPointer<Texture> > TextureBindingVector;
|
||||
typedef std::vector<BindingPointer<Texture>> TextureBindingVector;
|
||||
typedef std::map<GLenum, TextureBindingVector> TextureBindingMap;
|
||||
TextureBindingMap mSamplerTextures;
|
||||
|
||||
typedef std::vector< BindingPointer<Sampler> > SamplerBindingVector;
|
||||
typedef std::vector<BindingPointer<Sampler>> SamplerBindingVector;
|
||||
SamplerBindingVector mSamplers;
|
||||
|
||||
typedef std::map< GLenum, BindingPointer<Query> > ActiveQueryMap;
|
||||
typedef std::map<GLenum, BindingPointer<Query>> ActiveQueryMap;
|
||||
ActiveQueryMap mActiveQueries;
|
||||
|
||||
BindingPointer<Buffer> mGenericUniformBuffer;
|
||||
typedef std::vector< OffsetBindingPointer<Buffer> > BufferVector;
|
||||
typedef std::vector<OffsetBindingPointer<Buffer>> BufferVector;
|
||||
BufferVector mUniformBuffers;
|
||||
|
||||
BindingPointer<TransformFeedback> mTransformFeedback;
|
||||
|
@ -412,11 +439,15 @@ class State : angle::NonCopyable
|
|||
|
||||
bool mPrimitiveRestart;
|
||||
|
||||
Debug mDebug;
|
||||
|
||||
DirtyBits mDirtyBits;
|
||||
DirtyBits mUnpackStateBitMask;
|
||||
DirtyBits mPackStateBitMask;
|
||||
DirtyBits mClearStateBitMask;
|
||||
DirtyBits mBlitStateBitMask;
|
||||
|
||||
DirtyObjects mDirtyObjects;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -41,9 +41,15 @@ Surface::Surface(rx::SurfaceImpl *impl,
|
|||
// FIXME: Determine actual pixel aspect ratio
|
||||
mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
|
||||
mRenderBuffer(EGL_BACK_BUFFER),
|
||||
mSwapBehavior(impl->getSwapBehavior())
|
||||
mSwapBehavior(impl->getSwapBehavior()),
|
||||
mOrientation(0),
|
||||
mTexture()
|
||||
{
|
||||
mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
|
||||
mFlexibleSurfaceCompatibilityRequested =
|
||||
(attributes.get(EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_FALSE) == EGL_TRUE);
|
||||
|
||||
mDirectComposition = (attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE);
|
||||
|
||||
mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
|
||||
if (mFixedSize)
|
||||
|
@ -58,6 +64,8 @@ Surface::Surface(rx::SurfaceImpl *impl,
|
|||
mTextureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
|
||||
}
|
||||
|
||||
mOrientation = attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0);
|
||||
|
||||
mDefaultFramebuffer = createDefaultFramebuffer();
|
||||
ASSERT(mDefaultFramebuffer != nullptr);
|
||||
}
|
||||
|
|
|
@ -78,6 +78,14 @@ class Surface final : public gl::FramebufferAttachmentObject
|
|||
void onDetach() override {}
|
||||
GLuint getId() const override;
|
||||
|
||||
bool flexibleSurfaceCompatibilityRequested() const
|
||||
{
|
||||
return mFlexibleSurfaceCompatibilityRequested;
|
||||
}
|
||||
EGLint getOrientation() const { return mOrientation; }
|
||||
|
||||
bool directComposition() const { return mDirectComposition; }
|
||||
|
||||
private:
|
||||
virtual ~Surface();
|
||||
rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override { return mImplementation; }
|
||||
|
@ -98,11 +106,14 @@ class Surface final : public gl::FramebufferAttachmentObject
|
|||
const egl::Config *mConfig;
|
||||
|
||||
bool mPostSubBufferRequested;
|
||||
bool mFlexibleSurfaceCompatibilityRequested;
|
||||
|
||||
bool mFixedSize;
|
||||
size_t mFixedWidth;
|
||||
size_t mFixedHeight;
|
||||
|
||||
bool mDirectComposition;
|
||||
|
||||
EGLenum mTextureFormat;
|
||||
EGLenum mTextureTarget;
|
||||
|
||||
|
@ -110,6 +121,8 @@ class Surface final : public gl::FramebufferAttachmentObject
|
|||
EGLenum mRenderBuffer; // Render buffer
|
||||
EGLenum mSwapBehavior; // Buffer swap behavior
|
||||
|
||||
EGLint mOrientation;
|
||||
|
||||
BindingPointer<gl::Texture> mTexture;
|
||||
};
|
||||
|
||||
|
|
|
@ -51,10 +51,6 @@ TEST(SurfaceTest, DestructionDeletesImpl)
|
|||
EXPECT_CALL(*impl, getSwapBehavior());
|
||||
EXPECT_CALL(*impl, createDefaultFramebuffer(testing::_)).WillOnce(testing::Return(framebuffer));
|
||||
|
||||
EXPECT_CALL(*framebuffer, setDrawBuffers(1, testing::_));
|
||||
EXPECT_CALL(*framebuffer, setReadBuffer(GL_BACK));
|
||||
EXPECT_CALL(*framebuffer, onUpdateColorAttachment(0));
|
||||
|
||||
egl::Config config;
|
||||
egl::Surface *surface = new egl::Surface(impl, EGL_WINDOW_BIT, &config, egl::AttributeMap());
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ static size_t GetImageDescIndex(GLenum target, size_t level)
|
|||
Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
|
||||
: egl::ImageSibling(id),
|
||||
mTexture(impl),
|
||||
mLabel(),
|
||||
mTextureState(),
|
||||
mTarget(target),
|
||||
mImageDescs(IMPLEMENTATION_MAX_TEXTURE_LEVELS * (target == GL_TEXTURE_CUBE_MAP ? 6 : 1)),
|
||||
|
@ -68,6 +69,16 @@ Texture::~Texture()
|
|||
SafeDelete(mTexture);
|
||||
}
|
||||
|
||||
void Texture::setLabel(const std::string &label)
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &Texture::getLabel() const
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
GLenum Texture::getTarget() const
|
||||
{
|
||||
return mTarget;
|
||||
|
@ -801,19 +812,21 @@ bool Texture::computeLevelCompleteness(GLenum target, size_t level) const
|
|||
return false;
|
||||
}
|
||||
|
||||
if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> level))
|
||||
ASSERT(level >= mTextureState.baseLevel);
|
||||
const size_t relativeLevel = level - mTextureState.baseLevel;
|
||||
if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> relativeLevel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> level))
|
||||
if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> relativeLevel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mTarget == GL_TEXTURE_3D)
|
||||
{
|
||||
if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> level))
|
||||
if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> relativeLevel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "angle_gl.h"
|
||||
#include "common/debug.h"
|
||||
#include "libANGLE/Caps.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/Constants.h"
|
||||
#include "libANGLE/Error.h"
|
||||
#include "libANGLE/FramebufferAttachment.h"
|
||||
|
@ -33,14 +34,19 @@ class Context;
|
|||
class Framebuffer;
|
||||
struct Data;
|
||||
|
||||
bool IsMipmapFiltered(const gl::SamplerState &samplerState);
|
||||
bool IsMipmapFiltered(const SamplerState &samplerState);
|
||||
|
||||
class Texture final : public egl::ImageSibling, public gl::FramebufferAttachmentObject
|
||||
class Texture final : public egl::ImageSibling,
|
||||
public FramebufferAttachmentObject,
|
||||
public LabeledObject
|
||||
{
|
||||
public:
|
||||
Texture(rx::TextureImpl *impl, GLuint id, GLenum target);
|
||||
~Texture() override;
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
GLenum getTarget() const;
|
||||
|
||||
void setSwizzleRed(GLenum swizzleRed);
|
||||
|
@ -184,6 +190,8 @@ class Texture final : public egl::ImageSibling, public gl::FramebufferAttachment
|
|||
|
||||
rx::TextureImpl *mTexture;
|
||||
|
||||
std::string mLabel;
|
||||
|
||||
TextureState mTextureState;
|
||||
|
||||
GLenum mTarget;
|
||||
|
|
|
@ -13,9 +13,10 @@
|
|||
namespace gl
|
||||
{
|
||||
|
||||
TransformFeedback::TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id, const Caps &caps)
|
||||
TransformFeedback::TransformFeedback(rx::TransformFeedbackImpl *impl, GLuint id, const Caps &caps)
|
||||
: RefCountObject(id),
|
||||
mImplementation(impl),
|
||||
mLabel(),
|
||||
mActive(false),
|
||||
mPrimitiveMode(GL_NONE),
|
||||
mPaused(false),
|
||||
|
@ -36,6 +37,16 @@ TransformFeedback::~TransformFeedback()
|
|||
SafeDelete(mImplementation);
|
||||
}
|
||||
|
||||
void TransformFeedback::setLabel(const std::string &label)
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &TransformFeedback::getLabel() const
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
void TransformFeedback::begin(GLenum primitiveMode)
|
||||
{
|
||||
mActive = true;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "libANGLE/RefCountObject.h"
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
|
||||
#include "angle_gl.h"
|
||||
|
||||
|
@ -23,12 +24,15 @@ namespace gl
|
|||
class Buffer;
|
||||
struct Caps;
|
||||
|
||||
class TransformFeedback : public RefCountObject
|
||||
class TransformFeedback final : public RefCountObject, public LabeledObject
|
||||
{
|
||||
public:
|
||||
TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id, const Caps &caps);
|
||||
virtual ~TransformFeedback();
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
void begin(GLenum primitiveMode);
|
||||
void end();
|
||||
void pause();
|
||||
|
@ -53,6 +57,8 @@ class TransformFeedback : public RefCountObject
|
|||
private:
|
||||
rx::TransformFeedbackImpl* mImplementation;
|
||||
|
||||
std::string mLabel;
|
||||
|
||||
bool mActive;
|
||||
GLenum mPrimitiveMode;
|
||||
bool mPaused;
|
||||
|
|
|
@ -15,8 +15,7 @@ namespace gl
|
|||
{
|
||||
|
||||
VertexArray::Data::Data(size_t maxAttribs)
|
||||
: mVertexAttributes(maxAttribs),
|
||||
mMaxEnabledAttribute(0)
|
||||
: mLabel(), mVertexAttributes(maxAttribs), mMaxEnabledAttribute(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -46,6 +45,16 @@ GLuint VertexArray::id() const
|
|||
return mId;
|
||||
}
|
||||
|
||||
void VertexArray::setLabel(const std::string &label)
|
||||
{
|
||||
mData.mLabel = label;
|
||||
}
|
||||
|
||||
const std::string &VertexArray::getLabel() const
|
||||
{
|
||||
return mData.mLabel;
|
||||
}
|
||||
|
||||
void VertexArray::detachBuffer(GLuint bufferName)
|
||||
{
|
||||
for (size_t attribute = 0; attribute < getMaxAttribs(); attribute++)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "libANGLE/RefCountObject.h"
|
||||
#include "libANGLE/Constants.h"
|
||||
#include "libANGLE/Debug.h"
|
||||
#include "libANGLE/State.h"
|
||||
#include "libANGLE/VertexAttribute.h"
|
||||
|
||||
|
@ -30,7 +31,7 @@ namespace gl
|
|||
{
|
||||
class Buffer;
|
||||
|
||||
class VertexArray
|
||||
class VertexArray final : public LabeledObject
|
||||
{
|
||||
public:
|
||||
VertexArray(rx::ImplFactory *factory, GLuint id, size_t maxAttribs);
|
||||
|
@ -38,6 +39,9 @@ class VertexArray
|
|||
|
||||
GLuint id() const;
|
||||
|
||||
void setLabel(const std::string &label) override;
|
||||
const std::string &getLabel() const override;
|
||||
|
||||
const VertexAttribute &getVertexAttribute(size_t attributeIndex) const;
|
||||
|
||||
void detachBuffer(GLuint bufferName);
|
||||
|
@ -63,6 +67,8 @@ class VertexArray
|
|||
explicit Data(size_t maxAttribs);
|
||||
~Data();
|
||||
|
||||
const std::string &getLabel() const { return mLabel; }
|
||||
|
||||
const BindingPointer<Buffer> &getElementArrayBuffer() const { return mElementArrayBuffer; }
|
||||
size_t getMaxAttribs() const { return mVertexAttributes.size(); }
|
||||
size_t getMaxEnabledAttribute() const { return mMaxEnabledAttribute; }
|
||||
|
@ -74,6 +80,7 @@ class VertexArray
|
|||
|
||||
private:
|
||||
friend class VertexArray;
|
||||
std::string mLabel;
|
||||
std::vector<VertexAttribute> mVertexAttributes;
|
||||
BindingPointer<Buffer> mElementArrayBuffer;
|
||||
size_t mMaxEnabledAttribute;
|
||||
|
@ -102,6 +109,7 @@ class VertexArray
|
|||
typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
|
||||
|
||||
void syncImplState();
|
||||
bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
|
||||
|
||||
private:
|
||||
GLuint mId;
|
||||
|
|
|
@ -219,6 +219,54 @@ static bool RequireExtOrExt(GLuint, const Extensions &extensions)
|
|||
return extensions.*bool1 || extensions.*bool2;
|
||||
}
|
||||
|
||||
// Special function for half float formats with three or four channels.
|
||||
static bool HalfFloatSupport(GLuint clientVersion, const Extensions &extensions)
|
||||
{
|
||||
return clientVersion >= 3 || extensions.textureHalfFloat;
|
||||
}
|
||||
|
||||
static bool HalfFloatRenderableSupport(GLuint clientVersion, const Extensions &extensions)
|
||||
{
|
||||
return HalfFloatSupport(clientVersion, extensions) && extensions.colorBufferHalfFloat;
|
||||
}
|
||||
|
||||
// Special function for half float formats with one or two channels.
|
||||
static bool HalfFloatSupportRG(GLuint clientVersion, const Extensions &extensions)
|
||||
{
|
||||
return clientVersion >= 3 || (extensions.textureHalfFloat && extensions.textureRG);
|
||||
}
|
||||
|
||||
static bool HalfFloatRenderableSupportRG(GLuint clientVersion, const Extensions &extensions)
|
||||
{
|
||||
return HalfFloatSupportRG(clientVersion, extensions) && extensions.colorBufferHalfFloat;
|
||||
}
|
||||
|
||||
// Special function for float formats with three or four channels.
|
||||
static bool FloatSupport(GLuint clientVersion, const Extensions &extensions)
|
||||
{
|
||||
return clientVersion >= 3 || extensions.textureFloat;
|
||||
}
|
||||
|
||||
static bool FloatRenderableSupport(GLuint clientVersion, const Extensions &extensions)
|
||||
{
|
||||
// We don't expose colorBufferFloat in ES2, but we silently support rendering to float.
|
||||
return FloatSupport(clientVersion, extensions) &&
|
||||
(extensions.colorBufferFloat || clientVersion == 2);
|
||||
}
|
||||
|
||||
// Special function for float formats with one or two channels.
|
||||
static bool FloatSupportRG(GLuint clientVersion, const Extensions &extensions)
|
||||
{
|
||||
return clientVersion >= 3 || (extensions.textureFloat && extensions.textureRG);
|
||||
}
|
||||
|
||||
static bool FloatRenderableSupportRG(GLuint clientVersion, const Extensions &extensions)
|
||||
{
|
||||
// We don't expose colorBufferFloat in ES2, but we silently support rendering to float.
|
||||
return FloatSupportRG(clientVersion, extensions) &&
|
||||
(extensions.colorBufferFloat || clientVersion == 2);
|
||||
}
|
||||
|
||||
InternalFormat::InternalFormat()
|
||||
: redBits(0),
|
||||
greenBits(0),
|
||||
|
@ -400,16 +448,16 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap()
|
|||
map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported)));
|
||||
|
||||
// Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
|
||||
// | Internal format | | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable |
|
||||
// | | | | | | | type | | | | |
|
||||
map.insert(InternalFormatInfoPair(GL_R16F, RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureHalfFloatLinear>)));
|
||||
map.insert(InternalFormatInfoPair(GL_RG16F, RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureHalfFloatLinear>)));
|
||||
map.insert(InternalFormatInfoPair(GL_RGB16F, RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>)));
|
||||
map.insert(InternalFormatInfoPair(GL_RGBA16F, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>)));
|
||||
map.insert(InternalFormatInfoPair(GL_R32F, RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureFloatLinear> )));
|
||||
map.insert(InternalFormatInfoPair(GL_RG32F, RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureFloatLinear> )));
|
||||
map.insert(InternalFormatInfoPair(GL_RGB32F, RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureFloat>, RequireESOrExt<3, &Extensions::textureFloat>, RequireExt<&Extensions::textureFloatLinear> )));
|
||||
map.insert(InternalFormatInfoPair(GL_RGBA32F, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureFloat>, RequireESOrExt<3, &Extensions::textureFloat>, RequireExt<&Extensions::textureFloatLinear> )));
|
||||
// | Internal format | | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable |
|
||||
// | | | | | | | type | | | | |
|
||||
map.insert(InternalFormatInfoPair(GL_R16F, RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupportRG, HalfFloatRenderableSupportRG, RequireExt<&Extensions::textureHalfFloatLinear>)));
|
||||
map.insert(InternalFormatInfoPair(GL_RG16F, RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupportRG, HalfFloatRenderableSupportRG, RequireExt<&Extensions::textureHalfFloatLinear>)));
|
||||
map.insert(InternalFormatInfoPair(GL_RGB16F, RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRenderableSupport, RequireExt<&Extensions::textureHalfFloatLinear>)));
|
||||
map.insert(InternalFormatInfoPair(GL_RGBA16F, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRenderableSupport, RequireExt<&Extensions::textureHalfFloatLinear>)));
|
||||
map.insert(InternalFormatInfoPair(GL_R32F, RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, FloatSupportRG, FloatRenderableSupportRG, RequireExt<&Extensions::textureFloatLinear> )));
|
||||
map.insert(InternalFormatInfoPair(GL_RG32F, RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, FloatSupportRG, FloatRenderableSupportRG, RequireExt<&Extensions::textureFloatLinear> )));
|
||||
map.insert(InternalFormatInfoPair(GL_RGB32F, RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRenderableSupport, RequireExt<&Extensions::textureFloatLinear> )));
|
||||
map.insert(InternalFormatInfoPair(GL_RGBA32F, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRenderableSupport, RequireExt<&Extensions::textureFloatLinear> )));
|
||||
|
||||
// Depth stencil formats
|
||||
// | Internal format | | D |S | X | Format | Type | Component type | Supported | Renderable | Filterable |
|
||||
|
@ -517,6 +565,10 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap()
|
|||
// - It affects only validation of internalformat in RenderbufferStorageMultisample.
|
||||
// | Internal format | |D |S |X | Format | Type | Component type | Supported | Renderable | Filterable |
|
||||
map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, DepthStencilFormat(0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, NeverSupported)));
|
||||
|
||||
// From GL_ANGLE_lossy_etc_decode
|
||||
map.insert(InternalFormatInfoPair(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, CompressedFormat(4, 4, 64, 3, GL_ETC1_RGB8_OES, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported)));
|
||||
|
||||
// clang-format on
|
||||
|
||||
return map;
|
||||
|
|
|
@ -113,6 +113,7 @@ UNIFIED_SOURCES += [
|
|||
'Config.cpp',
|
||||
'Context.cpp',
|
||||
'Data.cpp',
|
||||
'Debug.cpp',
|
||||
'Device.cpp',
|
||||
'Error.cpp',
|
||||
'Fence.cpp',
|
||||
|
@ -127,7 +128,6 @@ UNIFIED_SOURCES += [
|
|||
'Program.cpp',
|
||||
'Query.cpp',
|
||||
'queryconversions.cpp',
|
||||
'RefCountObject.cpp',
|
||||
'Renderbuffer.cpp',
|
||||
'renderer/d3d/BufferD3D.cpp',
|
||||
'renderer/d3d/CompilerD3D.cpp',
|
||||
|
@ -145,6 +145,7 @@ UNIFIED_SOURCES += [
|
|||
'renderer/d3d/d3d9/renderer9_utils.cpp',
|
||||
'renderer/d3d/d3d9/RenderTarget9.cpp',
|
||||
'renderer/d3d/d3d9/ShaderExecutable9.cpp',
|
||||
'renderer/d3d/d3d9/StateManager9.cpp',
|
||||
'renderer/d3d/d3d9/SwapChain9.cpp',
|
||||
'renderer/d3d/d3d9/TextureStorage9.cpp',
|
||||
'renderer/d3d/d3d9/VertexBuffer9.cpp',
|
||||
|
@ -196,6 +197,7 @@ UNIFIED_SOURCES += [
|
|||
'renderer/gl/TransformFeedbackGL.cpp',
|
||||
'renderer/gl/VertexArrayGL.cpp',
|
||||
'renderer/gl/wgl/DisplayWGL.cpp',
|
||||
'renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp',
|
||||
'renderer/gl/wgl/FunctionsWGL.cpp',
|
||||
'renderer/gl/wgl/PbufferSurfaceWGL.cpp',
|
||||
'renderer/gl/wgl/wgl_utils.cpp',
|
||||
|
@ -253,11 +255,11 @@ if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
|
|||
'renderer/d3d/d3d11/TextureStorage11.cpp',
|
||||
'renderer/d3d/d3d11/Trim11.cpp',
|
||||
'renderer/d3d/d3d11/VertexBuffer11.cpp',
|
||||
'renderer/d3d/d3d11/win32/NativeWindow.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
|
||||
SOURCES += [
|
||||
'renderer/d3d/d3d11/SwapChain11.cpp',
|
||||
'renderer/d3d/d3d11/win32/NativeWindow.cpp',
|
||||
]
|
||||
|
||||
|
||||
|
@ -307,6 +309,8 @@ LOCAL_INCLUDES += [ '../../include', '../../src', '../../src/third_party/khronos
|
|||
|
||||
DEFINES['LIBANGLE_IMPLEMENTATION'] = "1"
|
||||
DEFINES['ANGLE_ENABLE_HLSL'] = "1"
|
||||
DEFINES['ANGLE_ENABLE_GLSL'] = "1"
|
||||
DEFINES['ANGLE_ENABLE_ESSL'] = "1"
|
||||
DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
|
||||
DEFINES['ANGLE_DEFAULT_D3D11'] = "0"
|
||||
|
||||
|
|
|
@ -64,8 +64,9 @@ class DisplayImpl : angle::NonCopyable
|
|||
egl::ImageSibling *buffer,
|
||||
const egl::AttributeMap &attribs) = 0;
|
||||
|
||||
virtual egl::Error createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs,
|
||||
gl::Context **outContext) = 0;
|
||||
virtual gl::Context *createContext(const egl::Config *config,
|
||||
const gl::Context *shareContext,
|
||||
const egl::AttributeMap &attribs) = 0;
|
||||
|
||||
virtual egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) = 0;
|
||||
|
||||
|
@ -81,6 +82,11 @@ class DisplayImpl : angle::NonCopyable
|
|||
|
||||
virtual egl::Error getDevice(DeviceImpl **device) = 0;
|
||||
|
||||
virtual egl::Error waitClient() const = 0;
|
||||
virtual egl::Error waitNative(EGLint engine,
|
||||
egl::Surface *drawSurface,
|
||||
egl::Surface *readSurface) const = 0;
|
||||
|
||||
const egl::Caps &getCaps() const;
|
||||
|
||||
typedef std::set<egl::Surface*> SurfaceSet;
|
||||
|
|
|
@ -31,14 +31,6 @@ class FramebufferImpl : angle::NonCopyable
|
|||
explicit FramebufferImpl(const gl::Framebuffer::Data &data) : mData(data) { }
|
||||
virtual ~FramebufferImpl() { }
|
||||
|
||||
virtual void onUpdateColorAttachment(size_t index) = 0;
|
||||
virtual void onUpdateDepthAttachment() = 0;
|
||||
virtual void onUpdateStencilAttachment() = 0;
|
||||
virtual void onUpdateDepthStencilAttachment() = 0;
|
||||
|
||||
virtual void setDrawBuffers(size_t count, const GLenum *buffers) = 0;
|
||||
virtual void setReadBuffer(GLenum buffer) = 0;
|
||||
|
||||
virtual gl::Error discard(size_t count, const GLenum *attachments) = 0;
|
||||
virtual gl::Error invalidate(size_t count, const GLenum *attachments) = 0;
|
||||
virtual gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) = 0;
|
||||
|
@ -71,6 +63,8 @@ class FramebufferImpl : angle::NonCopyable
|
|||
|
||||
virtual bool checkStatus() const = 0;
|
||||
|
||||
virtual void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) = 0;
|
||||
|
||||
const gl::Framebuffer::Data &getData() const { return mData; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -23,14 +23,6 @@ class MockFramebufferImpl : public rx::FramebufferImpl
|
|||
MockFramebufferImpl() : rx::FramebufferImpl(gl::Framebuffer::Data()) {}
|
||||
virtual ~MockFramebufferImpl() { destroy(); }
|
||||
|
||||
MOCK_METHOD1(onUpdateColorAttachment, void(size_t));
|
||||
MOCK_METHOD0(onUpdateDepthAttachment, void());
|
||||
MOCK_METHOD0(onUpdateStencilAttachment, void());
|
||||
MOCK_METHOD0(onUpdateDepthStencilAttachment, void());
|
||||
|
||||
MOCK_METHOD2(setDrawBuffers, void(size_t, const GLenum *));
|
||||
MOCK_METHOD1(setReadBuffer, void(GLenum));
|
||||
|
||||
MOCK_METHOD2(discard, gl::Error(size_t, const GLenum *));
|
||||
MOCK_METHOD2(invalidate, gl::Error(size_t, const GLenum *));
|
||||
MOCK_METHOD3(invalidateSub, gl::Error(size_t, const GLenum *, const gl::Rectangle &));
|
||||
|
@ -57,9 +49,24 @@ class MockFramebufferImpl : public rx::FramebufferImpl
|
|||
|
||||
MOCK_CONST_METHOD0(checkStatus, bool());
|
||||
|
||||
MOCK_METHOD1(syncState, void(const gl::Framebuffer::DirtyBits &));
|
||||
|
||||
MOCK_METHOD0(destroy, void());
|
||||
};
|
||||
|
||||
inline ::testing::NiceMock<MockFramebufferImpl> *MakeFramebufferMock()
|
||||
{
|
||||
::testing::NiceMock<MockFramebufferImpl> *framebufferImpl =
|
||||
new ::testing::NiceMock<MockFramebufferImpl>();
|
||||
// TODO(jmadill): add ON_CALLS for other returning methods
|
||||
ON_CALL(*framebufferImpl, checkStatus()).WillByDefault(::testing::Return(true));
|
||||
|
||||
// We must mock the destructor since NiceMock doesn't work for destructors.
|
||||
EXPECT_CALL(*framebufferImpl, destroy()).Times(1).RetiresOnSaturation();
|
||||
|
||||
return framebufferImpl;
|
||||
}
|
||||
|
||||
} // namespace rx
|
||||
|
||||
#endif // LIBANGLE_RENDERER_FRAMEBUFFERIMPLMOCK_H_
|
||||
|
|
|
@ -60,6 +60,16 @@ class MockProgramImpl : public rx::ProgramImpl
|
|||
MOCK_METHOD0(destroy, void());
|
||||
};
|
||||
|
||||
inline ::testing::NiceMock<MockProgramImpl> *MakeProgramMock()
|
||||
{
|
||||
::testing::NiceMock<MockProgramImpl> *programImpl = new ::testing::NiceMock<MockProgramImpl>();
|
||||
// TODO(jmadill): add ON_CALLS for returning methods
|
||||
// We must mock the destructor since NiceMock doesn't work for destructors.
|
||||
EXPECT_CALL(*programImpl, destroy()).Times(1).RetiresOnSaturation();
|
||||
|
||||
return programImpl;
|
||||
}
|
||||
|
||||
} // namespace rx
|
||||
|
||||
#endif // LIBANGLE_RENDERER_PROGRAMIMPLMOCK_H_
|
||||
|
|
|
@ -26,8 +26,12 @@ class QueryImpl : angle::NonCopyable
|
|||
|
||||
virtual gl::Error begin() = 0;
|
||||
virtual gl::Error end() = 0;
|
||||
virtual gl::Error queryCounter() = 0;
|
||||
virtual gl::Error getResult(GLint *params) = 0;
|
||||
virtual gl::Error getResult(GLuint *params) = 0;
|
||||
virtual gl::Error isResultAvailable(GLuint *available) = 0;
|
||||
virtual gl::Error getResult(GLint64 *params) = 0;
|
||||
virtual gl::Error getResult(GLuint64 *params) = 0;
|
||||
virtual gl::Error isResultAvailable(bool *available) = 0;
|
||||
|
||||
GLenum getType() const { return mType; }
|
||||
|
||||
|
|
|
@ -82,7 +82,6 @@ class Renderer : public ImplFactory
|
|||
virtual bool testDeviceLost() = 0;
|
||||
virtual bool testDeviceResettable() = 0;
|
||||
|
||||
virtual VendorID getVendorId() const = 0;
|
||||
virtual std::string getVendorString() const = 0;
|
||||
virtual std::string getRendererDescription() const = 0;
|
||||
|
||||
|
@ -92,6 +91,13 @@ class Renderer : public ImplFactory
|
|||
|
||||
virtual void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) = 0;
|
||||
|
||||
// Disjoint timer queries
|
||||
virtual GLint getGPUDisjoint() = 0;
|
||||
virtual GLint64 getTimestamp() = 0;
|
||||
|
||||
// Context switching
|
||||
virtual void onMakeCurrent(const gl::Data &data) = 0;
|
||||
|
||||
// Renderer capabilities
|
||||
const gl::Caps &getRendererCaps() const;
|
||||
const gl::TextureCapsMap &getRendererTextureCaps() const;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче