Bug 1251375. Update to ANGLE/2653

This commit is contained in:
Jeff Muizelaar 2016-03-15 12:02:47 -07:00
Родитель 157a38bc63
Коммит 745acee9fd
309 изменённых файлов: 19684 добавлений и 6599 удалений

Просмотреть файл

@ -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 &param = 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, &registerCount);
}
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, &registerCount);
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 &registerString = 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 &param = 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 &param = 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;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше