| @@ -0,0 +1,287 @@ | |||
| 1 | + | // | |
| 2 | + | // Copyright 2013 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 | + | // ShaderVars.h: | |
| 7 | + | // Types to represent GL variables (varyings, uniforms, etc) | |
| 8 | + | // | |
| 9 | + | ||
| 10 | + | #ifndef GLSLANG_SHADERVARS_H_ | |
| 11 | + | #define GLSLANG_SHADERVARS_H_ | |
| 12 | + | ||
| 13 | + | #include <algorithm> | |
| 14 | + | #include <array> | |
| 15 | + | #include <string> | |
| 16 | + | #include <vector> | |
| 17 | + | ||
| 18 | + | // This type is defined here to simplify ANGLE's integration with glslang for SPIRv. | |
| 19 | + | using ShCompileOptions = uint64_t; | |
| 20 | + | ||
| 21 | + | namespace sh | |
| 22 | + | { | |
| 23 | + | // GLenum alias | |
| 24 | + | typedef unsigned int GLenum; | |
| 25 | + | ||
| 26 | + | // Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec | |
| 27 | + | enum InterpolationType | |
| 28 | + | { | |
| 29 | + | INTERPOLATION_SMOOTH, | |
| 30 | + | INTERPOLATION_CENTROID, | |
| 31 | + | INTERPOLATION_FLAT, | |
| 32 | + | INTERPOLATION_NOPERSPECTIVE | |
| 33 | + | }; | |
| 34 | + | ||
| 35 | + | // Validate link & SSO consistency of interpolation qualifiers | |
| 36 | + | bool InterpolationTypesMatch(InterpolationType a, InterpolationType b); | |
| 37 | + | ||
| 38 | + | // Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec | |
| 39 | + | enum BlockLayoutType | |
| 40 | + | { | |
| 41 | + | BLOCKLAYOUT_STANDARD, | |
| 42 | + | BLOCKLAYOUT_STD140 = BLOCKLAYOUT_STANDARD, | |
| 43 | + | BLOCKLAYOUT_STD430, // Shader storage block layout qualifier | |
| 44 | + | BLOCKLAYOUT_PACKED, | |
| 45 | + | BLOCKLAYOUT_SHARED | |
| 46 | + | }; | |
| 47 | + | ||
| 48 | + | // Interface Blocks, see section 4.3.9 of the ESSL 3.10 spec | |
| 49 | + | enum class BlockType | |
| 50 | + | { | |
| 51 | + | BLOCK_UNIFORM, | |
| 52 | + | BLOCK_BUFFER, | |
| 53 | + | ||
| 54 | + | // Required in OpenGL ES 3.1 extension GL_OES_shader_io_blocks. | |
| 55 | + | // TODO(jiawei.shao@intel.com): add BLOCK_OUT. | |
| 56 | + | // Also used in GLSL | |
| 57 | + | BLOCK_IN | |
| 58 | + | }; | |
| 59 | + | ||
| 60 | + | // Base class for all variables defined in shaders, including Varyings, Uniforms, etc | |
| 61 | + | // Note: we must override the copy constructor and assignment operator so we can | |
| 62 | + | // work around excessive GCC binary bloating: | |
| 63 | + | // See https://code.google.com/p/angleproject/issues/detail?id=697 | |
| 64 | + | struct ShaderVariable | |
| 65 | + | { | |
| 66 | + | ShaderVariable(); | |
| 67 | + | ShaderVariable(GLenum typeIn); | |
| 68 | + | ShaderVariable(GLenum typeIn, unsigned int arraySizeIn); | |
| 69 | + | ~ShaderVariable(); | |
| 70 | + | ShaderVariable(const ShaderVariable &other); | |
| 71 | + | ShaderVariable &operator=(const ShaderVariable &other); | |
| 72 | + | bool operator==(const ShaderVariable &other) const; | |
| 73 | + | bool operator!=(const ShaderVariable &other) const { return !operator==(other); } | |
| 74 | + | ||
| 75 | + | bool isArrayOfArrays() const { return arraySizes.size() >= 2u; } | |
| 76 | + | bool isArray() const { return !arraySizes.empty(); } | |
| 77 | + | unsigned int getArraySizeProduct() const; | |
| 78 | + | // Return the inner array size product. | |
| 79 | + | // For example, if there's a variable declared as size 3 array of size 4 array of size 5 array | |
| 80 | + | // of int: | |
| 81 | + | // int a[3][4][5]; | |
| 82 | + | // then getInnerArraySizeProduct of a would be 4*5. | |
| 83 | + | unsigned int getInnerArraySizeProduct() const; | |
| 84 | + | ||
| 85 | + | // Array size 0 means not an array when passed to or returned from these functions. | |
| 86 | + | // Note that setArraySize() is deprecated and should not be used inside ANGLE. | |
| 87 | + | unsigned int getOutermostArraySize() const { return isArray() ? arraySizes.back() : 0; } | |
| 88 | + | void setArraySize(unsigned int size); | |
| 89 | + | ||
| 90 | + | // Turn this ShaderVariable from an array into a specific element in that array. Will update | |
| 91 | + | // flattenedOffsetInParentArrays. | |
| 92 | + | void indexIntoArray(unsigned int arrayIndex); | |
| 93 | + | ||
| 94 | + | // Get the nth nested array size from the top. Caller is responsible for range checking | |
| 95 | + | // arrayNestingIndex. | |
| 96 | + | unsigned int getNestedArraySize(unsigned int arrayNestingIndex) const; | |
| 97 | + | ||
| 98 | + | // This function should only be used with variables that are of a basic type or an array of a | |
| 99 | + | // basic type. Shader interface variables that are enumerated according to rules in GLES 3.1 | |
| 100 | + | // spec section 7.3.1.1 page 77 are fine. For those variables the return value should match the | |
| 101 | + | // ARRAY_SIZE value that can be queried through the API. | |
| 102 | + | unsigned int getBasicTypeElementCount() const; | |
| 103 | + | ||
| 104 | + | unsigned int getExternalSize() const; | |
| 105 | + | ||
| 106 | + | bool isStruct() const { return !fields.empty(); } | |
| 107 | + | ||
| 108 | + | // All of the shader's variables are described using nested data | |
| 109 | + | // structures. This is needed in order to disambiguate similar looking | |
| 110 | + | // types, such as two structs containing the same fields, but in | |
| 111 | + | // different orders. "findInfoByMappedName" provides an easy query for | |
| 112 | + | // users to dive into the data structure and fetch the unique variable | |
| 113 | + | // instance corresponding to a dereferencing chain of the top-level | |
| 114 | + | // variable. | |
| 115 | + | // Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable | |
| 116 | + | // that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]' | |
| 117 | + | // in |originalName|, based on the assumption that |this| defines 'a'. | |
| 118 | + | // If no match is found, return false. | |
| 119 | + | bool findInfoByMappedName(const std::string &mappedFullName, | |
| 120 | + | const ShaderVariable **leafVar, | |
| 121 | + | std::string *originalFullName) const; | |
| 122 | + | ||
| 123 | + | bool isBuiltIn() const; | |
| 124 | + | bool isEmulatedBuiltIn() const; | |
| 125 | + | ||
| 126 | + | GLenum type; | |
| 127 | + | GLenum precision; | |
| 128 | + | std::string name; | |
| 129 | + | std::string mappedName; | |
| 130 | + | ||
| 131 | + | // Used to make an array type. Outermost array size is stored at the end of the vector. | |
| 132 | + | std::vector<unsigned int> arraySizes; | |
| 133 | + | ||
| 134 | + | // Offset of this variable in parent arrays. In case the parent is an array of arrays, the | |
| 135 | + | // offset is outerArrayElement * innerArraySize + innerArrayElement. | |
| 136 | + | // For example, if there's a variable declared as size 3 array of size 4 array of int: | |
| 137 | + | // int a[3][4]; | |
| 138 | + | // then the flattenedOffsetInParentArrays of a[2] would be 2. | |
| 139 | + | // and flattenedOffsetInParentArrays of a[2][1] would be 2*4 + 1 = 9. | |
| 140 | + | int parentArrayIndex() const | |
| 141 | + | { | |
| 142 | + | return hasParentArrayIndex() ? flattenedOffsetInParentArrays : 0; | |
| 143 | + | } | |
| 144 | + | ||
| 145 | + | void setParentArrayIndex(int indexIn) { flattenedOffsetInParentArrays = indexIn; } | |
| 146 | + | ||
| 147 | + | bool hasParentArrayIndex() const { return flattenedOffsetInParentArrays != -1; } | |
| 148 | + | ||
| 149 | + | // Static use means that the variable is accessed somewhere in the shader source. | |
| 150 | + | bool staticUse; | |
| 151 | + | // A variable is active unless the compiler determined that it is not accessed by the shader. | |
| 152 | + | // All active variables are statically used, but not all statically used variables are | |
| 153 | + | // necessarily active. GLES 3.0.5 section 2.12.6. GLES 3.1 section 7.3.1. | |
| 154 | + | bool active; | |
| 155 | + | std::vector<ShaderVariable> fields; | |
| 156 | + | std::string structName; | |
| 157 | + | ||
| 158 | + | // Only applies to interface block fields. Kept here for simplicity. | |
| 159 | + | bool isRowMajorLayout; | |
| 160 | + | ||
| 161 | + | // VariableWithLocation | |
| 162 | + | int location; | |
| 163 | + | ||
| 164 | + | // Uniform | |
| 165 | + | int binding; | |
| 166 | + | // Decide whether two uniforms are the same at shader link time, | |
| 167 | + | // assuming one from vertex shader and the other from fragment shader. | |
| 168 | + | // GLSL ES Spec 3.00.3, section 4.3.5. | |
| 169 | + | // GLSL ES Spec 3.10.4, section 4.4.5 | |
| 170 | + | bool isSameUniformAtLinkTime(const ShaderVariable &other) const; | |
| 171 | + | GLenum imageUnitFormat; | |
| 172 | + | int offset; | |
| 173 | + | bool readonly; | |
| 174 | + | bool writeonly; | |
| 175 | + | ||
| 176 | + | // OutputVariable | |
| 177 | + | // From EXT_blend_func_extended. | |
| 178 | + | int index; | |
| 179 | + | ||
| 180 | + | // InterfaceBlockField | |
| 181 | + | // Decide whether two InterfaceBlock fields are the same at shader | |
| 182 | + | // link time, assuming one from vertex shader and the other from | |
| 183 | + | // fragment shader. | |
| 184 | + | // See GLSL ES Spec 3.00.3, sec 4.3.7. | |
| 185 | + | bool isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable &other) const; | |
| 186 | + | ||
| 187 | + | // Varying | |
| 188 | + | InterpolationType interpolation; | |
| 189 | + | bool isInvariant; | |
| 190 | + | // Decide whether two varyings are the same at shader link time, | |
| 191 | + | // assuming one from vertex shader and the other from fragment shader. | |
| 192 | + | // Invariance needs to match only in ESSL1. Relevant spec sections: | |
| 193 | + | // GLSL ES 3.00.4, sections 4.6.1 and 4.3.9. | |
| 194 | + | // GLSL ES 1.00.17, section 4.6.4. | |
| 195 | + | bool isSameVaryingAtLinkTime(const ShaderVariable &other, int shaderVersion) const; | |
| 196 | + | // Deprecated version of isSameVaryingAtLinkTime, which assumes ESSL1. | |
| 197 | + | bool isSameVaryingAtLinkTime(const ShaderVariable &other) const; | |
| 198 | + | ||
| 199 | + | protected: | |
| 200 | + | bool isSameVariableAtLinkTime(const ShaderVariable &other, | |
| 201 | + | bool matchPrecision, | |
| 202 | + | bool matchName) const; | |
| 203 | + | ||
| 204 | + | int flattenedOffsetInParentArrays; | |
| 205 | + | }; | |
| 206 | + | ||
| 207 | + | // TODO: anglebug.com/3899 | |
| 208 | + | // For backwards compatibility for other codebases (e.g., chromium/src/gpu/command_buffer/service) | |
| 209 | + | using Uniform = ShaderVariable; | |
| 210 | + | using Attribute = ShaderVariable; | |
| 211 | + | using OutputVariable = ShaderVariable; | |
| 212 | + | using InterfaceBlockField = ShaderVariable; | |
| 213 | + | using Varying = ShaderVariable; | |
| 214 | + | ||
| 215 | + | struct InterfaceBlock | |
| 216 | + | { | |
| 217 | + | InterfaceBlock(); | |
| 218 | + | ~InterfaceBlock(); | |
| 219 | + | InterfaceBlock(const InterfaceBlock &other); | |
| 220 | + | InterfaceBlock &operator=(const InterfaceBlock &other); | |
| 221 | + | ||
| 222 | + | // Fields from blocks with non-empty instance names are prefixed with the block name. | |
| 223 | + | std::string fieldPrefix() const; | |
| 224 | + | std::string fieldMappedPrefix() const; | |
| 225 | + | ||
| 226 | + | // Decide whether two interface blocks are the same at shader link time. | |
| 227 | + | bool isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const; | |
| 228 | + | ||
| 229 | + | bool isBuiltIn() const; | |
| 230 | + | ||
| 231 | + | bool isArray() const { return arraySize > 0; } | |
| 232 | + | unsigned int elementCount() const { return std::max(1u, arraySize); } | |
| 233 | + | ||
| 234 | + | std::string name; | |
| 235 | + | std::string mappedName; | |
| 236 | + | std::string instanceName; | |
| 237 | + | unsigned int arraySize; | |
| 238 | + | BlockLayoutType layout; | |
| 239 | + | ||
| 240 | + | // Deprecated. Matrix packing should only be queried from individual fields of the block. | |
| 241 | + | // TODO(oetuaho): Remove this once it is no longer used in Chromium. | |
| 242 | + | bool isRowMajorLayout; | |
| 243 | + | ||
| 244 | + | int binding; | |
| 245 | + | bool staticUse; | |
| 246 | + | bool active; | |
| 247 | + | BlockType blockType; | |
| 248 | + | std::vector<ShaderVariable> fields; | |
| 249 | + | }; | |
| 250 | + | ||
| 251 | + | struct WorkGroupSize | |
| 252 | + | { | |
| 253 | + | // Must have a trivial default constructor since it is used in YYSTYPE. | |
| 254 | + | inline WorkGroupSize() = default; | |
| 255 | + | inline explicit constexpr WorkGroupSize(int initialSize); | |
| 256 | + | ||
| 257 | + | void fill(int fillValue); | |
| 258 | + | void setLocalSize(int localSizeX, int localSizeY, int localSizeZ); | |
| 259 | + | ||
| 260 | + | int &operator[](size_t index); | |
| 261 | + | int operator[](size_t index) const; | |
| 262 | + | size_t size() const; | |
| 263 | + | ||
| 264 | + | // Checks whether two work group size declarations match. | |
| 265 | + | // Two work group size declarations are the same if the explicitly specified elements are the | |
| 266 | + | // same or if one of them is specified as one and the other one is not specified | |
| 267 | + | bool isWorkGroupSizeMatching(const WorkGroupSize &right) const; | |
| 268 | + | ||
| 269 | + | // Checks whether any of the values are set. | |
| 270 | + | bool isAnyValueSet() const; | |
| 271 | + | ||
| 272 | + | // Checks whether all of the values are set. | |
| 273 | + | bool isDeclared() const; | |
| 274 | + | ||
| 275 | + | // Checks whether either all of the values are set, or none of them are. | |
| 276 | + | bool isLocalSizeValid() const; | |
| 277 | + | ||
| 278 | + | int localSizeQualifiers[3]; | |
| 279 | + | }; | |
| 280 | + | ||
| 281 | + | inline constexpr WorkGroupSize::WorkGroupSize(int initialSize) | |
| 282 | + | : localSizeQualifiers{initialSize, initialSize, initialSize} | |
| 283 | + | {} | |
| 284 | + | ||
| 285 | + | } // namespace sh | |
| 286 | + | ||
| 287 | + | #endif // GLSLANG_SHADERVARS_H_ |
| @@ -0,0 +1,3 @@ | |||
| 1 | + | ||
| 2 | + | ||
| 3 | + | DisableFormat: true |
| @@ -0,0 +1,282 @@ | |||
| 1 | + | #ifndef __khrplatform_h_ | |
| 2 | + | #define __khrplatform_h_ | |
| 3 | + | ||
| 4 | + | /* | |
| 5 | + | ** Copyright (c) 2008-2018 The Khronos Group Inc. | |
| 6 | + | ** | |
| 7 | + | ** Permission is hereby granted, free of charge, to any person obtaining a | |
| 8 | + | ** copy of this software and/or associated documentation files (the | |
| 9 | + | ** "Materials"), to deal in the Materials without restriction, including | |
| 10 | + | ** without limitation the rights to use, copy, modify, merge, publish, | |
| 11 | + | ** distribute, sublicense, and/or sell copies of the Materials, and to | |
| 12 | + | ** permit persons to whom the Materials are furnished to do so, subject to | |
| 13 | + | ** the following conditions: | |
| 14 | + | ** | |
| 15 | + | ** The above copyright notice and this permission notice shall be included | |
| 16 | + | ** in all copies or substantial portions of the Materials. | |
| 17 | + | ** | |
| 18 | + | ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| 19 | + | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| 20 | + | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
| 21 | + | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 22 | + | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
| 23 | + | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
| 24 | + | ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. | |
| 25 | + | */ | |
| 26 | + | ||
| 27 | + | /* Khronos platform-specific types and definitions. | |
| 28 | + | * | |
| 29 | + | * The master copy of khrplatform.h is maintained in the Khronos EGL | |
| 30 | + | * Registry repository at https://github.com/KhronosGroup/EGL-Registry | |
| 31 | + | * The last semantic modification to khrplatform.h was at commit ID: | |
| 32 | + | * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 | |
| 33 | + | * | |
| 34 | + | * Adopters may modify this file to suit their platform. Adopters are | |
| 35 | + | * encouraged to submit platform specific modifications to the Khronos | |
| 36 | + | * group so that they can be included in future versions of this file. | |
| 37 | + | * Please submit changes by filing pull requests or issues on | |
| 38 | + | * the EGL Registry repository linked above. | |
| 39 | + | * | |
| 40 | + | * | |
| 41 | + | * See the Implementer's Guidelines for information about where this file | |
| 42 | + | * should be located on your system and for more details of its use: | |
| 43 | + | * http://www.khronos.org/registry/implementers_guide.pdf | |
| 44 | + | * | |
| 45 | + | * This file should be included as | |
| 46 | + | * #include <KHR/khrplatform.h> | |
| 47 | + | * by Khronos client API header files that use its types and defines. | |
| 48 | + | * | |
| 49 | + | * The types in khrplatform.h should only be used to define API-specific types. | |
| 50 | + | * | |
| 51 | + | * Types defined in khrplatform.h: | |
| 52 | + | * khronos_int8_t signed 8 bit | |
| 53 | + | * khronos_uint8_t unsigned 8 bit | |
| 54 | + | * khronos_int16_t signed 16 bit | |
| 55 | + | * khronos_uint16_t unsigned 16 bit | |
| 56 | + | * khronos_int32_t signed 32 bit | |
| 57 | + | * khronos_uint32_t unsigned 32 bit | |
| 58 | + | * khronos_int64_t signed 64 bit | |
| 59 | + | * khronos_uint64_t unsigned 64 bit | |
| 60 | + | * khronos_intptr_t signed same number of bits as a pointer | |
| 61 | + | * khronos_uintptr_t unsigned same number of bits as a pointer | |
| 62 | + | * khronos_ssize_t signed size | |
| 63 | + | * khronos_usize_t unsigned size | |
| 64 | + | * khronos_float_t signed 32 bit floating point | |
| 65 | + | * khronos_time_ns_t unsigned 64 bit time in nanoseconds | |
| 66 | + | * khronos_utime_nanoseconds_t unsigned time interval or absolute time in | |
| 67 | + | * nanoseconds | |
| 68 | + | * khronos_stime_nanoseconds_t signed time interval in nanoseconds | |
| 69 | + | * khronos_boolean_enum_t enumerated boolean type. This should | |
| 70 | + | * only be used as a base type when a client API's boolean type is | |
| 71 | + | * an enum. Client APIs which use an integer or other type for | |
| 72 | + | * booleans cannot use this as the base type for their boolean. | |
| 73 | + | * | |
| 74 | + | * Tokens defined in khrplatform.h: | |
| 75 | + | * | |
| 76 | + | * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. | |
| 77 | + | * | |
| 78 | + | * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. | |
| 79 | + | * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. | |
| 80 | + | * | |
| 81 | + | * Calling convention macros defined in this file: | |
| 82 | + | * KHRONOS_APICALL | |
| 83 | + | * KHRONOS_APIENTRY | |
| 84 | + | * KHRONOS_APIATTRIBUTES | |
| 85 | + | * | |
| 86 | + | * These may be used in function prototypes as: | |
| 87 | + | * | |
| 88 | + | * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( | |
| 89 | + | * int arg1, | |
| 90 | + | * int arg2) KHRONOS_APIATTRIBUTES; | |
| 91 | + | */ | |
| 92 | + | ||
| 93 | + | /*------------------------------------------------------------------------- | |
| 94 | + | * Definition of KHRONOS_APICALL | |
| 95 | + | *------------------------------------------------------------------------- | |
| 96 | + | * This precedes the return type of the function in the function prototype. | |
| 97 | + | */ | |
| 98 | + | #if defined(_WIN32) && !defined(__SCITECH_SNAP__) | |
| 99 | + | # define KHRONOS_APICALL __declspec(dllimport) | |
| 100 | + | #elif defined (__SYMBIAN32__) | |
| 101 | + | # define KHRONOS_APICALL IMPORT_C | |
| 102 | + | #elif defined(__ANDROID__) | |
| 103 | + | # define KHRONOS_APICALL __attribute__((visibility("default"))) | |
| 104 | + | #else | |
| 105 | + | # define KHRONOS_APICALL | |
| 106 | + | #endif | |
| 107 | + | ||
| 108 | + | /*------------------------------------------------------------------------- | |
| 109 | + | * Definition of KHRONOS_APIENTRY | |
| 110 | + | *------------------------------------------------------------------------- | |
| 111 | + | * This follows the return type of the function and precedes the function | |
| 112 | + | * name in the function prototype. | |
| 113 | + | */ | |
| 114 | + | #if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) | |
| 115 | + | /* Win32 but not WinCE */ | |
| 116 | + | # define KHRONOS_APIENTRY __stdcall | |
| 117 | + | #else | |
| 118 | + | # define KHRONOS_APIENTRY | |
| 119 | + | #endif | |
| 120 | + | ||
| 121 | + | /*------------------------------------------------------------------------- | |
| 122 | + | * Definition of KHRONOS_APIATTRIBUTES | |
| 123 | + | *------------------------------------------------------------------------- | |
| 124 | + | * This follows the closing parenthesis of the function prototype arguments. | |
| 125 | + | */ | |
| 126 | + | #if defined (__ARMCC_2__) | |
| 127 | + | #define KHRONOS_APIATTRIBUTES __softfp | |
| 128 | + | #else | |
| 129 | + | #define KHRONOS_APIATTRIBUTES | |
| 130 | + | #endif | |
| 131 | + | ||
| 132 | + | /*------------------------------------------------------------------------- | |
| 133 | + | * basic type definitions | |
| 134 | + | *-----------------------------------------------------------------------*/ | |
| 135 | + | #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) | |
| 136 | + | ||
| 137 | + | ||
| 138 | + | /* | |
| 139 | + | * Using <stdint.h> | |
| 140 | + | */ | |
| 141 | + | #include <stdint.h> | |
| 142 | + | typedef int32_t khronos_int32_t; | |
| 143 | + | typedef uint32_t khronos_uint32_t; | |
| 144 | + | typedef int64_t khronos_int64_t; | |
| 145 | + | typedef uint64_t khronos_uint64_t; | |
| 146 | + | #define KHRONOS_SUPPORT_INT64 1 | |
| 147 | + | #define KHRONOS_SUPPORT_FLOAT 1 | |
| 148 | + | ||
| 149 | + | #elif defined(__VMS ) || defined(__sgi) | |
| 150 | + | ||
| 151 | + | /* | |
| 152 | + | * Using <inttypes.h> | |
| 153 | + | */ | |
| 154 | + | #include <inttypes.h> | |
| 155 | + | typedef int32_t khronos_int32_t; | |
| 156 | + | typedef uint32_t khronos_uint32_t; | |
| 157 | + | typedef int64_t khronos_int64_t; | |
| 158 | + | typedef uint64_t khronos_uint64_t; | |
| 159 | + | #define KHRONOS_SUPPORT_INT64 1 | |
| 160 | + | #define KHRONOS_SUPPORT_FLOAT 1 | |
| 161 | + | ||
| 162 | + | #elif defined(_WIN32) && !defined(__SCITECH_SNAP__) | |
| 163 | + | ||
| 164 | + | /* | |
| 165 | + | * Win32 | |
| 166 | + | */ | |
| 167 | + | typedef __int32 khronos_int32_t; | |
| 168 | + | typedef unsigned __int32 khronos_uint32_t; | |
| 169 | + | typedef __int64 khronos_int64_t; | |
| 170 | + | typedef unsigned __int64 khronos_uint64_t; | |
| 171 | + | #define KHRONOS_SUPPORT_INT64 1 | |
| 172 | + | #define KHRONOS_SUPPORT_FLOAT 1 | |
| 173 | + | ||
| 174 | + | #elif defined(__sun__) || defined(__digital__) | |
| 175 | + | ||
| 176 | + | /* | |
| 177 | + | * Sun or Digital | |
| 178 | + | */ | |
| 179 | + | typedef int khronos_int32_t; | |
| 180 | + | typedef unsigned int khronos_uint32_t; | |
| 181 | + | #if defined(__arch64__) || defined(_LP64) | |
| 182 | + | typedef long int khronos_int64_t; | |
| 183 | + | typedef unsigned long int khronos_uint64_t; | |
| 184 | + | #else | |
| 185 | + | typedef long long int khronos_int64_t; | |
| 186 | + | typedef unsigned long long int khronos_uint64_t; | |
| 187 | + | #endif /* __arch64__ */ | |
| 188 | + | #define KHRONOS_SUPPORT_INT64 1 | |
| 189 | + | #define KHRONOS_SUPPORT_FLOAT 1 | |
| 190 | + | ||
| 191 | + | #elif 0 | |
| 192 | + | ||
| 193 | + | /* | |
| 194 | + | * Hypothetical platform with no float or int64 support | |
| 195 | + | */ | |
| 196 | + | typedef int khronos_int32_t; | |
| 197 | + | typedef unsigned int khronos_uint32_t; | |
| 198 | + | #define KHRONOS_SUPPORT_INT64 0 | |
| 199 | + | #define KHRONOS_SUPPORT_FLOAT 0 | |
| 200 | + | ||
| 201 | + | #else | |
| 202 | + | ||
| 203 | + | /* | |
| 204 | + | * Generic fallback | |
| 205 | + | */ | |
| 206 | + | #include <stdint.h> | |
| 207 | + | typedef int32_t khronos_int32_t; | |
| 208 | + | typedef uint32_t khronos_uint32_t; | |
| 209 | + | typedef int64_t khronos_int64_t; | |
| 210 | + | typedef uint64_t khronos_uint64_t; | |
| 211 | + | #define KHRONOS_SUPPORT_INT64 1 | |
| 212 | + | #define KHRONOS_SUPPORT_FLOAT 1 | |
| 213 | + | ||
| 214 | + | #endif | |
| 215 | + | ||
| 216 | + | ||
| 217 | + | /* | |
| 218 | + | * Types that are (so far) the same on all platforms | |
| 219 | + | */ | |
| 220 | + | typedef signed char khronos_int8_t; | |
| 221 | + | typedef unsigned char khronos_uint8_t; | |
| 222 | + | typedef signed short int khronos_int16_t; | |
| 223 | + | typedef unsigned short int khronos_uint16_t; | |
| 224 | + | ||
| 225 | + | /* | |
| 226 | + | * Types that differ between LLP64 and LP64 architectures - in LLP64, | |
| 227 | + | * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears | |
| 228 | + | * to be the only LLP64 architecture in current use. | |
| 229 | + | */ | |
| 230 | + | #ifdef _WIN64 | |
| 231 | + | typedef signed long long int khronos_intptr_t; | |
| 232 | + | typedef unsigned long long int khronos_uintptr_t; | |
| 233 | + | typedef signed long long int khronos_ssize_t; | |
| 234 | + | typedef unsigned long long int khronos_usize_t; | |
| 235 | + | #else | |
| 236 | + | typedef signed long int khronos_intptr_t; | |
| 237 | + | typedef unsigned long int khronos_uintptr_t; | |
| 238 | + | typedef signed long int khronos_ssize_t; | |
| 239 | + | typedef unsigned long int khronos_usize_t; | |
| 240 | + | #endif | |
| 241 | + | ||
| 242 | + | #if KHRONOS_SUPPORT_FLOAT | |
| 243 | + | /* | |
| 244 | + | * Float type | |
| 245 | + | */ | |
| 246 | + | typedef float khronos_float_t; | |
| 247 | + | #endif | |
| 248 | + | ||
| 249 | + | #if KHRONOS_SUPPORT_INT64 | |
| 250 | + | /* Time types | |
| 251 | + | * | |
| 252 | + | * These types can be used to represent a time interval in nanoseconds or | |
| 253 | + | * an absolute Unadjusted System Time. Unadjusted System Time is the number | |
| 254 | + | * of nanoseconds since some arbitrary system event (e.g. since the last | |
| 255 | + | * time the system booted). The Unadjusted System Time is an unsigned | |
| 256 | + | * 64 bit value that wraps back to 0 every 584 years. Time intervals | |
| 257 | + | * may be either signed or unsigned. | |
| 258 | + | */ | |
| 259 | + | typedef khronos_uint64_t khronos_utime_nanoseconds_t; | |
| 260 | + | typedef khronos_int64_t khronos_stime_nanoseconds_t; | |
| 261 | + | #endif | |
| 262 | + | ||
| 263 | + | /* | |
| 264 | + | * Dummy value used to pad enum types to 32 bits. | |
| 265 | + | */ | |
| 266 | + | #ifndef KHRONOS_MAX_ENUM | |
| 267 | + | #define KHRONOS_MAX_ENUM 0x7FFFFFFF | |
| 268 | + | #endif | |
| 269 | + | ||
| 270 | + | /* | |
| 271 | + | * Enumerated boolean type | |
| 272 | + | * | |
| 273 | + | * Values other than zero should be considered to be true. Therefore | |
| 274 | + | * comparisons should not be made against KHRONOS_TRUE. | |
| 275 | + | */ | |
| 276 | + | typedef enum { | |
| 277 | + | KHRONOS_FALSE = 0, | |
| 278 | + | KHRONOS_TRUE = 1, | |
| 279 | + | KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM | |
| 280 | + | } khronos_boolean_enum_t; | |
| 281 | + | ||
| 282 | + | #endif /* __khrplatform_h_ */ |
| @@ -0,0 +1,192 @@ | |||
| 1 | + | // | |
| 2 | + | // Copyright 2019 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 | + | // Feature.h: Definition of structs to hold feature/workaround information. | |
| 7 | + | // | |
| 8 | + | ||
| 9 | + | #ifndef ANGLE_PLATFORM_FEATURE_H_ | |
| 10 | + | #define ANGLE_PLATFORM_FEATURE_H_ | |
| 11 | + | ||
| 12 | + | #include <map> | |
| 13 | + | #include <string> | |
| 14 | + | #include <vector> | |
| 15 | + | ||
| 16 | + | #define ANGLE_FEATURE_CONDITION(set, feature, cond) \ | |
| 17 | + | do \ | |
| 18 | + | { \ | |
| 19 | + | (set)->feature.enabled = cond; \ | |
| 20 | + | (set)->feature.condition = ANGLE_STRINGIFY(cond); \ | |
| 21 | + | } while (0) | |
| 22 | + | ||
| 23 | + | namespace angle | |
| 24 | + | { | |
| 25 | + | ||
| 26 | + | enum class FeatureCategory | |
| 27 | + | { | |
| 28 | + | FrontendWorkarounds, | |
| 29 | + | OpenGLWorkarounds, | |
| 30 | + | D3DWorkarounds, | |
| 31 | + | D3DCompilerWorkarounds, | |
| 32 | + | VulkanWorkarounds, | |
| 33 | + | VulkanFeatures, | |
| 34 | + | MetalFeatures, | |
| 35 | + | }; | |
| 36 | + | ||
| 37 | + | constexpr char kFeatureCategoryFrontendWorkarounds[] = "Frontend workarounds"; | |
| 38 | + | constexpr char kFeatureCategoryOpenGLWorkarounds[] = "OpenGL workarounds"; | |
| 39 | + | constexpr char kFeatureCategoryD3DWorkarounds[] = "D3D workarounds"; | |
| 40 | + | constexpr char kFeatureCategoryD3DCompilerWorkarounds[] = "D3D compiler workarounds"; | |
| 41 | + | constexpr char kFeatureCategoryVulkanWorkarounds[] = "Vulkan workarounds"; | |
| 42 | + | constexpr char kFeatureCategoryVulkanFeatures[] = "Vulkan features"; | |
| 43 | + | constexpr char kFeatureCategoryMetalFeatures[] = "Metal features"; | |
| 44 | + | constexpr char kFeatureCategoryUnknown[] = "Unknown"; | |
| 45 | + | ||
| 46 | + | inline const char *FeatureCategoryToString(const FeatureCategory &fc) | |
| 47 | + | { | |
| 48 | + | switch (fc) | |
| 49 | + | { | |
| 50 | + | case FeatureCategory::FrontendWorkarounds: | |
| 51 | + | return kFeatureCategoryFrontendWorkarounds; | |
| 52 | + | break; | |
| 53 | + | ||
| 54 | + | case FeatureCategory::OpenGLWorkarounds: | |
| 55 | + | return kFeatureCategoryOpenGLWorkarounds; | |
| 56 | + | break; | |
| 57 | + | ||
| 58 | + | case FeatureCategory::D3DWorkarounds: | |
| 59 | + | return kFeatureCategoryD3DWorkarounds; | |
| 60 | + | break; | |
| 61 | + | ||
| 62 | + | case FeatureCategory::D3DCompilerWorkarounds: | |
| 63 | + | return kFeatureCategoryD3DCompilerWorkarounds; | |
| 64 | + | break; | |
| 65 | + | ||
| 66 | + | case FeatureCategory::VulkanWorkarounds: | |
| 67 | + | return kFeatureCategoryVulkanWorkarounds; | |
| 68 | + | break; | |
| 69 | + | ||
| 70 | + | case FeatureCategory::VulkanFeatures: | |
| 71 | + | return kFeatureCategoryVulkanFeatures; | |
| 72 | + | break; | |
| 73 | + | ||
| 74 | + | case FeatureCategory::MetalFeatures: | |
| 75 | + | return kFeatureCategoryMetalFeatures; | |
| 76 | + | break; | |
| 77 | + | ||
| 78 | + | default: | |
| 79 | + | return kFeatureCategoryUnknown; | |
| 80 | + | break; | |
| 81 | + | } | |
| 82 | + | } | |
| 83 | + | ||
| 84 | + | constexpr char kFeatureStatusEnabled[] = "enabled"; | |
| 85 | + | constexpr char kFeatureStatusDisabled[] = "disabled"; | |
| 86 | + | ||
| 87 | + | inline const char *FeatureStatusToString(const bool &status) | |
| 88 | + | { | |
| 89 | + | if (status) | |
| 90 | + | { | |
| 91 | + | return kFeatureStatusEnabled; | |
| 92 | + | } | |
| 93 | + | return kFeatureStatusDisabled; | |
| 94 | + | } | |
| 95 | + | ||
| 96 | + | struct Feature; | |
| 97 | + | ||
| 98 | + | using FeatureMap = std::map<std::string, Feature *>; | |
| 99 | + | using FeatureList = std::vector<const Feature *>; | |
| 100 | + | ||
| 101 | + | struct Feature | |
| 102 | + | { | |
| 103 | + | Feature(const Feature &other); | |
| 104 | + | Feature(const char *name, | |
| 105 | + | const FeatureCategory &category, | |
| 106 | + | const char *description, | |
| 107 | + | FeatureMap *const mapPtr, | |
| 108 | + | const char *bug); | |
| 109 | + | ~Feature(); | |
| 110 | + | ||
| 111 | + | // The name of the workaround, lowercase, camel_case | |
| 112 | + | const char *const name; | |
| 113 | + | ||
| 114 | + | // The category that the workaround belongs to. Eg. "Vulkan workarounds" | |
| 115 | + | const FeatureCategory category; | |
| 116 | + | ||
| 117 | + | // A short description to be read by the user. | |
| 118 | + | const char *const description; | |
| 119 | + | ||
| 120 | + | // A link to the bug, if any | |
| 121 | + | const char *const bug; | |
| 122 | + | ||
| 123 | + | // Whether the workaround is enabled or not. Determined by heuristics like vendor ID and | |
| 124 | + | // version, but may be overriden to any value. | |
| 125 | + | bool enabled = false; | |
| 126 | + | ||
| 127 | + | // A stingified version of the condition used to set 'enabled'. ie "IsNvidia() && IsApple()" | |
| 128 | + | const char *condition; | |
| 129 | + | }; | |
| 130 | + | ||
| 131 | + | inline Feature::Feature(const Feature &other) = default; | |
| 132 | + | inline Feature::Feature(const char *name, | |
| 133 | + | const FeatureCategory &category, | |
| 134 | + | const char *description, | |
| 135 | + | FeatureMap *const mapPtr, | |
| 136 | + | const char *bug = "") | |
| 137 | + | : name(name), | |
| 138 | + | category(category), | |
| 139 | + | description(description), | |
| 140 | + | bug(bug), | |
| 141 | + | enabled(false), | |
| 142 | + | condition("") | |
| 143 | + | { | |
| 144 | + | if (mapPtr != nullptr) | |
| 145 | + | { | |
| 146 | + | (*mapPtr)[std::string(name)] = this; | |
| 147 | + | } | |
| 148 | + | } | |
| 149 | + | ||
| 150 | + | inline Feature::~Feature() = default; | |
| 151 | + | ||
| 152 | + | struct FeatureSetBase | |
| 153 | + | { | |
| 154 | + | public: | |
| 155 | + | FeatureSetBase(); | |
| 156 | + | ~FeatureSetBase(); | |
| 157 | + | ||
| 158 | + | private: | |
| 159 | + | // Non-copyable | |
| 160 | + | FeatureSetBase(const FeatureSetBase &other) = delete; | |
| 161 | + | FeatureSetBase &operator=(const FeatureSetBase &other) = delete; | |
| 162 | + | ||
| 163 | + | protected: | |
| 164 | + | FeatureMap members = FeatureMap(); | |
| 165 | + | ||
| 166 | + | public: | |
| 167 | + | void overrideFeatures(const std::vector<std::string> &feature_names, const bool enabled) | |
| 168 | + | { | |
| 169 | + | for (const std::string &name : feature_names) | |
| 170 | + | { | |
| 171 | + | if (members.find(name) != members.end()) | |
| 172 | + | { | |
| 173 | + | members[name]->enabled = enabled; | |
| 174 | + | } | |
| 175 | + | } | |
| 176 | + | } | |
| 177 | + | ||
| 178 | + | void populateFeatureList(FeatureList *features) const | |
| 179 | + | { | |
| 180 | + | for (FeatureMap::const_iterator it = members.begin(); it != members.end(); it++) | |
| 181 | + | { | |
| 182 | + | features->push_back(it->second); | |
| 183 | + | } | |
| 184 | + | } | |
| 185 | + | }; | |
| 186 | + | ||
| 187 | + | inline FeatureSetBase::FeatureSetBase() = default; | |
| 188 | + | inline FeatureSetBase::~FeatureSetBase() = default; | |
| 189 | + | ||
| 190 | + | } // namespace angle | |
| 191 | + | ||
| 192 | + | #endif // ANGLE_PLATFORM_WORKAROUND_H_ |
| @@ -0,0 +1,222 @@ | |||
| 1 | + | // | |
| 2 | + | // Copyright 2015 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 | + | ||
| 7 | + | // FeaturesD3D.h: Features and workarounds for D3D driver bugs and other issues. | |
| 8 | + | ||
| 9 | + | #ifndef ANGLE_PLATFORM_FEATURESD3D_H_ | |
| 10 | + | #define ANGLE_PLATFORM_FEATURESD3D_H_ | |
| 11 | + | ||
| 12 | + | #include "platform/Feature.h" | |
| 13 | + | ||
| 14 | + | namespace angle | |
| 15 | + | { | |
| 16 | + | ||
| 17 | + | // Workarounds attached to each shader. Do not need to expose information about these workarounds so | |
| 18 | + | // a simple bool struct suffices. | |
| 19 | + | struct CompilerWorkaroundsD3D | |
| 20 | + | { | |
| 21 | + | bool skipOptimization = false; | |
| 22 | + | ||
| 23 | + | bool useMaxOptimization = false; | |
| 24 | + | ||
| 25 | + | // IEEE strictness needs to be enabled for NANs to work. | |
| 26 | + | bool enableIEEEStrictness = false; | |
| 27 | + | }; | |
| 28 | + | ||
| 29 | + | struct FeaturesD3D : FeatureSetBase | |
| 30 | + | { | |
| 31 | + | FeaturesD3D(); | |
| 32 | + | ~FeaturesD3D(); | |
| 33 | + | ||
| 34 | + | // On some systems, having extra rendertargets than necessary slows down the shader. | |
| 35 | + | // We can fix this by optimizing those out of the shader. At the same time, we can | |
| 36 | + | // work around a bug on some nVidia drivers that they ignore "null" render targets | |
| 37 | + | // in D3D11, by compacting the active color attachments list to omit null entries. | |
| 38 | + | Feature mrtPerfWorkaround = {"mrt_perf_workaround", FeatureCategory::D3DWorkarounds, | |
| 39 | + | "Some drivers have a bug where they ignore null render targets", | |
| 40 | + | &members}; | |
| 41 | + | ||
| 42 | + | Feature setDataFasterThanImageUpload = {"set_data_faster_than_image_upload", | |
| 43 | + | FeatureCategory::D3DWorkarounds, | |
| 44 | + | "Set data faster than image upload", &members}; | |
| 45 | + | ||
| 46 | + | // Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level | |
| 47 | + | // zero, and ignore the other levels). D3D11 Feature Level 10+ does this by setting MaxLOD to | |
| 48 | + | // 0.0f in the Sampler state. D3D9 sets D3DSAMP_MIPFILTER to D3DTEXF_NONE. There is no | |
| 49 | + | // equivalent to this in D3D11 Feature Level 9_3. This causes problems when (for example) an | |
| 50 | + | // application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST | |
| 51 | + | // (i.e disables mipmaps). To work around this, D3D11 FL9_3 has to create two copies of the | |
| 52 | + | // texture. The textures' level zeros are identical, but only one texture has mips. | |
| 53 | + | Feature zeroMaxLodWorkaround = {"zero_max_lod", FeatureCategory::D3DWorkarounds, | |
| 54 | + | "Missing an option to disable mipmaps on a mipmapped texture", | |
| 55 | + | &members}; | |
| 56 | + | ||
| 57 | + | // Some renderers do not support Geometry Shaders so the Geometry Shader-based PointSprite | |
| 58 | + | // emulation will not work. To work around this, D3D11 FL9_3 has to use a different pointsprite | |
| 59 | + | // emulation that is implemented using instanced quads. | |
| 60 | + | Feature useInstancedPointSpriteEmulation = { | |
| 61 | + | "use_instanced_point_sprite_emulation", FeatureCategory::D3DWorkarounds, | |
| 62 | + | "Some D3D11 renderers do not support geometry shaders for pointsprite emulation", &members}; | |
| 63 | + | ||
| 64 | + | // A bug fixed in NVIDIA driver version 347.88 < x <= 368.81 triggers a TDR when using | |
| 65 | + | // CopySubresourceRegion from a staging texture to a depth/stencil in D3D11. The workaround | |
| 66 | + | // is to use UpdateSubresource to trigger an extra copy. We disable this workaround on newer | |
| 67 | + | // NVIDIA driver versions because of a second driver bug present with the workaround enabled. | |
| 68 | + | // (See: http://anglebug.com/1452) | |
| 69 | + | Feature depthStencilBlitExtraCopy = { | |
| 70 | + | "depth_stencil_blit_extra_copy", FeatureCategory::D3DWorkarounds, | |
| 71 | + | "Bug in some drivers triggers a TDR when using CopySubresourceRegion from a staging " | |
| 72 | + | "texture to a depth/stencil", | |
| 73 | + | &members, "http://anglebug.com/1452"}; | |
| 74 | + | ||
| 75 | + | // The HLSL optimizer has a bug with optimizing "pow" in certain integer-valued expressions. | |
| 76 | + | // We can work around this by expanding the pow into a series of multiplies if we're running | |
| 77 | + | // under the affected compiler. | |
| 78 | + | Feature expandIntegerPowExpressions = { | |
| 79 | + | "expand_integer_pow_expressions", FeatureCategory::D3DWorkarounds, | |
| 80 | + | "The HLSL optimizer has a bug with optimizing 'pow' in certain integer-valued expressions", | |
| 81 | + | &members}; | |
| 82 | + | ||
| 83 | + | // NVIDIA drivers sometimes write out-of-order results to StreamOut buffers when transform | |
| 84 | + | // feedback is used to repeatedly write to the same buffer positions. | |
| 85 | + | Feature flushAfterEndingTransformFeedback = { | |
| 86 | + | "flush_after_ending_transform_feedback", FeatureCategory::D3DWorkarounds, | |
| 87 | + | "Some drivers sometimes write out-of-order results to StreamOut buffers when transform " | |
| 88 | + | "feedback is used to repeatedly write to the same buffer positions", | |
| 89 | + | &members}; | |
| 90 | + | ||
| 91 | + | // Some drivers (NVIDIA) do not take into account the base level of the texture in the results | |
| 92 | + | // of the HLSL GetDimensions builtin. | |
| 93 | + | Feature getDimensionsIgnoresBaseLevel = { | |
| 94 | + | "get_dimensions_ignores_base_level", FeatureCategory::D3DWorkarounds, | |
| 95 | + | "Some drivers do not take into account the base level of the " | |
| 96 | + | "texture in the results of the HLSL GetDimensions builtin", | |
| 97 | + | &members}; | |
| 98 | + | ||
| 99 | + | // On some Intel drivers, HLSL's function texture.Load returns 0 when the parameter Location | |
| 100 | + | // is negative, even if the sum of Offset and Location is in range. This may cause errors when | |
| 101 | + | // translating GLSL's function texelFetchOffset into texture.Load, as it is valid for | |
| 102 | + | // texelFetchOffset to use negative texture coordinates as its parameter P when the sum of P | |
| 103 | + | // and Offset is in range. To work around this, we translate texelFetchOffset into texelFetch | |
| 104 | + | // by adding Offset directly to Location before reading the texture. | |
| 105 | + | Feature preAddTexelFetchOffsets = { | |
| 106 | + | "pre_add_texel_fetch_offsets", FeatureCategory::D3DWorkarounds, | |
| 107 | + | "HLSL's function texture.Load returns 0 when the parameter Location is negative, even if " | |
| 108 | + | "the sum of Offset and Location is in range", | |
| 109 | + | &members}; | |
| 110 | + | ||
| 111 | + | // On some AMD drivers, 1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly. | |
| 112 | + | // We can work around this bug by doing an internal blit to a temporary single-channel texture | |
| 113 | + | // before we sample. | |
| 114 | + | Feature emulateTinyStencilTextures = { | |
| 115 | + | "emulate_tiny_stencil_textures", FeatureCategory::D3DWorkarounds, | |
| 116 | + | "1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly", &members}; | |
| 117 | + | ||
| 118 | + | // In Intel driver, the data with format DXGI_FORMAT_B5G6R5_UNORM will be parsed incorrectly. | |
| 119 | + | // This workaroud will disable B5G6R5 support when it's Intel driver. By default, it will use | |
| 120 | + | // R8G8B8A8 format. This bug is fixed in version 4539 on Intel drivers. | |
| 121 | + | // On older AMD drivers, the data in DXGI_FORMAT_B5G6R5_UNORM becomes corrupted for unknown | |
| 122 | + | // reasons. | |
| 123 | + | Feature disableB5G6R5Support = {"disable_b5g6r5_support", FeatureCategory::D3DWorkarounds, | |
| 124 | + | "Textures with the format " | |
| 125 | + | "DXGI_FORMAT_B5G6R5_UNORM have incorrect data", | |
| 126 | + | &members}; | |
| 127 | + | ||
| 128 | + | // On some Intel drivers, evaluating unary minus operator on integer may get wrong answer in | |
| 129 | + | // vertex shaders. To work around this bug, we translate -(int) into ~(int)+1. | |
| 130 | + | // This driver bug is fixed in 20.19.15.4624. | |
| 131 | + | Feature rewriteUnaryMinusOperator = { | |
| 132 | + | "rewrite_unary_minus_operator", FeatureCategory::D3DWorkarounds, | |
| 133 | + | "Evaluating unary minus operator on integer may get wrong answer in vertex shaders", | |
| 134 | + | &members}; | |
| 135 | + | ||
| 136 | + | // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around | |
| 137 | + | // this bug, we use an expression to emulate function isnan(). | |
| 138 | + | // Tracking bug: https://crbug.com/650547 | |
| 139 | + | // This driver bug is fixed in 21.20.16.4542. | |
| 140 | + | Feature emulateIsnanFloat = {"emulate_isnan_float", FeatureCategory::D3DWorkarounds, | |
| 141 | + | "Using isnan() on highp float will get wrong answer", &members, | |
| 142 | + | "https://crbug.com/650547"}; | |
| 143 | + | ||
| 144 | + | // On some Intel drivers, using clear() may not take effect. To work around this bug, we call | |
| 145 | + | // clear() twice on these platforms. | |
| 146 | + | // Tracking bug: https://crbug.com/655534 | |
| 147 | + | Feature callClearTwice = {"call_clear_twice", FeatureCategory::D3DWorkarounds, | |
| 148 | + | "Using clear() may not take effect", &members, | |
| 149 | + | "https://crbug.com/655534"}; | |
| 150 | + | ||
| 151 | + | // On some Intel drivers, copying from staging storage to constant buffer storage does not | |
| 152 | + | // seem to work. Work around this by keeping system memory storage as a canonical reference | |
| 153 | + | // for buffer data. | |
| 154 | + | // D3D11-only workaround. See http://crbug.com/593024. | |
| 155 | + | Feature useSystemMemoryForConstantBuffers = {"use_system_memory_for_constant_buffers", | |
| 156 | + | FeatureCategory::D3DWorkarounds, | |
| 157 | + | "Copying from staging storage to constant buffer " | |
| 158 | + | "storage does not work", | |
| 159 | + | &members, "https://crbug.com/593024"}; | |
| 160 | + | ||
| 161 | + | // This workaround is for the ANGLE_multiview extension. If enabled the viewport or render | |
| 162 | + | // target slice will be selected in the geometry shader stage. The workaround flag is added to | |
| 163 | + | // make it possible to select the code path in end2end and performance tests. | |
| 164 | + | Feature selectViewInGeometryShader = { | |
| 165 | + | "select_view_in_geometry_shader", FeatureCategory::D3DWorkarounds, | |
| 166 | + | "The viewport or render target slice will be selected in the geometry shader stage for " | |
| 167 | + | "the ANGLE_multiview extension", | |
| 168 | + | &members}; | |
| 169 | + | ||
| 170 | + | // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel | |
| 171 | + | // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel | |
| 172 | + | // shader. | |
| 173 | + | // 1. If rendertarget is not set, the pixel shader will be recompiled to drop 'SV_TARGET'. | |
| 174 | + | // When using a pixel shader with no 'SV_TARGET' in a draw, the pixels are always generated even | |
| 175 | + | // if they should be discard by 'discard' statements. | |
| 176 | + | // 2. If ID3D11BlendState.RenderTarget[].RenderTargetWriteMask is 0 and rendertarget is not set, | |
| 177 | + | // then rendering samples also pass neglecting discard statements in pixel shader. | |
| 178 | + | // So we add a dummy texture as render target in such case. See http://anglebug.com/2152 | |
| 179 | + | Feature addDummyTextureNoRenderTarget = { | |
| 180 | + | "add_dummy_texture_no_render_target", FeatureCategory::D3DWorkarounds, | |
| 181 | + | "On some drivers when rendering with no render target, two bugs lead to incorrect behavior", | |
| 182 | + | &members, "http://anglebug.com/2152"}; | |
| 183 | + | ||
| 184 | + | // Don't use D3D constant register zero when allocating space for uniforms in the vertex shader. | |
| 185 | + | // This is targeted to work around a bug in NVIDIA D3D driver version 388.59 where in very | |
| 186 | + | // specific cases the driver would not handle constant register zero correctly. | |
| 187 | + | Feature skipVSConstantRegisterZero = { | |
| 188 | + | "skip_vs_constant_register_zero", FeatureCategory::D3DWorkarounds, | |
| 189 | + | "In specific cases the driver doesn't handle constant register zero correctly", &members}; | |
| 190 | + | ||
| 191 | + | // Forces the value returned from an atomic operations to be always be resolved. This is | |
| 192 | + | // targeted to workaround a bug in NVIDIA D3D driver where the return value from | |
| 193 | + | // RWByteAddressBuffer.InterlockedAdd does not get resolved when used in the .yzw components of | |
| 194 | + | // a RWByteAddressBuffer.Store operation. Only has an effect on HLSL translation. | |
| 195 | + | // http://anglebug.com/3246 | |
| 196 | + | Feature forceAtomicValueResolution = { | |
| 197 | + | "force_atomic_value_resolution", FeatureCategory::D3DWorkarounds, | |
| 198 | + | "On some drivers the return value from RWByteAddressBuffer.InterlockedAdd does not resolve " | |
| 199 | + | "when used in the .yzw components of a RWByteAddressBuffer.Store operation", | |
| 200 | + | &members, "http://anglebug.com/3246"}; | |
| 201 | + | ||
| 202 | + | // Match chromium's robust resource init behaviour by always prefering to upload texture data | |
| 203 | + | // instead of clearing. Clear calls have been observed to cause texture corruption for some | |
| 204 | + | // formats. | |
| 205 | + | Feature allowClearForRobustResourceInit = { | |
| 206 | + | "allow_clear_for_robust_resource_init", FeatureCategory::D3DWorkarounds, | |
| 207 | + | "Some drivers corrupt texture data when clearing for robust resource initialization.", | |
| 208 | + | &members, "http://crbug.com/941620"}; | |
| 209 | + | ||
| 210 | + | // Don't translate uniform block to StructuredBuffer on Windows 7 and earlier. This is targeted | |
| 211 | + | // to work around a bug that fails to allocate ShaderResourceView for StructuredBuffer. | |
| 212 | + | Feature dontTranslateUniformBlockToStructuredBuffer = { | |
| 213 | + | "dont_translate_uniform_block_to_structured_buffer", FeatureCategory::D3DWorkarounds, | |
| 214 | + | "Fails to allocate ShaderResourceView for StructuredBuffer on some drivers", &members}; | |
| 215 | + | }; | |
| 216 | + | ||
| 217 | + | inline FeaturesD3D::FeaturesD3D() = default; | |
| 218 | + | inline FeaturesD3D::~FeaturesD3D() = default; | |
| 219 | + | ||
| 220 | + | } // namespace angle | |
| 221 | + | ||
| 222 | + | #endif // ANGLE_PLATFORM_FEATURESD3D_H_ |
| @@ -0,0 +1,440 @@ | |||
| 1 | + | // | |
| 2 | + | // Copyright 2015 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 | + | ||
| 7 | + | // FeaturesGL.h: Features and workarounds for GL driver bugs and other issues. | |
| 8 | + | ||
| 9 | + | #ifndef ANGLE_PLATFORM_FEATURESGL_H_ | |
| 10 | + | #define ANGLE_PLATFORM_FEATURESGL_H_ | |
| 11 | + | ||
| 12 | + | #include "platform/Feature.h" | |
| 13 | + | ||
| 14 | + | namespace angle | |
| 15 | + | { | |
| 16 | + | ||
| 17 | + | struct FeaturesGL : FeatureSetBase | |
| 18 | + | { | |
| 19 | + | FeaturesGL(); | |
| 20 | + | ~FeaturesGL(); | |
| 21 | + | ||
| 22 | + | // When writing a float to a normalized integer framebuffer, desktop OpenGL is allowed to write | |
| 23 | + | // one of the two closest normalized integer representations (although round to nearest is | |
| 24 | + | // preferred) (see section 2.3.5.2 of the GL 4.5 core specification). OpenGL ES requires that | |
| 25 | + | // round-to-nearest is used (see "Conversion from Floating-Point to Framebuffer Fixed-Point" in | |
| 26 | + | // section 2.1.2 of the OpenGL ES 2.0.25 spec). This issue only shows up on AMD drivers on | |
| 27 | + | // framebuffer formats that have 1-bit alpha, work around this by using higher precision formats | |
| 28 | + | // instead. | |
| 29 | + | Feature avoid1BitAlphaTextureFormats = {"avoid_1_bit_alpha_texture_formats", | |
| 30 | + | FeatureCategory::OpenGLWorkarounds, | |
| 31 | + | "Issue with 1-bit alpha framebuffer formats", &members}; | |
| 32 | + | ||
| 33 | + | // On some older Intel drivers, GL_RGBA4 is not color renderable, glCheckFramebufferStatus | |
| 34 | + | // returns GL_FRAMEBUFFER_UNSUPPORTED. Work around this by using a known color-renderable | |
| 35 | + | // format. | |
| 36 | + | Feature rgba4IsNotSupportedForColorRendering = {"rgba4_is_not_supported_for_color_rendering", | |
| 37 | + | FeatureCategory::OpenGLWorkarounds, | |
| 38 | + | "GL_RGBA4 is not color renderable", &members}; | |
| 39 | + | ||
| 40 | + | // When clearing a framebuffer on Intel or AMD drivers, when GL_FRAMEBUFFER_SRGB is enabled, the | |
| 41 | + | // driver clears to the linearized clear color despite the framebuffer not supporting SRGB | |
| 42 | + | // blending. It only seems to do this when the framebuffer has only linear attachments, mixed | |
| 43 | + | // attachments appear to get the correct clear color. | |
| 44 | + | Feature doesSRGBClearsOnLinearFramebufferAttachments = { | |
| 45 | + | "does_srgb_clears_on_linear_framebuffer_attachments", FeatureCategory::OpenGLWorkarounds, | |
| 46 | + | "Issue clearing framebuffers with linear attachments when GL_FRAMEBUFFER_SRGB is enabled", | |
| 47 | + | &members}; | |
| 48 | + | ||
| 49 | + | // On Mac some GLSL constructs involving do-while loops cause GPU hangs, such as the following: | |
| 50 | + | // int i = 1; | |
| 51 | + | // do { | |
| 52 | + | // i --; | |
| 53 | + | // continue; | |
| 54 | + | // } while (i > 0) | |
| 55 | + | // Work around this by rewriting the do-while to use another GLSL construct (block + while) | |
| 56 | + | Feature doWhileGLSLCausesGPUHang = { | |
| 57 | + | "do_while_glsl_causes_gpu_hang", FeatureCategory::OpenGLWorkarounds, | |
| 58 | + | "Some GLSL constructs involving do-while loops cause GPU hangs", &members, | |
| 59 | + | "http://crbug.com/644669"}; | |
| 60 | + | ||
| 61 | + | // On Mac AMD GPU gl_VertexID in GLSL vertex shader doesn't include base vertex value, | |
| 62 | + | // Work aronud this by replace gl_VertexID with (gl_VertexID - angle_BaseVertex) when | |
| 63 | + | // angle_BaseVertex is present. | |
| 64 | + | Feature addBaseVertexToVertexID = { | |
| 65 | + | "vertex_id_does_not_include_base_vertex", FeatureCategory::OpenGLWorkarounds, | |
| 66 | + | "gl_VertexID in GLSL vertex shader doesn't include base vertex value", &members}; | |
| 67 | + | ||
| 68 | + | // Calling glFinish doesn't cause all queries to report that the result is available on some | |
| 69 | + | // (NVIDIA) drivers. It was found that enabling GL_DEBUG_OUTPUT_SYNCHRONOUS before the finish | |
| 70 | + | // causes it to fully finish. | |
| 71 | + | Feature finishDoesNotCauseQueriesToBeAvailable = { | |
| 72 | + | "finish_does_not_cause_queries_to_be_available", FeatureCategory::OpenGLWorkarounds, | |
| 73 | + | "glFinish doesn't cause all queries to report available result", &members}; | |
| 74 | + | ||
| 75 | + | // Always call useProgram after a successful link to avoid a driver bug. | |
| 76 | + | // This workaround is meant to reproduce the use_current_program_after_successful_link | |
| 77 | + | // workaround in Chromium (http://crbug.com/110263). It has been shown that this workaround is | |
| 78 | + | // not necessary for MacOSX 10.9 and higher (http://crrev.com/39eb535b). | |
| 79 | + | Feature alwaysCallUseProgramAfterLink = { | |
| 80 | + | "always_call_use_program_after_link", FeatureCategory::OpenGLWorkarounds, | |
| 81 | + | "Always call useProgram after a successful link to avoid a driver bug", &members, | |
| 82 | + | "http://crbug.com/110263"}; | |
| 83 | + | ||
| 84 | + | // On NVIDIA, in the case of unpacking from a pixel unpack buffer, unpack overlapping rows row | |
| 85 | + | // by row. | |
| 86 | + | Feature unpackOverlappingRowsSeparatelyUnpackBuffer = { | |
| 87 | + | "unpack_overlapping_rows_separately_unpack_buffer", FeatureCategory::OpenGLWorkarounds, | |
| 88 | + | "In the case of unpacking from a pixel unpack buffer, unpack overlapping rows row by row", | |
| 89 | + | &members}; | |
| 90 | + | ||
| 91 | + | // On NVIDIA, in the case of packing to a pixel pack buffer, pack overlapping rows row by row. | |
| 92 | + | Feature packOverlappingRowsSeparatelyPackBuffer = { | |
| 93 | + | "pack_overlapping_rows_separately_pack_buffer", FeatureCategory::OpenGLWorkarounds, | |
| 94 | + | "In the case of packing to a pixel pack buffer, pack overlapping rows row by row", | |
| 95 | + | &members}; | |
| 96 | + | ||
| 97 | + | // On NVIDIA, during initialization, assign the current vertex attributes to the spec-mandated | |
| 98 | + | // defaults. | |
| 99 | + | Feature initializeCurrentVertexAttributes = { | |
| 100 | + | "initialize_current_vertex_attributes", FeatureCategory::OpenGLWorkarounds, | |
| 101 | + | "During initialization, assign the current vertex attributes to the spec-mandated defaults", | |
| 102 | + | &members}; | |
| 103 | + | ||
| 104 | + | // abs(i) where i is an integer returns unexpected result on Intel Mac. | |
| 105 | + | // Emulate abs(i) with i * sign(i). | |
| 106 | + | Feature emulateAbsIntFunction = {"emulate_abs_int_function", FeatureCategory::OpenGLWorkarounds, | |
| 107 | + | "abs(i) where i is an integer returns unexpected result", | |
| 108 | + | &members, "http://crbug.com/642227"}; | |
| 109 | + | ||
| 110 | + | // On Intel Mac, calculation of loop conditions in for and while loop has bug. | |
| 111 | + | // Add "&& true" to the end of the condition expression to work around the bug. | |
| 112 | + | Feature addAndTrueToLoopCondition = { | |
| 113 | + | "add_and_true_to_loop_condition", FeatureCategory::OpenGLWorkarounds, | |
| 114 | + | "Calculation of loop conditions in for and while loop has bug", &members}; | |
| 115 | + | ||
| 116 | + | // When uploading textures from an unpack buffer, some drivers count an extra row padding when | |
| 117 | + | // checking if the pixel unpack buffer is big enough. Tracking bug: http://anglebug.com/1512 | |
| 118 | + | // For example considering the pixel buffer below where in memory, each row data (D) of the | |
| 119 | + | // texture is followed by some unused data (the dots): | |
| 120 | + | // +-------+--+ | |
| 121 | + | // |DDDDDDD|..| | |
| 122 | + | // |DDDDDDD|..| | |
| 123 | + | // |DDDDDDD|..| | |
| 124 | + | // |DDDDDDD|..| | |
| 125 | + | // +-------A--B | |
| 126 | + | // The last pixel read will be A, but the driver will think it is B, causing it to generate an | |
| 127 | + | // error when the pixel buffer is just big enough. | |
| 128 | + | Feature unpackLastRowSeparatelyForPaddingInclusion = { | |
| 129 | + | "unpack_last_row_separately_for_padding_inclusion", FeatureCategory::OpenGLWorkarounds, | |
| 130 | + | "When uploading textures from an unpack buffer, some drivers count an extra row padding", | |
| 131 | + | &members, "http://anglebug.com/1512"}; | |
| 132 | + | ||
| 133 | + | // Equivalent workaround when uploading data from a pixel pack buffer. | |
| 134 | + | Feature packLastRowSeparatelyForPaddingInclusion = { | |
| 135 | + | "pack_last_row_separately_for_padding_inclusion", FeatureCategory::OpenGLWorkarounds, | |
| 136 | + | "When uploading textures from an pack buffer, some drivers count an extra row padding", | |
| 137 | + | &members, "http://anglebug.com/1512"}; | |
| 138 | + | ||
| 139 | + | // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around | |
| 140 | + | // this bug, we use an expression to emulate function isnan(). | |
| 141 | + | // Tracking bug: http://crbug.com/650547 | |
| 142 | + | Feature emulateIsnanFloat = {"emulate_isnan_float", FeatureCategory::OpenGLWorkarounds, | |
| 143 | + | "Using isnan() on highp float will get wrong answer", &members, | |
| 144 | + | "http://crbug.com/650547"}; | |
| 145 | + | ||
| 146 | + | // On Mac with OpenGL version 4.1, unused std140 or shared uniform blocks will be | |
| 147 | + | // treated as inactive which is not consistent with WebGL2.0 spec. Reference all members in a | |
| 148 | + | // unused std140 or shared uniform block at the beginning of main to work around it. | |
| 149 | + | // Also used on Linux AMD. | |
| 150 | + | Feature useUnusedBlocksWithStandardOrSharedLayout = { | |
| 151 | + | "use_unused_blocks_with_standard_or_shared_layout", FeatureCategory::OpenGLWorkarounds, | |
| 152 | + | "Unused std140 or shared uniform blocks will be treated as inactive", &members}; | |
| 153 | + | ||
| 154 | + | // This flag is used to fix spec difference between GLSL 4.1 or lower and ESSL3. | |
| 155 | + | Feature removeInvariantAndCentroidForESSL3 = { | |
| 156 | + | "remove_invarient_and_centroid_for_essl3", FeatureCategory::OpenGLWorkarounds, | |
| 157 | + | "Fix spec difference between GLSL 4.1 or lower and ESSL3", &members}; | |
| 158 | + | ||
| 159 | + | // On Intel Mac OSX 10.11 driver, using "-float" will get wrong answer. Use "0.0 - float" to | |
| 160 | + | // replace "-float". | |
| 161 | + | // Tracking bug: http://crbug.com/308366 | |
| 162 | + | Feature rewriteFloatUnaryMinusOperator = { | |
| 163 | + | "rewrite_float_unary_minus_operator", FeatureCategory::OpenGLWorkarounds, | |
| 164 | + | "Using '-<float>' will get wrong answer", &members, "http://crbug.com/308366"}; | |
| 165 | + | ||
| 166 | + | // On NVIDIA drivers, atan(y, x) may return a wrong answer. | |
| 167 | + | // Tracking bug: http://crbug.com/672380 | |
| 168 | + | Feature emulateAtan2Float = {"emulate_atan_2_float", FeatureCategory::OpenGLWorkarounds, | |
| 169 | + | "atan(y, x) may return a wrong answer", &members, | |
| 170 | + | "http://crbug.com/672380"}; | |
| 171 | + | ||
| 172 | + | // Some drivers seem to forget about UBO bindings when using program binaries. Work around | |
| 173 | + | // this by re-applying the bindings after the program binary is loaded or saved. | |
| 174 | + | // This only seems to affect AMD OpenGL drivers, and some Android devices. | |
| 175 | + | // http://anglebug.com/1637 | |
| 176 | + | Feature reapplyUBOBindingsAfterUsingBinaryProgram = { | |
| 177 | + | "reapply_ubo_bindings_after_using_binary_program", FeatureCategory::OpenGLWorkarounds, | |
| 178 | + | "Some drivers forget about UBO bindings when using program binaries", &members, | |
| 179 | + | "http://anglebug.com/1637"}; | |
| 180 | + | ||
| 181 | + | // Some Linux OpenGL drivers return 0 when we query MAX_VERTEX_ATTRIB_STRIDE in an OpenGL 4.4 or | |
| 182 | + | // higher context. | |
| 183 | + | // This only seems to affect AMD OpenGL drivers. | |
| 184 | + | // Tracking bug: http://anglebug.com/1936 | |
| 185 | + | Feature emulateMaxVertexAttribStride = { | |
| 186 | + | "emulate_max_vertex_attrib_stride", FeatureCategory::OpenGLWorkarounds, | |
| 187 | + | "Some drivers return 0 when MAX_VERTEX_ATTRIB_STRIED queried", &members, | |
| 188 | + | "http://anglebug.com/1936"}; | |
| 189 | + | ||
| 190 | + | // Initializing uninitialized locals caused odd behavior on Android Qualcomm in a few WebGL 2 | |
| 191 | + | // tests. Tracking bug: http://anglebug.com/2046 | |
| 192 | + | Feature dontInitializeUninitializedLocals = { | |
| 193 | + | "dont_initialize_uninitialized_locals", FeatureCategory::OpenGLWorkarounds, | |
| 194 | + | "Initializing uninitialized locals caused odd behavior in a few WebGL 2 tests", &members, | |
| 195 | + | "http://anglebug.com/2046"}; | |
| 196 | + | ||
| 197 | + | // On some NVIDIA drivers the point size range reported from the API is inconsistent with the | |
| 198 | + | // actual behavior. Clamp the point size to the value from the API to fix this. | |
| 199 | + | Feature clampPointSize = { | |
| 200 | + | "clamp_point_size", FeatureCategory::OpenGLWorkarounds, | |
| 201 | + | "The point size range reported from the API is inconsistent with the actual behavior", | |
| 202 | + | &members}; | |
| 203 | + | ||
| 204 | + | // On some NVIDIA drivers certain types of GLSL arithmetic ops mixing vectors and scalars may be | |
| 205 | + | // executed incorrectly. Change them in the shader translator. Tracking bug: | |
| 206 | + | // http://crbug.com/772651 | |
| 207 | + | Feature rewriteVectorScalarArithmetic = {"rewrite_vector_scalar_arithmetic", | |
| 208 | + | FeatureCategory::OpenGLWorkarounds, | |
| 209 | + | "Certain types of GLSL arithmetic ops mixing vectors " | |
| 210 | + | "and scalars may be executed incorrectly", | |
| 211 | + | &members, "http://crbug.com/772651"}; | |
| 212 | + | ||
| 213 | + | // On some Android devices for loops used to initialize variables hit native GLSL compiler bugs. | |
| 214 | + | Feature dontUseLoopsToInitializeVariables = { | |
| 215 | + | "dont_use_loops_to_initialize_variables", FeatureCategory::OpenGLWorkarounds, | |
| 216 | + | "For loops used to initialize variables hit native GLSL compiler bugs", &members, | |
| 217 | + | "http://crbug.com/809422"}; | |
| 218 | + | ||
| 219 | + | // On some NVIDIA drivers gl_FragDepth is not clamped correctly when rendering to a floating | |
| 220 | + | // point depth buffer. Clamp it in the translated shader to fix this. | |
| 221 | + | Feature clampFragDepth = { | |
| 222 | + | "clamp_frag_depth", FeatureCategory::OpenGLWorkarounds, | |
| 223 | + | "gl_FragDepth is not clamped correctly when rendering to a floating point depth buffer", | |
| 224 | + | &members}; | |
| 225 | + | ||
| 226 | + | // On some NVIDIA drivers before version 397.31 repeated assignment to swizzled values inside a | |
| 227 | + | // GLSL user-defined function have incorrect results. Rewrite this type of statements to fix | |
| 228 | + | // this. | |
| 229 | + | Feature rewriteRepeatedAssignToSwizzled = {"rewrite_repeated_assign_to_swizzled", | |
| 230 | + | FeatureCategory::OpenGLWorkarounds, | |
| 231 | + | "Repeated assignment to swizzled values inside a " | |
| 232 | + | "GLSL user-defined function have incorrect results", | |
| 233 | + | &members}; | |
| 234 | + | ||
| 235 | + | // On some AMD and Intel GL drivers ARB_blend_func_extended does not pass the tests. | |
| 236 | + | // It might be possible to work around the Intel bug by rewriting *FragData to *FragColor | |
| 237 | + | // instead of disabling the functionality entirely. The AMD bug looked like incorrect blending, | |
| 238 | + | // not sure if a workaround is feasible. http://anglebug.com/1085 | |
| 239 | + | Feature disableBlendFuncExtended = { | |
| 240 | + | "disable_blend_func_extended", FeatureCategory::OpenGLWorkarounds, | |
| 241 | + | "ARB_blend_func_extended does not pass the tests", &members, "http://anglebug.com/1085"}; | |
| 242 | + | ||
| 243 | + | // Qualcomm drivers returns raw sRGB values instead of linearized values when calling | |
| 244 | + | // glReadPixels on unsized sRGB texture formats. http://crbug.com/550292 and | |
| 245 | + | // http://crbug.com/565179 | |
| 246 | + | Feature unsizedsRGBReadPixelsDoesntTransform = { | |
| 247 | + | "unsized_srgb_read_pixels_doesnt_transform", FeatureCategory::OpenGLWorkarounds, | |
| 248 | + | "Drivers returning raw sRGB values instead of linearized values when calling glReadPixels " | |
| 249 | + | "on unsized sRGB texture formats", | |
| 250 | + | &members, "http://crbug.com/565179"}; | |
| 251 | + | ||
| 252 | + | // Older Qualcomm drivers generate errors when querying the number of bits in timer queries, ex: | |
| 253 | + | // GetQueryivEXT(GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS). http://anglebug.com/3027 | |
| 254 | + | Feature queryCounterBitsGeneratesErrors = { | |
| 255 | + | "query_counter_bits_generates_errors", FeatureCategory::OpenGLWorkarounds, | |
| 256 | + | "Drivers generate errors when querying the number of bits in timer queries", &members, | |
| 257 | + | "http://anglebug.com/3027"}; | |
| 258 | + | ||
| 259 | + | // Re-linking a program in parallel is buggy on some Intel Windows OpenGL drivers and Android | |
| 260 | + | // platforms. | |
| 261 | + | // http://anglebug.com/3045 | |
| 262 | + | Feature dontRelinkProgramsInParallel = { | |
| 263 | + | "dont_relink_programs_in_parallel", FeatureCategory::OpenGLWorkarounds, | |
| 264 | + | "Relinking a program in parallel is buggy", &members, "http://anglebug.com/3045"}; | |
| 265 | + | ||
| 266 | + | // Some tests have been seen to fail using worker contexts, this switch allows worker contexts | |
| 267 | + | // to be disabled for some platforms. http://crbug.com/849576 | |
| 268 | + | Feature disableWorkerContexts = {"disable_worker_contexts", FeatureCategory::OpenGLWorkarounds, | |
| 269 | + | "Some tests have been seen to fail using worker contexts", | |
| 270 | + | &members, "http://crbug.com/849576"}; | |
| 271 | + | ||
| 272 | + | // Most Android devices fail to allocate a texture that is larger than 4096. Limit the caps | |
| 273 | + | // instead of generating GL_OUT_OF_MEMORY errors. Also causes system to hang on some older | |
| 274 | + | // intel mesa drivers on Linux. | |
| 275 | + | Feature limitMaxTextureSizeTo4096 = {"max_texture_size_limit_4096", | |
| 276 | + | FeatureCategory::OpenGLWorkarounds, | |
| 277 | + | "Limit max texture size to 4096 to avoid frequent " | |
| 278 | + | "out-of-memory errors", | |
| 279 | + | &members, "http://crbug.com/927470"}; | |
| 280 | + | ||
| 281 | + | // Prevent excessive MSAA allocations on Android devices, various rendering bugs have been | |
| 282 | + | // observed and they tend to be high DPI anyways. http://crbug.com/797243 | |
| 283 | + | Feature limitMaxMSAASamplesTo4 = { | |
| 284 | + | "max_msaa_sample_count_4", FeatureCategory::OpenGLWorkarounds, | |
| 285 | + | "Various rendering bugs have been observed when using higher MSAA counts", &members, | |
| 286 | + | "http://crbug.com/797243"}; | |
| 287 | + | ||
| 288 | + | // Prefer to do the robust resource init clear using a glClear. Calls to TexSubImage2D on large | |
| 289 | + | // textures can take hundreds of milliseconds because of slow uploads on macOS. Do this only on | |
| 290 | + | // macOS because clears are buggy on other drivers. | |
| 291 | + | // https://crbug.com/848952 (slow uploads on macOS) | |
| 292 | + | // https://crbug.com/883276 (buggy clears on Android) | |
| 293 | + | Feature allowClearForRobustResourceInit = { | |
| 294 | + | "allow_clear_for_robust_resource_init", FeatureCategory::OpenGLWorkarounds, | |
| 295 | + | "Using glClear for robust resource initialization is buggy on some drivers and leads to " | |
| 296 | + | "texture corruption. Default to data uploads except on MacOS where it is very slow.", | |
| 297 | + | &members, "http://crbug.com/883276"}; | |
| 298 | + | ||
| 299 | + | // Some drivers automatically handle out-of-bounds uniform array access but others need manual | |
| 300 | + | // clamping to satisfy the WebGL requirements. | |
| 301 | + | Feature clampArrayAccess = {"clamp_array_access", FeatureCategory::OpenGLWorkarounds, | |
| 302 | + | "Clamp uniform array access to avoid reading invalid memory.", | |
| 303 | + | &members, "http://anglebug.com/2978"}; | |
| 304 | + | ||
| 305 | + | // Reset glTexImage2D base level to workaround pixel comparison failure above Mac OS 10.12.4 on | |
| 306 | + | // Intel Mac. | |
| 307 | + | Feature resetTexImage2DBaseLevel = {"reset_teximage2d_base_level", | |
| 308 | + | FeatureCategory::OpenGLWorkarounds, | |
| 309 | + | "Reset texture base level before calling glTexImage2D to " | |
| 310 | + | "work around pixel comparison failure.", | |
| 311 | + | &members, "https://crbug.com/705865"}; | |
| 312 | + | ||
| 313 | + | // glClearColor does not always work on Intel 6xxx Mac drivers when the clear color made up of | |
| 314 | + | // all zeros and ones. | |
| 315 | + | Feature clearToZeroOrOneBroken = { | |
| 316 | + | "clear_to_zero_or_one_broken", FeatureCategory::OpenGLWorkarounds, | |
| 317 | + | "Clears when the clear color is all zeros or ones do not work.", &members, | |
| 318 | + | "https://crbug.com/710443"}; | |
| 319 | + | ||
| 320 | + | // Some older Linux Intel mesa drivers will hang the system when allocating large textures. Fix | |
| 321 | + | // this by capping the max texture size. | |
| 322 | + | Feature limitMax3dArrayTextureSizeTo1024 = { | |
| 323 | + | "max_3d_array_texture_size_1024", FeatureCategory::OpenGLWorkarounds, | |
| 324 | + | "Limit max 3d texture size and max array texture layers to 1024 to avoid system hang", | |
| 325 | + | &members, "http://crbug.com/927470"}; | |
| 326 | + | ||
| 327 | + | // BlitFramebuffer has issues on some platforms with large source/dest texture sizes. This | |
| 328 | + | // workaround adjusts the destination rectangle source and dest rectangle to fit within maximum | |
| 329 | + | // twice the size of the framebuffer. | |
| 330 | + | Feature adjustSrcDstRegionBlitFramebuffer = { | |
| 331 | + | "adjust_src_dst_region_for_blitframebuffer", FeatureCategory::OpenGLWorkarounds, | |
| 332 | + | "Many platforms have issues with blitFramebuffer when the parameters are large.", &members, | |
| 333 | + | "http://crbug.com/830046"}; | |
| 334 | + | ||
| 335 | + | // BlitFramebuffer has issues on Mac when the source bounds aren't enclosed by the framebuffer. | |
| 336 | + | // This workaround clips the source region and adjust the dest region proportionally. | |
| 337 | + | Feature clipSrcRegionBlitFramebuffer = { | |
| 338 | + | "clip_src_region_for_blitframebuffer", FeatureCategory::OpenGLWorkarounds, | |
| 339 | + | "Issues with blitFramebuffer when the parameters don't match the framebuffer size.", | |
| 340 | + | &members, "http://crbug.com/830046"}; | |
| 341 | + | ||
| 342 | + | // Calling glTexImage2D with zero size generates GL errors | |
| 343 | + | Feature resettingTexturesGeneratesErrors = { | |
| 344 | + | "reset_texture_generates_errors", FeatureCategory::OpenGLWorkarounds, | |
| 345 | + | "Calling glTexImage2D with zero size generates errors.", &members, | |
| 346 | + | "http://anglebug.com/3859"}; | |
| 347 | + | ||
| 348 | + | // Mac Intel samples transparent black from GL_COMPRESSED_RGB_S3TC_DXT1_EXT | |
| 349 | + | Feature rgbDXT1TexturesSampleZeroAlpha = { | |
| 350 | + | "rgb_dxt1_textures_sample_zero_alpha", FeatureCategory::OpenGLWorkarounds, | |
| 351 | + | "Sampling BLACK texels from RGB DXT1 textures returns transparent black on Mac.", &members, | |
| 352 | + | "http://anglebug.com/3729"}; | |
| 353 | + | ||
| 354 | + | // Mac incorrectly executes both sides of && and || expressions when they should short-circuit. | |
| 355 | + | Feature unfoldShortCircuits = { | |
| 356 | + | "unfold_short_circuits", FeatureCategory::OpenGLWorkarounds, | |
| 357 | + | "Mac incorrectly executes both sides of && and || expressions when they should " | |
| 358 | + | "short-circuit.", | |
| 359 | + | &members, "http://anglebug.com/482"}; | |
| 360 | + | ||
| 361 | + | Feature emulatePrimitiveRestartFixedIndex = { | |
| 362 | + | "emulate_primitive_restart_fixed_index", FeatureCategory::OpenGLWorkarounds, | |
| 363 | + | "When GL_PRIMITIVE_RESTART_FIXED_INDEX is not available, emulate it with " | |
| 364 | + | "GL_PRIMITIVE_RESTART and glPrimitiveRestartIndex.", | |
| 365 | + | &members, "http://anglebug.com/3997"}; | |
| 366 | + | ||
| 367 | + | Feature setPrimitiveRestartFixedIndexForDrawArrays = { | |
| 368 | + | "set_primitive_restart_fixed_index_for_draw_arrays", FeatureCategory::OpenGLWorkarounds, | |
| 369 | + | "Some drivers discard vertex data in DrawArrays calls when the fixed primitive restart " | |
| 370 | + | "index is within the number of primitives being drawn.", | |
| 371 | + | &members, "http://anglebug.com/3997"}; | |
| 372 | + | ||
| 373 | + | // Dynamic indexing of swizzled l-values doesn't work correctly on various platforms. | |
| 374 | + | Feature removeDynamicIndexingOfSwizzledVector = { | |
| 375 | + | "remove_dynamic_indexing_of_swizzled_vector", FeatureCategory::OpenGLWorkarounds, | |
| 376 | + | "Dynamic indexing of swizzled l-values doesn't work correctly on various platforms.", | |
| 377 | + | &members, "http://crbug.com/709351"}; | |
| 378 | + | ||
| 379 | + | // Intel Mac drivers does not treat texelFetchOffset() correctly. | |
| 380 | + | Feature preAddTexelFetchOffsets = { | |
| 381 | + | "pre_add_texel_fetch_offsets", FeatureCategory::OpenGLWorkarounds, | |
| 382 | + | "Intel Mac drivers mistakenly consider the parameter position of nagative vaule as invalid " | |
| 383 | + | "even if the sum of position and offset is in range, so we need to add workarounds by " | |
| 384 | + | "rewriting texelFetchOffset(sampler, position, lod, offset) into texelFetch(sampler, " | |
| 385 | + | "position + offset, lod).", | |
| 386 | + | &members, "http://crbug.com/642605"}; | |
| 387 | + | ||
| 388 | + | // All Mac drivers do not handle struct scopes correctly. This workaround overwrites a struct | |
| 389 | + | // name with a unique prefix | |
| 390 | + | Feature regenerateStructNames = { | |
| 391 | + | "regenerate_struct_names", FeatureCategory::OpenGLWorkarounds, | |
| 392 | + | "All Mac drivers do not handle struct scopes correctly. This workaround overwrites a struct" | |
| 393 | + | "name with a unique prefix.", | |
| 394 | + | &members, "http://crbug.com/403957"}; | |
| 395 | + | ||
| 396 | + | // Quite some OpenGL ES drivers don't implement readPixels for RGBA/UNSIGNED_SHORT from | |
| 397 | + | // EXT_texture_norm16 correctly | |
| 398 | + | Feature readPixelsUsingImplementationColorReadFormatForNorm16 = { | |
| 399 | + | "read_pixels_using_implementation_color_read_format", FeatureCategory::OpenGLWorkarounds, | |
| 400 | + | "Quite some OpenGL ES drivers don't implement readPixels for RGBA/UNSIGNED_SHORT from " | |
| 401 | + | "EXT_texture_norm16 correctly", | |
| 402 | + | &members, "http://anglebug.com/4214"}; | |
| 403 | + | ||
| 404 | + | // Bugs exist in some Intel drivers where dependencies are incorrectly | |
| 405 | + | // tracked for textures which are copy destinations (via CopyTexImage2D, for | |
| 406 | + | // example). Flush before DeleteTexture if these entry points have been | |
| 407 | + | // called recently. | |
| 408 | + | Feature flushBeforeDeleteTextureIfCopiedTo = { | |
| 409 | + | "flush_before_delete_texture_if_copied_to", FeatureCategory::OpenGLWorkarounds, | |
| 410 | + | "Some drivers track CopyTex{Sub}Image texture dependencies incorrectly. Flush" | |
| 411 | + | " before glDeleteTextures in this case", | |
| 412 | + | &members, "http://anglebug.com/4267"}; | |
| 413 | + | ||
| 414 | + | // Rewrite row-major matrices as column-major as a driver bug workaround if | |
| 415 | + | // necessary. | |
| 416 | + | Feature rewriteRowMajorMatrices = { | |
| 417 | + | "rewrite_row_major_matrices", FeatureCategory::OpenGLWorkarounds, | |
| 418 | + | "Rewrite row major matrices in shaders as column major as a driver bug workaround", | |
| 419 | + | &members, "http://anglebug.com/2273"}; | |
| 420 | + | ||
| 421 | + | // Bugs exist in various OpenGL Intel drivers on Windows that produce incorrect | |
| 422 | + | // values for GL_COMPRESSED_SRGB_S3TC_DXT1_EXT format. Replace it with | |
| 423 | + | // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT as it's the closest option allowed by | |
| 424 | + | // the WebGL extension spec. | |
| 425 | + | Feature avoidDXT1sRGBTextureFormat = { | |
| 426 | + | "avoid_dxt1_srgb_texture_format", FeatureCategory::OpenGLWorkarounds, | |
| 427 | + | "Replaces DXT1 sRGB with DXT1 sRGB Alpha as a driver bug workaround.", &members}; | |
| 428 | + | ||
| 429 | + | // GL_EXT_semaphore_fd doesn't work properly with Mesa 19.3.4 and earlier versions. | |
| 430 | + | Feature disableSemaphoreFd = {"disable_semaphore_fd", FeatureCategory::OpenGLWorkarounds, | |
| 431 | + | "Disable GL_EXT_semaphore_fd extension", &members, | |
| 432 | + | "https://crbug.com/1046462"}; | |
| 433 | + | }; | |
| 434 | + | ||
| 435 | + | inline FeaturesGL::FeaturesGL() = default; | |
| 436 | + | inline FeaturesGL::~FeaturesGL() = default; | |
| 437 | + | ||
| 438 | + | } // namespace angle | |
| 439 | + | ||
| 440 | + | #endif // ANGLE_PLATFORM_FEATURESGL_H_ |
| @@ -0,0 +1,48 @@ | |||
| 1 | + | // | |
| 2 | + | // Copyright 2019 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 | + | // FeaturesMtl.h: Optional features for the Metal renderer. | |
| 7 | + | // | |
| 8 | + | ||
| 9 | + | #ifndef ANGLE_PLATFORM_FEATURESMTL_H_ | |
| 10 | + | #define ANGLE_PLATFORM_FEATURESMTL_H_ | |
| 11 | + | ||
| 12 | + | #include "platform/Feature.h" | |
| 13 | + | ||
| 14 | + | namespace angle | |
| 15 | + | { | |
| 16 | + | ||
| 17 | + | struct FeaturesMtl : FeatureSetBase | |
| 18 | + | { | |
| 19 | + | // BaseVertex/Instanced draw support: | |
| 20 | + | Feature hasBaseVertexInstancedDraw = { | |
| 21 | + | "has_base_vertex_instanced_draw", FeatureCategory::MetalFeatures, | |
| 22 | + | "The renderer supports base vertex instanced draw", &members}; | |
| 23 | + | ||
| 24 | + | // Support depth texture filtering | |
| 25 | + | Feature hasDepthTextureFiltering = { | |
| 26 | + | "has_depth_texture_filtering", FeatureCategory::MetalFeatures, | |
| 27 | + | "The renderer supports depth texture's filtering other than nearest", &members}; | |
| 28 | + | ||
| 29 | + | // Non-uniform compute shader dispatch support, i.e. Group size is not necessarily to be fixed: | |
| 30 | + | Feature hasNonUniformDispatch = { | |
| 31 | + | "has_non_uniform_dispatch", FeatureCategory::MetalFeatures, | |
| 32 | + | "The renderer supports non uniform compute shader dispatch's group size", &members}; | |
| 33 | + | // Texture swizzle support: | |
| 34 | + | Feature hasTextureSwizzle = {"has_texture_swizzle", FeatureCategory::MetalFeatures, | |
| 35 | + | "The renderer supports texture swizzle", &members}; | |
| 36 | + | ||
| 37 | + | // On macos, separate depth & stencil buffers are not supproted. However, on iOS devices, | |
| 38 | + | // they are supproted: | |
| 39 | + | Feature allowSeparatedDepthStencilBuffers = { | |
| 40 | + | "allow_separate_depth_stencil_buffers", FeatureCategory::MetalFeatures, | |
| 41 | + | "Some Apple platforms such as iOS allows separate depth & stencil buffers, " | |
| 42 | + | "whereas others such as macOS don't", | |
| 43 | + | &members}; | |
| 44 | + | }; | |
| 45 | + | ||
| 46 | + | } // namespace angle | |
| 47 | + | ||
| 48 | + | #endif // ANGLE_PLATFORM_FEATURESMTL_H_ |
| @@ -0,0 +1,284 @@ | |||
| 1 | + | // | |
| 2 | + | // Copyright 2018 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 | + | // FeaturesVk.h: Optional features for the Vulkan renderer. | |
| 7 | + | // | |
| 8 | + | ||
| 9 | + | #ifndef ANGLE_PLATFORM_FEATURESVK_H_ | |
| 10 | + | #define ANGLE_PLATFORM_FEATURESVK_H_ | |
| 11 | + | ||
| 12 | + | #include "platform/Feature.h" | |
| 13 | + | ||
| 14 | + | namespace angle | |
| 15 | + | { | |
| 16 | + | ||
| 17 | + | struct FeaturesVk : FeatureSetBase | |
| 18 | + | { | |
| 19 | + | FeaturesVk(); | |
| 20 | + | ~FeaturesVk(); | |
| 21 | + | ||
| 22 | + | // Line segment rasterization must follow OpenGL rules. This means using an algorithm similar | |
| 23 | + | // to Bresenham's. Vulkan uses a different algorithm. This feature enables the use of pixel | |
| 24 | + | // shader patching to implement OpenGL basic line rasterization rules. This feature will | |
| 25 | + | // normally always be enabled. Exposing it as an option enables performance testing. | |
| 26 | + | Feature basicGLLineRasterization = { | |
| 27 | + | "basic_gl_line_rasterization", FeatureCategory::VulkanFeatures, | |
| 28 | + | "Enable the use of pixel shader patching to implement OpenGL basic line " | |
| 29 | + | "rasterization rules", | |
| 30 | + | &members}; | |
| 31 | + | ||
| 32 | + | // If the VK_EXT_line_rasterization extension is available we'll use it to get | |
| 33 | + | // Bresenham line rasterization. | |
| 34 | + | Feature bresenhamLineRasterization = { | |
| 35 | + | "bresenham_line_rasterization", FeatureCategory::VulkanFeatures, | |
| 36 | + | "Enable Bresenham line rasterization via VK_EXT_line_rasterization extension", &members}; | |
| 37 | + | ||
| 38 | + | // If the VK_EXT_provoking_vertex extension is available, we'll use it to set | |
| 39 | + | // the provoking vertex mode | |
| 40 | + | Feature provokingVertex = {"provoking_vertex", FeatureCategory::VulkanFeatures, | |
| 41 | + | "Enable provoking vertex mode via VK_EXT_provoking_vertex extension", | |
| 42 | + | &members}; | |
| 43 | + | ||
| 44 | + | // Flips the viewport to render upside-down. This has the effect to render the same way as | |
| 45 | + | // OpenGL. If this feature gets enabled, we enable the KHR_MAINTENANCE_1 extension to allow | |
| 46 | + | // negative viewports. We inverse rendering to the backbuffer by reversing the height of the | |
| 47 | + | // viewport and increasing Y by the height. So if the viewport was (0,0,width,height), it | |
| 48 | + | // becomes (0, height, width, -height). Unfortunately, when we start doing this, we also need | |
| 49 | + | // to adjust a lot of places since the rendering now happens upside-down. Affected places so | |
| 50 | + | // far: | |
| 51 | + | // -readPixels | |
| 52 | + | // -copyTexImage | |
| 53 | + | // -framebuffer blit | |
| 54 | + | // -generating mipmaps | |
| 55 | + | // -Point sprites tests | |
| 56 | + | // -texStorage | |
| 57 | + | Feature flipViewportY = {"flip_viewport_y", FeatureCategory::VulkanFeatures, | |
| 58 | + | "Flips the viewport to render upside-down", &members}; | |
| 59 | + | ||
| 60 | + | // Add an extra copy region when using vkCmdCopyBuffer as the Windows Intel driver seems | |
| 61 | + | // to have a bug where the last region is ignored. | |
| 62 | + | Feature extraCopyBufferRegion = { | |
| 63 | + | "extra_copy_buffer_region", FeatureCategory::VulkanWorkarounds, | |
| 64 | + | "Some drivers seem to have a bug where the last copy region in vkCmdCopyBuffer is ignored", | |
| 65 | + | &members}; | |
| 66 | + | ||
| 67 | + | // This flag is added for the sole purpose of end2end tests, to test the correctness | |
| 68 | + | // of various algorithms when a fallback format is used, such as using a packed format to | |
| 69 | + | // emulate a depth- or stencil-only format. | |
| 70 | + | Feature forceFallbackFormat = {"force_fallback_format", FeatureCategory::VulkanWorkarounds, | |
| 71 | + | "Force a fallback format for angle_end2end_tests", &members}; | |
| 72 | + | ||
| 73 | + | // On some NVIDIA drivers the point size range reported from the API is inconsistent with the | |
| 74 | + | // actual behavior. Clamp the point size to the value from the API to fix this. | |
| 75 | + | // Tracked in http://anglebug.com/2970. | |
| 76 | + | Feature clampPointSize = { | |
| 77 | + | "clamp_point_size", FeatureCategory::VulkanWorkarounds, | |
| 78 | + | "The point size range reported from the API is inconsistent with the actual behavior", | |
| 79 | + | &members, "http://anglebug.com/2970"}; | |
| 80 | + | ||
| 81 | + | // On some android devices, the memory barrier between the compute shader that converts vertex | |
| 82 | + | // attributes and the vertex shader that reads from it is ineffective. Only known workaround is | |
| 83 | + | // to perform a flush after the conversion. http://anglebug.com/3016 | |
| 84 | + | Feature flushAfterVertexConversion = { | |
| 85 | + | "flush_after_vertex_conversion", FeatureCategory::VulkanWorkarounds, | |
| 86 | + | "The memory barrier between the compute shader that converts vertex attributes and the " | |
| 87 | + | "vertex shader that reads from it is ineffective", | |
| 88 | + | &members, "http://anglebug.com/3016"}; | |
| 89 | + | ||
| 90 | + | // Whether the VkDevice supports the VK_KHR_incremental_present extension, on which the | |
| 91 | + | // EGL_KHR_swap_buffers_with_damage extension can be layered. | |
| 92 | + | Feature supportsIncrementalPresent = { | |
| 93 | + | "supports_incremental_present", FeatureCategory::VulkanFeatures, | |
| 94 | + | "VkDevice supports the VK_KHR_incremental_present extension", &members}; | |
| 95 | + | ||
| 96 | + | // Whether texture copies on cube map targets should be done on GPU. This is a workaround for | |
| 97 | + | // Intel drivers on windows that have an issue with creating single-layer views on cube map | |
| 98 | + | // textures. | |
| 99 | + | Feature forceCPUPathForCubeMapCopy = { | |
| 100 | + | "force_cpu_path_for_cube_map_copy", FeatureCategory::VulkanWorkarounds, | |
| 101 | + | "Some drivers have an issue with creating single-layer views on cube map textures", | |
| 102 | + | &members}; | |
| 103 | + | ||
| 104 | + | // Whether the VkDevice supports the VK_ANDROID_external_memory_android_hardware_buffer | |
| 105 | + | // extension, on which the EGL_ANDROID_image_native_buffer extension can be layered. | |
| 106 | + | Feature supportsAndroidHardwareBuffer = { | |
| 107 | + | "supports_android_hardware_buffer", FeatureCategory::VulkanFeatures, | |
| 108 | + | "VkDevice supports the VK_ANDROID_external_memory_android_hardware_buffer extension", | |
| 109 | + | &members}; | |
| 110 | + | ||
| 111 | + | // Whether the VkDevice supports the VK_KHR_external_memory_fd extension, on which the | |
| 112 | + | // GL_EXT_memory_object_fd extension can be layered. | |
| 113 | + | Feature supportsExternalMemoryFd = { | |
| 114 | + | "supports_external_memory_fd", FeatureCategory::VulkanFeatures, | |
| 115 | + | "VkDevice supports the VK_KHR_external_memory_fd extension", &members}; | |
| 116 | + | ||
| 117 | + | // Whether the VkDevice supports the VK_FUCHSIA_external_memory | |
| 118 | + | // extension, on which the GL_ANGLE_memory_object_fuchsia extension can be layered. | |
| 119 | + | angle::Feature supportsExternalMemoryFuchsia = { | |
| 120 | + | "supports_external_memory_fuchsia", FeatureCategory::VulkanFeatures, | |
| 121 | + | "VkDevice supports the VK_FUCHSIA_external_memory extension", &members}; | |
| 122 | + | ||
| 123 | + | // Whether the VkDevice supports the VK_KHR_external_semaphore_fd extension, on which the | |
| 124 | + | // GL_EXT_semaphore_fd extension can be layered. | |
| 125 | + | Feature supportsExternalSemaphoreFd = { | |
| 126 | + | "supports_external_semaphore_fd", FeatureCategory::VulkanFeatures, | |
| 127 | + | "VkDevice supports the VK_KHR_external_semaphore_fd extension", &members}; | |
| 128 | + | ||
| 129 | + | // Whether the VkDevice supports the VK_FUCHSIA_external_semaphore | |
| 130 | + | // extension, on which the GL_ANGLE_semaphore_fuchsia extension can be layered. | |
| 131 | + | angle::Feature supportsExternalSemaphoreFuchsia = { | |
| 132 | + | "supports_external_semaphore_fuchsia", FeatureCategory::VulkanFeatures, | |
| 133 | + | "VkDevice supports the VK_FUCHSIA_external_semaphore extension", &members}; | |
| 134 | + | ||
| 135 | + | // Whether the VkDevice supports the VK_EXT_shader_stencil_export extension, which is used to | |
| 136 | + | // perform multisampled resolve of stencil buffer. A multi-step workaround is used instead if | |
| 137 | + | // this extension is not available. | |
| 138 | + | Feature supportsShaderStencilExport = { | |
| 139 | + | "supports_shader_stencil_export", FeatureCategory::VulkanFeatures, | |
| 140 | + | "VkDevice supports the VK_EXT_shader_stencil_export extension", &members}; | |
| 141 | + | ||
| 142 | + | // Where VK_EXT_transform_feedback is not support, an emulation path is used. | |
| 143 | + | // http://anglebug.com/3205 | |
| 144 | + | Feature emulateTransformFeedback = { | |
| 145 | + | "emulate_transform_feedback", FeatureCategory::VulkanFeatures, | |
| 146 | + | "Emulate transform feedback as the VK_EXT_transform_feedback is not present.", &members, | |
| 147 | + | "http://anglebug.com/3205"}; | |
| 148 | + | ||
| 149 | + | // Where VK_EXT_transform_feedback is supported, it's preferred over an emulation path. | |
| 150 | + | // http://anglebug.com/3206 | |
| 151 | + | Feature supportsTransformFeedbackExtension = { | |
| 152 | + | "supports_transform_feedback_extension", FeatureCategory::VulkanFeatures, | |
| 153 | + | "Transform feedback uses the VK_EXT_transform_feedback extension.", &members, | |
| 154 | + | "http://anglebug.com/3206"}; | |
| 155 | + | ||
| 156 | + | // Whether the VkDevice supports the VK_EXT_index_type_uint8 extension | |
| 157 | + | // http://anglebug.com/4405 | |
| 158 | + | Feature supportsIndexTypeUint8 = {"supports_index_type_uint8", FeatureCategory::VulkanFeatures, | |
| 159 | + | "VkDevice supports the VK_EXT_index_type_uint8 extension", | |
| 160 | + | &members, "http://anglebug.com/4405"}; | |
| 161 | + | ||
| 162 | + | // VK_PRESENT_MODE_FIFO_KHR causes random timeouts on Linux Intel. http://anglebug.com/3153 | |
| 163 | + | Feature disableFifoPresentMode = { | |
| 164 | + | "disable_fifo_present_mode", FeatureCategory::VulkanWorkarounds, | |
| 165 | + | "VK_PRESENT_MODE_FIFO_KHR causes random timeouts", &members, "http://anglebug.com/3153"}; | |
| 166 | + | ||
| 167 | + | // On Qualcomm, gaps in bound descriptor set indices causes the post-gap sets to misbehave. | |
| 168 | + | // For example, binding only descriptor set 3 results in zero being read from a uniform buffer | |
| 169 | + | // object within that set. This flag results in empty descriptor sets being bound for any | |
| 170 | + | // unused descriptor set to work around this issue. http://anglebug.com/2727 | |
| 171 | + | Feature bindEmptyForUnusedDescriptorSets = { | |
| 172 | + | "bind_empty_for_unused_descriptor_sets", FeatureCategory::VulkanWorkarounds, | |
| 173 | + | "Gaps in bound descriptor set indices causes the post-gap sets to misbehave", &members, | |
| 174 | + | "http://anglebug.com/2727"}; | |
| 175 | + | ||
| 176 | + | // OES_depth_texture is a commonly expected feature on Android. However it | |
| 177 | + | // requires that D16_UNORM support texture filtering | |
| 178 | + | // (e.g. VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) and some devices | |
| 179 | + | // do not. Work-around this by setting saying D16_UNORM supports filtering | |
| 180 | + | // anyway. | |
| 181 | + | Feature forceD16TexFilter = { | |
| 182 | + | "force_D16_texture_filter", FeatureCategory::VulkanWorkarounds, | |
| 183 | + | "VK_FORMAT_D16_UNORM does not support VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, " | |
| 184 | + | "which prevents OES_depth_texture from being supported.", | |
| 185 | + | &members, "http://anglebug.com/3452"}; | |
| 186 | + | ||
| 187 | + | // On some android devices, vkCmdBlitImage with flipped coordinates blits incorrectly. This | |
| 188 | + | // workaround makes sure this path is avoided. http://anglebug.com/3498 | |
| 189 | + | Feature disableFlippingBlitWithCommand = { | |
| 190 | + | "disable_flipping_blit_with_command", FeatureCategory::VulkanWorkarounds, | |
| 191 | + | "vkCmdBlitImage with flipped coordinates blits incorrectly.", &members, | |
| 192 | + | "http://anglebug.com/3498"}; | |
| 193 | + | ||
| 194 | + | // On platform with Intel or AMD GPU, a window resizing would not trigger the vulkan driver to | |
| 195 | + | // return VK_ERROR_OUT_OF_DATE on swapchain present. Work-around by query current window extent | |
| 196 | + | // every frame to detect a window resizing. | |
| 197 | + | // http://anglebug.com/3623, http://anglebug.com/3624, http://anglebug.com/3625 | |
| 198 | + | Feature perFrameWindowSizeQuery = { | |
| 199 | + | "per_frame_window_size_query", FeatureCategory::VulkanWorkarounds, | |
| 200 | + | "Vulkan swapchain is not returning VK_ERROR_OUT_OF_DATE when window resizing", &members, | |
| 201 | + | "http://anglebug.com/3623, http://anglebug.com/3624, http://anglebug.com/3625"}; | |
| 202 | + | ||
| 203 | + | // Seamful cube map emulation misbehaves on the AMD windows driver, so it's disallowed. | |
| 204 | + | Feature disallowSeamfulCubeMapEmulation = { | |
| 205 | + | "disallow_seamful_cube_map_emulation", FeatureCategory::VulkanWorkarounds, | |
| 206 | + | "Seamful cube map emulation misbehaves on some drivers, so it's disallowed", &members, | |
| 207 | + | "http://anglebug.com/3243"}; | |
| 208 | + | ||
| 209 | + | // Qualcomm and SwiftShader shader compiler doesn't support sampler arrays as parameters, so | |
| 210 | + | // revert to old RewriteStructSamplers behavior, which produces fewer. | |
| 211 | + | Feature forceOldRewriteStructSamplers = { | |
| 212 | + | "force_old_rewrite_struct_samplers", FeatureCategory::VulkanWorkarounds, | |
| 213 | + | "Some shader compilers don't support sampler arrays as parameters, so revert to old " | |
| 214 | + | "RewriteStructSamplers behavior, which produces fewer.", | |
| 215 | + | &members, "http://anglebug.com/2703"}; | |
| 216 | + | ||
| 217 | + | // Vulkan considers vertex attribute accesses to count up to the last multiple of the stride. | |
| 218 | + | // This additional access supports AMD's robust buffer access implementation. | |
| 219 | + | // AMDVLK in particular will return incorrect values when the vertex access extends into the | |
| 220 | + | // range that would be the stride padding and the buffer is too small. | |
| 221 | + | // This workaround limits GL_MAX_VERTEX_ATTRIB_STRIDE to a reasonable value and pads out | |
| 222 | + | // every buffer allocation size to be large enough to support a maximum vertex stride. | |
| 223 | + | // http://anglebug.com/4428 | |
| 224 | + | Feature padBuffersToMaxVertexAttribStride = { | |
| 225 | + | "pad_buffers_to_max_vertex_attrib_stride", FeatureCategory::VulkanWorkarounds, | |
| 226 | + | "Vulkan considers vertex attribute accesses to count up to the last multiple of the " | |
| 227 | + | "stride. This additional access supports AMD's robust buffer access implementation. " | |
| 228 | + | "AMDVLK in particular will return incorrect values when the vertex access extends into " | |
| 229 | + | "the range that would be the stride padding and the buffer is too small. " | |
| 230 | + | "This workaround limits GL_MAX_VERTEX_ATTRIB_STRIDE to a maximum value and " | |
| 231 | + | "pads up every buffer allocation size to be a multiple of the maximum stride.", | |
| 232 | + | &members, "http://anglebug.com/4428"}; | |
| 233 | + | ||
| 234 | + | // Whether the VkDevice supports the VK_EXT_swapchain_colorspace extension | |
| 235 | + | // http://anglebug.com/2514 | |
| 236 | + | Feature supportsSwapchainColorspace = { | |
| 237 | + | "supports_swapchain_colorspace", FeatureCategory::VulkanFeatures, | |
| 238 | + | "VkDevice supports the VK_EXT_swapchain_colorspace extension", &members, | |
| 239 | + | "http://anglebug.com/2514"}; | |
| 240 | + | ||
| 241 | + | // Whether the VkDevice supports the VK_EXT_external_memory_host extension, on which the | |
| 242 | + | // ANGLE_iosurface_client_buffer extension can be layered. | |
| 243 | + | Feature supportsExternalMemoryHost = { | |
| 244 | + | "supports_external_memory_host", FeatureCategory::VulkanFeatures, | |
| 245 | + | "VkDevice supports the VK_EXT_external_memory_host extension", &members}; | |
| 246 | + | ||
| 247 | + | // Whether to fill new buffers and textures with nonzero data to sanitize robust resource | |
| 248 | + | // initialization and flush out assumptions about zero init. | |
| 249 | + | Feature allocateNonZeroMemory = { | |
| 250 | + | "allocate_non_zero_memory", FeatureCategory::VulkanFeatures, | |
| 251 | + | "Fill new allocations with non-zero values to flush out errors.", &members, | |
| 252 | + | "http://anglebug.com/4384"}; | |
| 253 | + | ||
| 254 | + | // Android needs to pre-rotate surfaces that are not oriented per the native device's | |
| 255 | + | // orientation (e.g. a landscape application on a Pixel phone). This feature works for | |
| 256 | + | // full-screen applications. http://anglebug.com/3502 | |
| 257 | + | Feature enablePreRotateSurfaces = {"enable_pre_rotation_surfaces", | |
| 258 | + | FeatureCategory::VulkanFeatures, | |
| 259 | + | "Enable Android pre-rotation for landscape applications", | |
| 260 | + | &members, "http://anglebug.com/3502"}; | |
| 261 | + | ||
| 262 | + | // Cache FramebufferVk objects. Currently hitting a bug on Apple: http://anglebug.com/4442 | |
| 263 | + | Feature enableFramebufferVkCache = { | |
| 264 | + | "enable_framebuffer_vk_cache", FeatureCategory::VulkanFeatures, | |
| 265 | + | "Enable FramebufferVk objects to be cached", &members, "http://anglebug.com/4442"}; | |
| 266 | + | ||
| 267 | + | // Enable precision qualifiers for shaders generated by Vulkan backend http://anglebug.com/3078 | |
| 268 | + | Feature enablePrecisionQualifiers = { | |
| 269 | + | "enable_precision_qualifiers", FeatureCategory::VulkanFeatures, | |
| 270 | + | "Enable precision qualifiers in shaders", &members, "http://anglebug.com/3078"}; | |
| 271 | + | ||
| 272 | + | // Support Depth/Stencil rendering feedback loops by masking out the depth/stencil buffer. | |
| 273 | + | // Manhattan uses this feature in a few draw calls. | |
| 274 | + | Feature supportDepthStencilRenderingFeedbackLoops = { | |
| 275 | + | "support_depth_stencil_rendering_feedback_loops", FeatureCategory::VulkanFeatures, | |
| 276 | + | "Suport depth/stencil rendering feedback loops", &members, "http://anglebug.com/4490"}; | |
| 277 | + | }; | |
| 278 | + | ||
| 279 | + | inline FeaturesVk::FeaturesVk() = default; | |
| 280 | + | inline FeaturesVk::~FeaturesVk() = default; | |
| 281 | + | ||
| 282 | + | } // namespace angle | |
| 283 | + | ||
| 284 | + | #endif // ANGLE_PLATFORM_FEATURESVK_H_ |
| @@ -0,0 +1,59 @@ | |||
| 1 | + | // | |
| 2 | + | // Copyright 2016 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 | + | ||
| 7 | + | // FrontendFeatures.h: Features/workarounds for driver bugs and other behaviors seen | |
| 8 | + | // on all platforms. | |
| 9 | + | ||
| 10 | + | #ifndef ANGLE_PLATFORM_FRONTENDFEATURES_H_ | |
| 11 | + | #define ANGLE_PLATFORM_FRONTENDFEATURES_H_ | |
| 12 | + | ||
| 13 | + | #include "platform/Feature.h" | |
| 14 | + | ||
| 15 | + | namespace angle | |
| 16 | + | { | |
| 17 | + | ||
| 18 | + | struct FrontendFeatures : angle::FeatureSetBase | |
| 19 | + | { | |
| 20 | + | FrontendFeatures(); | |
| 21 | + | ~FrontendFeatures(); | |
| 22 | + | ||
| 23 | + | // Force the context to be lost (via KHR_robustness) if a GL_OUT_OF_MEMORY error occurs. The | |
| 24 | + | // driver may be in an inconsistent state if this happens, and some users of ANGLE rely on this | |
| 25 | + | // notification to prevent further execution. | |
| 26 | + | angle::Feature loseContextOnOutOfMemory = { | |
| 27 | + | "lose_context_on_out_of_memory", angle::FeatureCategory::FrontendWorkarounds, | |
| 28 | + | "Some users rely on a lost context notification if a GL_OUT_OF_MEMORY " | |
| 29 | + | "error occurs", | |
| 30 | + | &members}; | |
| 31 | + | ||
| 32 | + | // Program binaries don't contain transform feedback varyings on Qualcomm GPUs. | |
| 33 | + | // Work around this by disabling the program cache for programs with transform feedback. | |
| 34 | + | angle::Feature disableProgramCachingForTransformFeedback = { | |
| 35 | + | "disable_program_caching_for_transform_feedback", | |
| 36 | + | angle::FeatureCategory::FrontendWorkarounds, | |
| 37 | + | "On some GPUs, program binaries don't contain transform feedback varyings", &members}; | |
| 38 | + | ||
| 39 | + | // On Windows Intel OpenGL drivers TexImage sometimes seems to interact with the Framebuffer. | |
| 40 | + | // Flaky crashes can occur unless we sync the Framebuffer bindings. The workaround is to add | |
| 41 | + | // Framebuffer binding dirty bits to TexImage updates. See http://anglebug.com/2906 | |
| 42 | + | angle::Feature syncFramebufferBindingsOnTexImage = { | |
| 43 | + | "sync_framebuffer_bindings_on_tex_image", angle::FeatureCategory::FrontendWorkarounds, | |
| 44 | + | "On some drivers TexImage sometimes seems to interact " | |
| 45 | + | "with the Framebuffer", | |
| 46 | + | &members}; | |
| 47 | + | ||
| 48 | + | angle::Feature scalarizeVecAndMatConstructorArgs = { | |
| 49 | + | "scalarize_vec_and_mat_constructor_args", angle::FeatureCategory::FrontendWorkarounds, | |
| 50 | + | "Always rewrite vec/mat constructors to be consistent", &members, | |
| 51 | + | "http://crbug.com/398694"}; | |
| 52 | + | }; | |
| 53 | + | ||
| 54 | + | inline FrontendFeatures::FrontendFeatures() = default; | |
| 55 | + | inline FrontendFeatures::~FrontendFeatures() = default; | |
| 56 | + | ||
| 57 | + | } // namespace angle | |
| 58 | + | ||
| 59 | + | #endif // ANGLE_PLATFORM_FRONTENDFEATURES_H_ |
| @@ -0,0 +1,333 @@ | |||
| 1 | + | // | |
| 2 | + | // Copyright 2015 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 | + | // Platform.h: The public interface ANGLE exposes to the API layer, for | |
| 7 | + | // doing platform-specific tasks like gathering data, or for tracing. | |
| 8 | + | ||
| 9 | + | #ifndef ANGLE_PLATFORM_H | |
| 10 | + | #define ANGLE_PLATFORM_H | |
| 11 | + | ||
| 12 | + | #include <stdint.h> | |
| 13 | + | #include <stdlib.h> | |
| 14 | + | #include <array> | |
| 15 | + | ||
| 16 | + | #define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x3482 | |
| 17 | + | ||
| 18 | + | #if !defined(ANGLE_PLATFORM_EXPORT) | |
| 19 | + | # if defined(_WIN32) | |
| 20 | + | # if !defined(LIBANGLE_IMPLEMENTATION) | |
| 21 | + | # define ANGLE_PLATFORM_EXPORT __declspec(dllimport) | |
| 22 | + | # else | |
| 23 | + | # define ANGLE_PLATFORM_EXPORT __declspec(dllexport) | |
| 24 | + | # endif | |
| 25 | + | # elif defined(__GNUC__) || defined(__clang__) | |
| 26 | + | # define ANGLE_PLATFORM_EXPORT __attribute__((visibility("default"))) | |
| 27 | + | # endif | |
| 28 | + | #endif | |
| 29 | + | #if !defined(ANGLE_PLATFORM_EXPORT) | |
| 30 | + | # define ANGLE_PLATFORM_EXPORT | |
| 31 | + | #endif | |
| 32 | + | ||
| 33 | + | #if defined(_WIN32) | |
| 34 | + | # define ANGLE_APIENTRY __stdcall | |
| 35 | + | #else | |
| 36 | + | # define ANGLE_APIENTRY | |
| 37 | + | #endif | |
| 38 | + | ||
| 39 | + | namespace angle | |
| 40 | + | { | |
| 41 | + | struct FeaturesD3D; | |
| 42 | + | struct FeaturesVk; | |
| 43 | + | struct FeaturesMtl; | |
| 44 | + | using TraceEventHandle = uint64_t; | |
| 45 | + | using EGLDisplayType = void *; | |
| 46 | + | struct PlatformMethods; | |
| 47 | + | ||
| 48 | + | // Use a C-like API to not trigger undefined calling behaviour. | |
| 49 | + | // Avoid using decltype here to work around sanitizer limitations. | |
| 50 | + | // TODO(jmadill): Use decltype here if/when UBSAN is fixed. | |
| 51 | + | ||
| 52 | + | // System -------------------------------------------------------------- | |
| 53 | + | ||
| 54 | + | // Wall clock time in seconds since the epoch. | |
| 55 | + | // TODO(jmadill): investigate using an ANGLE internal time library | |
| 56 | + | using CurrentTimeFunc = double (*)(PlatformMethods *platform); | |
| 57 | + | inline double DefaultCurrentTime(PlatformMethods *platform) | |
| 58 | + | { | |
| 59 | + | return 0.0; | |
| 60 | + | } | |
| 61 | + | ||
| 62 | + | // Monotonically increasing time in seconds from an arbitrary fixed point in the past. | |
| 63 | + | // This function is expected to return at least millisecond-precision values. For this reason, | |
| 64 | + | // it is recommended that the fixed point be no further in the past than the epoch. | |
| 65 | + | using MonotonicallyIncreasingTimeFunc = double (*)(PlatformMethods *platform); | |
| 66 | + | inline double DefaultMonotonicallyIncreasingTime(PlatformMethods *platform) | |
| 67 | + | { | |
| 68 | + | return 0.0; | |
| 69 | + | } | |
| 70 | + | ||
| 71 | + | // Logging ------------------------------------------------------------ | |
| 72 | + | ||
| 73 | + | // Log an error message within the platform implementation. | |
| 74 | + | using LogErrorFunc = void (*)(PlatformMethods *platform, const char *errorMessage); | |
| 75 | + | inline void DefaultLogError(PlatformMethods *platform, const char *errorMessage) {} | |
| 76 | + | ||
| 77 | + | // Log a warning message within the platform implementation. | |
| 78 | + | using LogWarningFunc = void (*)(PlatformMethods *platform, const char *warningMessage); | |
| 79 | + | inline void DefaultLogWarning(PlatformMethods *platform, const char *warningMessage) {} | |
| 80 | + | ||
| 81 | + | // Log an info message within the platform implementation. | |
| 82 | + | using LogInfoFunc = void (*)(PlatformMethods *platform, const char *infoMessage); | |
| 83 | + | inline void DefaultLogInfo(PlatformMethods *platform, const char *infoMessage) {} | |
| 84 | + | ||
| 85 | + | // Tracing -------- | |
| 86 | + | ||
| 87 | + | // Get a pointer to the enabled state of the given trace category. The | |
| 88 | + | // embedder can dynamically change the enabled state as trace event | |
| 89 | + | // recording is started and stopped by the application. Only long-lived | |
| 90 | + | // literal strings should be given as the category name. The implementation | |
| 91 | + | // expects the returned pointer to be held permanently in a local static. If | |
| 92 | + | // the unsigned char is non-zero, tracing is enabled. If tracing is enabled, | |
| 93 | + | // addTraceEvent is expected to be called by the trace event macros. | |
| 94 | + | using GetTraceCategoryEnabledFlagFunc = const unsigned char *(*)(PlatformMethods *platform, | |
| 95 | + | const char *categoryName); | |
| 96 | + | inline const unsigned char *DefaultGetTraceCategoryEnabledFlag(PlatformMethods *platform, | |
| 97 | + | const char *categoryName) | |
| 98 | + | { | |
| 99 | + | return nullptr; | |
| 100 | + | } | |
| 101 | + | ||
| 102 | + | // | |
| 103 | + | // Add a trace event to the platform tracing system. Depending on the actual | |
| 104 | + | // enabled state, this event may be recorded or dropped. | |
| 105 | + | // - phase specifies the type of event: | |
| 106 | + | // - BEGIN ('B'): Marks the beginning of a scoped event. | |
| 107 | + | // - END ('E'): Marks the end of a scoped event. | |
| 108 | + | // - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't | |
| 109 | + | // need a matching END event. Instead, at the end of the scope, | |
| 110 | + | // updateTraceEventDuration() must be called with the TraceEventHandle | |
| 111 | + | // returned from addTraceEvent(). | |
| 112 | + | // - INSTANT ('I'): Standalone, instantaneous event. | |
| 113 | + | // - START ('S'): Marks the beginning of an asynchronous event (the end | |
| 114 | + | // event can occur in a different scope or thread). The id parameter is | |
| 115 | + | // used to match START/FINISH pairs. | |
| 116 | + | // - FINISH ('F'): Marks the end of an asynchronous event. | |
| 117 | + | // - COUNTER ('C'): Used to trace integer quantities that change over | |
| 118 | + | // time. The argument values are expected to be of type int. | |
| 119 | + | // - METADATA ('M'): Reserved for internal use. | |
| 120 | + | // - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag. | |
| 121 | + | // - name is the name of the event. Also used to match BEGIN/END and | |
| 122 | + | // START/FINISH pairs. | |
| 123 | + | // - id optionally allows events of the same name to be distinguished from | |
| 124 | + | // each other. For example, to trace the construction and destruction of | |
| 125 | + | // objects, specify the pointer as the id parameter. | |
| 126 | + | // - timestamp should be a time value returned from monotonicallyIncreasingTime. | |
| 127 | + | // - numArgs specifies the number of elements in argNames, argTypes, and | |
| 128 | + | // argValues. | |
| 129 | + | // - argNames is the array of argument names. Use long-lived literal strings | |
| 130 | + | // or specify the COPY flag. | |
| 131 | + | // - argTypes is the array of argument types: | |
| 132 | + | // - BOOL (1): bool | |
| 133 | + | // - UINT (2): unsigned long long | |
| 134 | + | // - INT (3): long long | |
| 135 | + | // - DOUBLE (4): double | |
| 136 | + | // - POINTER (5): void* | |
| 137 | + | // - STRING (6): char* (long-lived null-terminated char* string) | |
| 138 | + | // - COPY_STRING (7): char* (temporary null-terminated char* string) | |
| 139 | + | // - CONVERTABLE (8): WebConvertableToTraceFormat | |
| 140 | + | // - argValues is the array of argument values. Each value is the unsigned | |
| 141 | + | // long long member of a union of all supported types. | |
| 142 | + | // - flags can be 0 or one or more of the following, ORed together: | |
| 143 | + | // - COPY (0x1): treat all strings (name, argNames and argValues of type | |
| 144 | + | // string) as temporary so that they will be copied by addTraceEvent. | |
| 145 | + | // - HAS_ID (0x2): use the id argument to uniquely identify the event for | |
| 146 | + | // matching with other events of the same name. | |
| 147 | + | // - MANGLE_ID (0x4): specify this flag if the id parameter is the value | |
| 148 | + | // of a pointer. | |
| 149 | + | using AddTraceEventFunc = angle::TraceEventHandle (*)(PlatformMethods *platform, | |
| 150 | + | char phase, | |
| 151 | + | const unsigned char *categoryEnabledFlag, | |
| 152 | + | const char *name, | |
| 153 | + | unsigned long long id, | |
| 154 | + | double timestamp, | |
| 155 | + | int numArgs, | |
| 156 | + | const char **argNames, | |
| 157 | + | const unsigned char *argTypes, | |
| 158 | + | const unsigned long long *argValues, | |
| 159 | + | unsigned char flags); | |
| 160 | + | inline angle::TraceEventHandle DefaultAddTraceEvent(PlatformMethods *platform, | |
| 161 | + | char phase, | |
| 162 | + | const unsigned char *categoryEnabledFlag, | |
| 163 | + | const char *name, | |
| 164 | + | unsigned long long id, | |
| 165 | + | double timestamp, | |
| 166 | + | int numArgs, | |
| 167 | + | const char **argNames, | |
| 168 | + | const unsigned char *argTypes, | |
| 169 | + | const unsigned long long *argValues, | |
| 170 | + | unsigned char flags) | |
| 171 | + | { | |
| 172 | + | return 0; | |
| 173 | + | } | |
| 174 | + | ||
| 175 | + | // Set the duration field of a COMPLETE trace event. | |
| 176 | + | using UpdateTraceEventDurationFunc = void (*)(PlatformMethods *platform, | |
| 177 | + | const unsigned char *categoryEnabledFlag, | |
| 178 | + | const char *name, | |
| 179 | + | angle::TraceEventHandle eventHandle); | |
| 180 | + | inline void DefaultUpdateTraceEventDuration(PlatformMethods *platform, | |
| 181 | + | const unsigned char *categoryEnabledFlag, | |
| 182 | + | const char *name, | |
| 183 | + | angle::TraceEventHandle eventHandle) | |
| 184 | + | {} | |
| 185 | + | ||
| 186 | + | // Callbacks for reporting histogram data. | |
| 187 | + | // CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50 | |
| 188 | + | // would do. | |
| 189 | + | using HistogramCustomCountsFunc = void (*)(PlatformMethods *platform, | |
| 190 | + | const char *name, | |
| 191 | + | int sample, | |
| 192 | + | int min, | |
| 193 | + | int max, | |
| 194 | + | int bucketCount); | |
| 195 | + | inline void DefaultHistogramCustomCounts(PlatformMethods *platform, | |
| 196 | + | const char *name, | |
| 197 | + | int sample, | |
| 198 | + | int min, | |
| 199 | + | int max, | |
| 200 | + | int bucketCount) | |
| 201 | + | {} | |
| 202 | + | // Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample | |
| 203 | + | // value. | |
| 204 | + | using HistogramEnumerationFunc = void (*)(PlatformMethods *platform, | |
| 205 | + | const char *name, | |
| 206 | + | int sample, | |
| 207 | + | int boundaryValue); | |
| 208 | + | inline void DefaultHistogramEnumeration(PlatformMethods *platform, | |
| 209 | + | const char *name, | |
| 210 | + | int sample, | |
| 211 | + | int boundaryValue) | |
| 212 | + | {} | |
| 213 | + | // Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets. | |
| 214 | + | using HistogramSparseFunc = void (*)(PlatformMethods *platform, const char *name, int sample); | |
| 215 | + | inline void DefaultHistogramSparse(PlatformMethods *platform, const char *name, int sample) {} | |
| 216 | + | // Boolean histograms track two-state variables. | |
| 217 | + | using HistogramBooleanFunc = void (*)(PlatformMethods *platform, const char *name, bool sample); | |
| 218 | + | inline void DefaultHistogramBoolean(PlatformMethods *platform, const char *name, bool sample) {} | |
| 219 | + | ||
| 220 | + | // Allows us to programatically override ANGLE's default workarounds for testing purposes. | |
| 221 | + | using OverrideWorkaroundsD3DFunc = void (*)(PlatformMethods *platform, | |
| 222 | + | angle::FeaturesD3D *featuresD3D); | |
| 223 | + | inline void DefaultOverrideWorkaroundsD3D(PlatformMethods *platform, | |
| 224 | + | angle::FeaturesD3D *featuresD3D) | |
| 225 | + | {} | |
| 226 | + | ||
| 227 | + | using OverrideFeaturesVkFunc = void (*)(PlatformMethods *platform, | |
| 228 | + | angle::FeaturesVk *featuresVulkan); | |
| 229 | + | inline void DefaultOverrideFeaturesVk(PlatformMethods *platform, angle::FeaturesVk *featuresVulkan) | |
| 230 | + | {} | |
| 231 | + | ||
| 232 | + | using OverrideFeaturesMtlFunc = void (*)(PlatformMethods *platform, | |
| 233 | + | angle::FeaturesMtl *featuresMetal); | |
| 234 | + | inline void DefaultOverrideFeaturesMtl(PlatformMethods *platform, angle::FeaturesMtl *featuresMetal) | |
| 235 | + | {} | |
| 236 | + | ||
| 237 | + | // Callback on a successful program link with the program binary. Can be used to store | |
| 238 | + | // shaders to disk. Keys are a 160-bit SHA-1 hash. | |
| 239 | + | using ProgramKeyType = std::array<uint8_t, 20>; | |
| 240 | + | using CacheProgramFunc = void (*)(PlatformMethods *platform, | |
| 241 | + | const ProgramKeyType &key, | |
| 242 | + | size_t programSize, | |
| 243 | + | const uint8_t *programBytes); | |
| 244 | + | inline void DefaultCacheProgram(PlatformMethods *platform, | |
| 245 | + | const ProgramKeyType &key, | |
| 246 | + | size_t programSize, | |
| 247 | + | const uint8_t *programBytes) | |
| 248 | + | {} | |
| 249 | + | ||
| 250 | + | // Platform methods are enumerated here once. | |
| 251 | + | #define ANGLE_PLATFORM_OP(OP) \ | |
| 252 | + | OP(currentTime, CurrentTime) \ | |
| 253 | + | OP(monotonicallyIncreasingTime, MonotonicallyIncreasingTime) \ | |
| 254 | + | OP(logError, LogError) \ | |
| 255 | + | OP(logWarning, LogWarning) \ | |
| 256 | + | OP(logInfo, LogInfo) \ | |
| 257 | + | OP(getTraceCategoryEnabledFlag, GetTraceCategoryEnabledFlag) \ | |
| 258 | + | OP(addTraceEvent, AddTraceEvent) \ | |
| 259 | + | OP(updateTraceEventDuration, UpdateTraceEventDuration) \ | |
| 260 | + | OP(histogramCustomCounts, HistogramCustomCounts) \ | |
| 261 | + | OP(histogramEnumeration, HistogramEnumeration) \ | |
| 262 | + | OP(histogramSparse, HistogramSparse) \ | |
| 263 | + | OP(histogramBoolean, HistogramBoolean) \ | |
| 264 | + | OP(overrideWorkaroundsD3D, OverrideWorkaroundsD3D) \ | |
| 265 | + | OP(overrideFeaturesVk, OverrideFeaturesVk) \ | |
| 266 | + | OP(cacheProgram, CacheProgram) \ | |
| 267 | + | OP(overrideFeaturesMtl, OverrideFeaturesMtl) | |
| 268 | + | ||
| 269 | + | #define ANGLE_PLATFORM_METHOD_DEF(Name, CapsName) CapsName##Func Name = Default##CapsName; | |
| 270 | + | ||
| 271 | + | struct ANGLE_PLATFORM_EXPORT PlatformMethods | |
| 272 | + | { | |
| 273 | + | inline PlatformMethods(); | |
| 274 | + | ||
| 275 | + | // User data pointer for any implementation specific members. Put it at the start of the | |
| 276 | + | // platform structure so it doesn't become overwritten if one version of the platform | |
| 277 | + | // adds or removes new members. | |
| 278 | + | void *context = 0; | |
| 279 | + | ||
| 280 | + | ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF) | |
| 281 | + | }; | |
| 282 | + | ||
| 283 | + | inline PlatformMethods::PlatformMethods() = default; | |
| 284 | + | ||
| 285 | + | #undef ANGLE_PLATFORM_METHOD_DEF | |
| 286 | + | ||
| 287 | + | // Subtract one to account for the context pointer. | |
| 288 | + | constexpr unsigned int g_NumPlatformMethods = (sizeof(PlatformMethods) / sizeof(uintptr_t)) - 1; | |
| 289 | + | ||
| 290 | + | #define ANGLE_PLATFORM_METHOD_STRING(Name) #Name | |
| 291 | + | #define ANGLE_PLATFORM_METHOD_STRING2(Name, CapsName) ANGLE_PLATFORM_METHOD_STRING(Name), | |
| 292 | + | ||
| 293 | + | constexpr const char *const g_PlatformMethodNames[g_NumPlatformMethods] = { | |
| 294 | + | ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_STRING2)}; | |
| 295 | + | ||
| 296 | + | #undef ANGLE_PLATFORM_METHOD_STRING2 | |
| 297 | + | #undef ANGLE_PLATFORM_METHOD_STRING | |
| 298 | + | ||
| 299 | + | } // namespace angle | |
| 300 | + | ||
| 301 | + | extern "C" { | |
| 302 | + | ||
| 303 | + | // Gets the platform methods on the passed-in EGL display. If the method name signature does not | |
| 304 | + | // match the compiled signature for this ANGLE, false is returned. On success true is returned. | |
| 305 | + | // The application should set any platform methods it cares about on the returned pointer. | |
| 306 | + | // If display is not valid, behaviour is undefined. | |
| 307 | + | ||
| 308 | + | ANGLE_PLATFORM_EXPORT bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display, | |
| 309 | + | const char *const methodNames[], | |
| 310 | + | unsigned int methodNameCount, | |
| 311 | + | void *context, | |
| 312 | + | void *platformMethodsOut); | |
| 313 | + | ||
| 314 | + | // Sets the platform methods back to their defaults. | |
| 315 | + | // If display is not valid, behaviour is undefined. | |
| 316 | + | ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display); | |
| 317 | + | ||
| 318 | + | } // extern "C" | |
| 319 | + | ||
| 320 | + | namespace angle | |
| 321 | + | { | |
| 322 | + | typedef bool(ANGLE_APIENTRY *GetDisplayPlatformFunc)(angle::EGLDisplayType, | |
| 323 | + | const char *const *, | |
| 324 | + | unsigned int, | |
| 325 | + | void *, | |
| 326 | + | void *); | |
| 327 | + | typedef void(ANGLE_APIENTRY *ResetDisplayPlatformFunc)(angle::EGLDisplayType); | |
| 328 | + | } // namespace angle | |
| 329 | + | ||
| 330 | + | // This function is not exported | |
| 331 | + | angle::PlatformMethods *ANGLEPlatformCurrent(); | |
| 332 | + | ||
| 333 | + | #endif // ANGLE_PLATFORM_H |
| @@ -0,0 +1,145 @@ | |||
| 1 | + | // | |
| 2 | + | // Copyright 2019 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 | + | // vulkan_fuchsia_ext: | |
| 7 | + | // Defines Fuchsia-specific Vulkan extensions that haven't been | |
| 8 | + | // upstreamed to the official Vulkan headers. | |
| 9 | + | // | |
| 10 | + | ||
| 11 | + | #ifndef COMMON_VULKAN_FUCHSIA_EXT_H_ | |
| 12 | + | #define COMMON_VULKAN_FUCHSIA_EXT_H_ | |
| 13 | + | ||
| 14 | + | #if !defined(VK_NO_PROTOTYPES) | |
| 15 | + | # define VK_NO_PROTOTYPES | |
| 16 | + | #endif | |
| 17 | + | ||
| 18 | + | #include <vulkan/vulkan.h> | |
| 19 | + | ||
| 20 | + | #if defined(ANGLE_PLATFORM_FUCHSIA) | |
| 21 | + | # include <zircon/types.h> | |
| 22 | + | #else | |
| 23 | + | typedef uint32_t zx_handle_t; | |
| 24 | + | # define ZX_HANDLE_INVALID ((zx_handle_t)0) | |
| 25 | + | #endif | |
| 26 | + | ||
| 27 | + | #ifdef __cplusplus | |
| 28 | + | extern "C" { | |
| 29 | + | #endif | |
| 30 | + | ||
| 31 | + | const VkStructureType VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = | |
| 32 | + | static_cast<VkStructureType>(1001005000); | |
| 33 | + | const VkStructureType VK_STRUCTURE_TYPE_TEMP_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = | |
| 34 | + | static_cast<VkStructureType>(1001005001); | |
| 35 | + | const VkStructureType VK_STRUCTURE_TYPE_TEMP_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = | |
| 36 | + | static_cast<VkStructureType>(1001005002); | |
| 37 | + | const VkStructureType VK_STRUCTURE_TYPE_TEMP_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = | |
| 38 | + | static_cast<VkStructureType>(1001006000); | |
| 39 | + | const VkStructureType VK_STRUCTURE_TYPE_TEMP_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = | |
| 40 | + | static_cast<VkStructureType>(1001006001); | |
| 41 | + | ||
| 42 | + | const VkExternalMemoryHandleTypeFlagBits | |
| 43 | + | VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA = | |
| 44 | + | static_cast<VkExternalMemoryHandleTypeFlagBits>(0x00100000); | |
| 45 | + | ||
| 46 | + | const VkExternalSemaphoreHandleTypeFlagBits | |
| 47 | + | VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA = | |
| 48 | + | static_cast<VkExternalSemaphoreHandleTypeFlagBits>(0x00100000); | |
| 49 | + | ||
| 50 | + | #define VK_FUCHSIA_external_memory 1 | |
| 51 | + | #define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1 | |
| 52 | + | #define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory" | |
| 53 | + | ||
| 54 | + | typedef struct VkImportMemoryZirconHandleInfoFUCHSIA | |
| 55 | + | { | |
| 56 | + | VkStructureType sType; | |
| 57 | + | const void *pNext; | |
| 58 | + | VkExternalMemoryHandleTypeFlagBits handleType; | |
| 59 | + | zx_handle_t handle; | |
| 60 | + | } VkImportMemoryZirconHandleInfoFUCHSIA; | |
| 61 | + | ||
| 62 | + | typedef struct VkMemoryZirconHandlePropertiesFUCHSIA | |
| 63 | + | { | |
| 64 | + | VkStructureType sType; | |
| 65 | + | void *pNext; | |
| 66 | + | zx_handle_t memoryTypeBits; | |
| 67 | + | } VkMemoryZirconHandlePropertiesFUCHSIA; | |
| 68 | + | ||
| 69 | + | typedef struct VkMemoryGetZirconHandleInfoFUCHSIA | |
| 70 | + | { | |
| 71 | + | VkStructureType sType; | |
| 72 | + | const void *pNext; | |
| 73 | + | VkDeviceMemory memory; | |
| 74 | + | VkExternalMemoryHandleTypeFlagBits handleType; | |
| 75 | + | } VkMemoryGetZirconHandleInfoFUCHSIA; | |
| 76 | + | ||
| 77 | + | typedef VkResult(VKAPI_PTR *PFN_vkGetMemoryZirconHandleFUCHSIA)( | |
| 78 | + | VkDevice device, | |
| 79 | + | const VkMemoryGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo, | |
| 80 | + | zx_handle_t *pZirconHandle); | |
| 81 | + | typedef VkResult(VKAPI_PTR *PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)( | |
| 82 | + | VkDevice device, | |
| 83 | + | VkExternalMemoryHandleTypeFlagBits handleType, | |
| 84 | + | zx_handle_t ZirconHandle, | |
| 85 | + | VkMemoryZirconHandlePropertiesFUCHSIA *pMemoryZirconHandleProperties); | |
| 86 | + | ||
| 87 | + | #ifndef VK_NO_PROTOTYPES | |
| 88 | + | VKAPI_ATTR VkResult VKAPI_CALL | |
| 89 | + | vkGetMemoryZirconHandleFUCHSIA(VkDevice device, | |
| 90 | + | const VkMemoryGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo, | |
| 91 | + | zx_handle_t *pZirconHandle); | |
| 92 | + | ||
| 93 | + | VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA( | |
| 94 | + | VkDevice device, | |
| 95 | + | VkExternalMemoryHandleTypeFlagBits handleType, | |
| 96 | + | zx_handle_t ZirconHandle, | |
| 97 | + | VkMemoryZirconHandlePropertiesFUCHSIA *pMemoryZirconHandleProperties); | |
| 98 | + | #endif | |
| 99 | + | ||
| 100 | + | #define VK_FUCHSIA_external_semaphore 1 | |
| 101 | + | #define VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION 1 | |
| 102 | + | #define VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_FUCHSIA_external_semaphore" | |
| 103 | + | ||
| 104 | + | typedef struct VkImportSemaphoreZirconHandleInfoFUCHSIA | |
| 105 | + | { | |
| 106 | + | VkStructureType sType; | |
| 107 | + | const void *pNext; | |
| 108 | + | VkSemaphore semaphore; | |
| 109 | + | VkSemaphoreImportFlags flags; | |
| 110 | + | VkExternalSemaphoreHandleTypeFlagBits handleType; | |
| 111 | + | zx_handle_t handle; | |
| 112 | + | } VkImportSemaphoreZirconHandleInfoFUCHSIA; | |
| 113 | + | ||
| 114 | + | typedef struct VkSemaphoreGetZirconHandleInfoFUCHSIA | |
| 115 | + | { | |
| 116 | + | VkStructureType sType; | |
| 117 | + | const void *pNext; | |
| 118 | + | VkSemaphore semaphore; | |
| 119 | + | VkExternalSemaphoreHandleTypeFlagBits handleType; | |
| 120 | + | } VkSemaphoreGetZirconHandleInfoFUCHSIA; | |
| 121 | + | ||
| 122 | + | typedef VkResult(VKAPI_PTR *PFN_vkImportSemaphoreZirconHandleFUCHSIA)( | |
| 123 | + | VkDevice device, | |
| 124 | + | const VkImportSemaphoreZirconHandleInfoFUCHSIA *pImportSemaphoreZirconHandleInfo); | |
| 125 | + | typedef VkResult(VKAPI_PTR *PFN_vkGetSemaphoreZirconHandleFUCHSIA)( | |
| 126 | + | VkDevice device, | |
| 127 | + | const VkSemaphoreGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo, | |
| 128 | + | zx_handle_t *pZirconHandle); | |
| 129 | + | ||
| 130 | + | #ifndef VK_NO_PROTOTYPES | |
| 131 | + | VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreZirconHandleFUCHSIA( | |
| 132 | + | VkDevice device, | |
| 133 | + | const VkImportSemaphoreZirconHandleInfoFUCHSIA *pImportSemaphoreZirconHandleInfo); | |
| 134 | + | ||
| 135 | + | VKAPI_ATTR VkResult VKAPI_CALL | |
| 136 | + | vkGetSemaphoreZirconHandleFUCHSIA(VkDevice device, | |
| 137 | + | const VkSemaphoreGetZirconHandleInfoFUCHSIA *pGetZirconHandleInfo, | |
| 138 | + | zx_handle_t *pZirconHandle); | |
| 139 | + | #endif | |
| 140 | + | ||
| 141 | + | #ifdef __cplusplus | |
| 142 | + | } | |
| 143 | + | #endif | |
| 144 | + | ||
| 145 | + | #endif // COMMON_VULKAN_FUCHSIA_EXT_H_ |
| @@ -0,0 +1,3 @@ | |||
| 1 | + | ||
| 2 | + | ||
| 3 | + | DisableFormat: true |