1 | // |
2 | // Copyright 2017 The ANGLE Project Authors. All rights reserved. |
3 | // Use of this source code is governed by a BSD-style license that can be |
4 | // found in the LICENSE file. |
5 | // |
6 | // ExtensionBehavior.cpp: Extension name enumeration and data structures for storing extension |
7 | // behavior. |
8 | |
9 | #include "compiler/translator/ExtensionBehavior.h" |
10 | |
11 | #include "common/debug.h" |
12 | |
13 | #include <string.h> |
14 | |
15 | // clang-format off |
16 | // Extension Name, Min ESSL Version, Max ESSL Version |
17 | // |
18 | // Note that OES_EGL_image_external and OES_texture_3D are ESSL 100 only extensions, but one app has |
19 | // been found that uses them on GLSL 310. http://issuetracker.google.com/285871779 |
20 | #define LIST_EXTENSIONS(OP) \ |
21 | OP(ANDROID_extension_pack_es31a, 310, 320) \ |
22 | OP(ANGLE_base_vertex_base_instance_shader_builtin, 300, 320) \ |
23 | OP(ANGLE_clip_cull_distance, 300, 320) \ |
24 | OP(ANGLE_multi_draw, 100, 320) \ |
25 | OP(ANGLE_shader_pixel_local_storage, 300, 320) \ |
26 | OP(ANGLE_texture_multisample, 300, 320) \ |
27 | OP(APPLE_clip_distance, 100, 320) \ |
28 | OP(ARB_texture_rectangle, 100, 320) \ |
29 | OP(ARM_shader_framebuffer_fetch, 100, 320) \ |
30 | OP(EXT_blend_func_extended, 100, 320) \ |
31 | OP(EXT_clip_cull_distance, 300, 320) \ |
32 | OP(EXT_conservative_depth, 300, 320) \ |
33 | OP(EXT_draw_buffers, 100, 100) \ |
34 | OP(EXT_frag_depth, 100, 100) \ |
35 | OP(EXT_geometry_shader, 310, 320) \ |
36 | OP(OES_geometry_shader, 310, 320) \ |
37 | OP(OES_shader_io_blocks, 310, 320) \ |
38 | OP(EXT_shader_io_blocks, 310, 320) \ |
39 | OP(EXT_gpu_shader5, 310, 320) \ |
40 | OP(EXT_primitive_bounding_box, 310, 320) \ |
41 | OP(OES_primitive_bounding_box, 310, 320) \ |
42 | OP(EXT_separate_shader_objects, 100, 320) \ |
43 | OP(EXT_shader_framebuffer_fetch, 100, 320) \ |
44 | OP(EXT_shader_framebuffer_fetch_non_coherent, 100, 320) \ |
45 | OP(EXT_shader_non_constant_global_initializers, 100, 320) \ |
46 | OP(EXT_shader_texture_lod, 100, 100) \ |
47 | OP(EXT_shadow_samplers, 100, 100) \ |
48 | OP(EXT_tessellation_shader, 310, 320) \ |
49 | OP(EXT_texture_buffer, 310, 320) \ |
50 | OP(EXT_texture_cube_map_array, 310, 320) \ |
51 | OP(EXT_YUV_target, 300, 320) \ |
52 | OP(KHR_blend_equation_advanced, 100, 320) \ |
53 | OP(NV_EGL_stream_consumer_external, 100, 320) \ |
54 | OP(NV_shader_framebuffer_fetch, 100, 100) \ |
55 | OP(NV_shader_noperspective_interpolation, 300, 320) \ |
56 | OP(OES_EGL_image_external, 100, 310) \ |
57 | OP(OES_EGL_image_external_essl3, 300, 320) \ |
58 | OP(OES_sample_variables, 300, 320) \ |
59 | OP(OES_shader_multisample_interpolation, 300, 320) \ |
60 | OP(OES_shader_image_atomic, 310, 320) \ |
61 | OP(OES_standard_derivatives, 100, 100) \ |
62 | OP(OES_texture_3D, 100, 310) \ |
63 | OP(OES_texture_buffer, 310, 320) \ |
64 | OP(OES_texture_cube_map_array, 310, 320) \ |
65 | OP(OES_texture_storage_multisample_2d_array, 310, 320) \ |
66 | OP(OVR_multiview, 300, 320) \ |
67 | OP(OVR_multiview2, 300, 320) \ |
68 | OP(WEBGL_video_texture, 100, 320) |
69 | // clang-format on |
70 | |
71 | namespace sh |
72 | { |
73 | |
74 | #define RETURN_EXTENSION_NAME_CASE(ext, min_version, max_version) \ |
75 | case TExtension::ext: \ |
76 | return "GL_" #ext; |
77 | |
78 | const char *GetExtensionNameString(TExtension extension) |
79 | { |
80 | switch (extension) |
81 | { |
82 | LIST_EXTENSIONS(RETURN_EXTENSION_NAME_CASE) |
83 | default: |
84 | UNREACHABLE(); |
85 | return "" ; |
86 | } |
87 | } |
88 | |
89 | #define RETURN_EXTENSION_IF_NAME_MATCHES(ext, min_version, max_version) \ |
90 | if (strcmp(extWithoutGLPrefix, #ext) == 0) \ |
91 | { \ |
92 | return TExtension::ext; \ |
93 | } |
94 | |
95 | TExtension GetExtensionByName(const char *extension) |
96 | { |
97 | // If first characters of the extension don't equal "GL_", early out. |
98 | if (strncmp(s1: extension, s2: "GL_" , n: 3) != 0) |
99 | { |
100 | return TExtension::UNDEFINED; |
101 | } |
102 | const char *extWithoutGLPrefix = extension + 3; |
103 | |
104 | LIST_EXTENSIONS(RETURN_EXTENSION_IF_NAME_MATCHES) |
105 | |
106 | return TExtension::UNDEFINED; |
107 | } |
108 | |
109 | #define RETURN_VERSION_CHECK(ext, min_version, max_version) \ |
110 | case TExtension::ext: \ |
111 | return (version >= min_version) && (version <= max_version); |
112 | |
113 | bool CheckExtensionVersion(TExtension extension, int version) |
114 | { |
115 | switch (extension) |
116 | { |
117 | LIST_EXTENSIONS(RETURN_VERSION_CHECK) |
118 | default: |
119 | UNREACHABLE(); |
120 | return false; |
121 | } |
122 | } |
123 | |
124 | const char *GetBehaviorString(TBehavior b) |
125 | { |
126 | switch (b) |
127 | { |
128 | case EBhRequire: |
129 | return "require" ; |
130 | case EBhEnable: |
131 | return "enable" ; |
132 | case EBhWarn: |
133 | return "warn" ; |
134 | case EBhDisable: |
135 | return "disable" ; |
136 | default: |
137 | return nullptr; |
138 | } |
139 | } |
140 | |
141 | bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, TExtension extension) |
142 | { |
143 | ASSERT(extension != TExtension::UNDEFINED); |
144 | auto iter = extBehavior.find(k: extension); |
145 | return iter != extBehavior.end() && |
146 | (iter->second == EBhEnable || iter->second == EBhRequire || iter->second == EBhWarn); |
147 | } |
148 | |
149 | } // namespace sh |
150 | |