summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/include/GLSLANG/ShaderVars.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/include/GLSLANG/ShaderVars.h')
-rw-r--r--gfx/angle/checkout/include/GLSLANG/ShaderVars.h327
1 files changed, 327 insertions, 0 deletions
diff --git a/gfx/angle/checkout/include/GLSLANG/ShaderVars.h b/gfx/angle/checkout/include/GLSLANG/ShaderVars.h
new file mode 100644
index 0000000000..67a4039cd7
--- /dev/null
+++ b/gfx/angle/checkout/include/GLSLANG/ShaderVars.h
@@ -0,0 +1,327 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ShaderVars.h:
+// Types to represent GL variables (varyings, uniforms, etc)
+//
+
+#ifndef GLSLANG_SHADERVARS_H_
+#define GLSLANG_SHADERVARS_H_
+
+#include <algorithm>
+#include <array>
+#include <string>
+#include <vector>
+
+// This type is defined here to simplify ANGLE's integration with glslang for SPIRv.
+using ShCompileOptions = uint64_t;
+
+namespace sh
+{
+// GLenum alias
+typedef unsigned int GLenum;
+
+// Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec
+enum InterpolationType
+{
+ INTERPOLATION_SMOOTH,
+ INTERPOLATION_CENTROID,
+ INTERPOLATION_SAMPLE,
+ INTERPOLATION_FLAT,
+ INTERPOLATION_NOPERSPECTIVE
+};
+
+// Validate link & SSO consistency of interpolation qualifiers
+bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
+
+// Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
+enum BlockLayoutType
+{
+ BLOCKLAYOUT_STANDARD,
+ BLOCKLAYOUT_STD140 = BLOCKLAYOUT_STANDARD,
+ BLOCKLAYOUT_STD430, // Shader storage block layout qualifier
+ BLOCKLAYOUT_PACKED,
+ BLOCKLAYOUT_SHARED
+};
+
+// Interface Blocks, see section 4.3.9 of the ESSL 3.10 spec
+enum class BlockType
+{
+ BLOCK_UNIFORM,
+ BLOCK_BUFFER,
+};
+
+// Base class for all variables defined in shaders, including Varyings, Uniforms, etc
+// Note: we must override the copy constructor and assignment operator so we can
+// work around excessive GCC binary bloating:
+// See https://code.google.com/p/angleproject/issues/detail?id=697
+struct ShaderVariable
+{
+ ShaderVariable();
+ ShaderVariable(GLenum typeIn);
+ ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
+ ~ShaderVariable();
+ ShaderVariable(const ShaderVariable &other);
+ ShaderVariable &operator=(const ShaderVariable &other);
+ bool operator==(const ShaderVariable &other) const;
+ bool operator!=(const ShaderVariable &other) const { return !operator==(other); }
+
+ bool isArrayOfArrays() const { return arraySizes.size() >= 2u; }
+ bool isArray() const { return !arraySizes.empty(); }
+ unsigned int getArraySizeProduct() const;
+ // Return the inner array size product.
+ // For example, if there's a variable declared as size 3 array of size 4 array of size 5 array
+ // of int:
+ // int a[3][4][5];
+ // then getInnerArraySizeProduct of a would be 4*5.
+ unsigned int getInnerArraySizeProduct() const;
+
+ // Array size 0 means not an array when passed to or returned from these functions.
+ // Note that setArraySize() is deprecated and should not be used inside ANGLE.
+ unsigned int getOutermostArraySize() const { return isArray() ? arraySizes.back() : 0; }
+ void setArraySize(unsigned int size);
+
+ // Turn this ShaderVariable from an array into a specific element in that array. Will update
+ // flattenedOffsetInParentArrays.
+ void indexIntoArray(unsigned int arrayIndex);
+
+ // Get the nth nested array size from the top. Caller is responsible for range checking
+ // arrayNestingIndex.
+ unsigned int getNestedArraySize(unsigned int arrayNestingIndex) const;
+
+ // This function should only be used with variables that are of a basic type or an array of a
+ // basic type. Shader interface variables that are enumerated according to rules in GLES 3.1
+ // spec section 7.3.1.1 page 77 are fine. For those variables the return value should match the
+ // ARRAY_SIZE value that can be queried through the API.
+ unsigned int getBasicTypeElementCount() const;
+
+ unsigned int getExternalSize() const;
+
+ bool isStruct() const { return !fields.empty(); }
+ const std::string &getStructName() const { return structOrBlockName; }
+ void setStructName(const std::string &newName) { structOrBlockName = newName; }
+
+ // All of the shader's variables are described using nested data
+ // structures. This is needed in order to disambiguate similar looking
+ // types, such as two structs containing the same fields, but in
+ // different orders. "findInfoByMappedName" provides an easy query for
+ // users to dive into the data structure and fetch the unique variable
+ // instance corresponding to a dereferencing chain of the top-level
+ // variable.
+ // Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
+ // that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
+ // in |originalName|, based on the assumption that |this| defines 'a'.
+ // If no match is found, return false.
+ bool findInfoByMappedName(const std::string &mappedFullName,
+ const ShaderVariable **leafVar,
+ std::string *originalFullName) const;
+
+ // Find the child field which matches 'fullName' == var.name + "." + field.name.
+ // Return nullptr if not found.
+ const sh::ShaderVariable *findField(const std::string &fullName, uint32_t *fieldIndexOut) const;
+
+ bool isBuiltIn() const;
+ bool isEmulatedBuiltIn() const;
+
+ // Offset of this variable in parent arrays. In case the parent is an array of arrays, the
+ // offset is outerArrayElement * innerArraySize + innerArrayElement.
+ // For example, if there's a variable declared as size 3 array of size 4 array of int:
+ // int a[3][4];
+ // then the flattenedOffsetInParentArrays of a[2] would be 2.
+ // and flattenedOffsetInParentArrays of a[2][1] would be 2*4 + 1 = 9.
+ int parentArrayIndex() const
+ {
+ return hasParentArrayIndex() ? flattenedOffsetInParentArrays : 0;
+ }
+
+ int getFlattenedOffsetInParentArrays() const { return flattenedOffsetInParentArrays; }
+ void setParentArrayIndex(int indexIn) { flattenedOffsetInParentArrays = indexIn; }
+
+ bool hasParentArrayIndex() const { return flattenedOffsetInParentArrays != -1; }
+
+ void resetEffectiveLocation();
+ void updateEffectiveLocation(const sh::ShaderVariable &parent);
+
+ // Decide whether two uniforms are the same at shader link time,
+ // assuming they are from consecutive shader stages.
+ // GLSL ES Spec 3.00.3, section 4.3.5.
+ // GLSL ES Spec 3.10.4, section 4.4.5
+ bool isSameUniformAtLinkTime(const ShaderVariable &other) const;
+
+ // InterfaceBlockField
+ // Decide whether two InterfaceBlock fields are the same at shader
+ // link time, assuming they are from consecutive shader stages.
+ // See GLSL ES Spec 3.00.3, sec 4.3.7.
+ bool isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable &other) const;
+
+ // Decide whether two varyings are the same at shader link time,
+ // assuming they are from consecutive shader stages.
+ // Invariance needs to match only in ESSL1. Relevant spec sections:
+ // GLSL ES 3.00.4, sections 4.6.1 and 4.3.9.
+ // GLSL ES 1.00.17, section 4.6.4.
+ bool isSameVaryingAtLinkTime(const ShaderVariable &other, int shaderVersion) const;
+ // Deprecated version of isSameVaryingAtLinkTime, which assumes ESSL1.
+ bool isSameVaryingAtLinkTime(const ShaderVariable &other) const;
+
+ // Shader I/O blocks may match by block name or instance, based on whether both stages have an
+ // instance name or not.
+ bool isSameNameAtLinkTime(const ShaderVariable &other) const;
+
+ // NOTE: When adding new members, the following functions also need to be updated:
+ // gl::WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
+ // gl::LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
+
+ GLenum type;
+ GLenum precision;
+ std::string name;
+ std::string mappedName;
+
+ // Used to make an array type. Outermost array size is stored at the end of the vector.
+ std::vector<unsigned int> arraySizes;
+
+ // Static use means that the variable is accessed somewhere in the shader source.
+ bool staticUse;
+ // A variable is active unless the compiler determined that it is not accessed by the shader.
+ // All active variables are statically used, but not all statically used variables are
+ // necessarily active. GLES 3.0.5 section 2.12.6. GLES 3.1 section 7.3.1.
+ bool active;
+ std::vector<ShaderVariable> fields;
+ // structOrBlockName is used for:
+ // - varyings of struct type, in which case it contains the struct name.
+ // - shader I/O blocks, in which case it contains the block name.
+ std::string structOrBlockName;
+ std::string mappedStructOrBlockName;
+
+ // Only applies to interface block fields. Kept here for simplicity.
+ bool isRowMajorLayout;
+
+ // VariableWithLocation
+ int location;
+
+ // The location of inputs or outputs without location layout quailifer will be updated to '-1'.
+ // GLES Spec 3.1, Section 7.3. PROGRAM OBJECTS
+ // Not all active variables are assigned valid locations;
+ // the following variables will have an effective location of -1:
+ bool hasImplicitLocation;
+
+ // Uniform
+ int binding;
+ GLenum imageUnitFormat;
+ int offset;
+ bool readonly;
+ bool writeonly;
+
+ // From EXT_shader_framebuffer_fetch
+ bool isFragmentInOut;
+
+ // OutputVariable
+ // From EXT_blend_func_extended.
+ int index;
+
+ // From EXT_YUV_target
+ bool yuv;
+
+ // Varying
+ InterpolationType interpolation;
+ bool isInvariant;
+ bool isShaderIOBlock;
+ bool isPatch;
+
+ // If the variable is a sampler that has ever been statically used with texelFetch
+ bool texelFetchStaticUse;
+
+ protected:
+ bool isSameVariableAtLinkTime(const ShaderVariable &other,
+ bool matchPrecision,
+ bool matchName) const;
+
+ // NOTE: When adding new members, the following functions also need to be updated:
+ // gl::WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
+ // gl::LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
+
+ int flattenedOffsetInParentArrays;
+};
+
+// TODO: anglebug.com/3899
+// For backwards compatibility for other codebases (e.g., chromium/src/gpu/command_buffer/service)
+using Uniform = ShaderVariable;
+using Attribute = ShaderVariable;
+using OutputVariable = ShaderVariable;
+using InterfaceBlockField = ShaderVariable;
+using Varying = ShaderVariable;
+
+struct InterfaceBlock
+{
+ InterfaceBlock();
+ ~InterfaceBlock();
+ InterfaceBlock(const InterfaceBlock &other);
+ InterfaceBlock &operator=(const InterfaceBlock &other);
+
+ // Fields from blocks with non-empty instance names are prefixed with the block name.
+ std::string fieldPrefix() const;
+ std::string fieldMappedPrefix() const;
+
+ // Decide whether two interface blocks are the same at shader link time.
+ bool isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const;
+
+ bool isBuiltIn() const;
+
+ bool isArray() const { return arraySize > 0; }
+ unsigned int elementCount() const { return std::max(1u, arraySize); }
+
+ std::string name;
+ std::string mappedName;
+ std::string instanceName;
+ unsigned int arraySize;
+ BlockLayoutType layout;
+
+ // Deprecated. Matrix packing should only be queried from individual fields of the block.
+ // TODO(oetuaho): Remove this once it is no longer used in Chromium.
+ bool isRowMajorLayout;
+
+ int binding;
+ bool staticUse;
+ bool active;
+ BlockType blockType;
+ std::vector<ShaderVariable> fields;
+};
+
+struct WorkGroupSize
+{
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ inline WorkGroupSize() = default;
+ inline explicit constexpr WorkGroupSize(int initialSize);
+
+ void fill(int fillValue);
+ void setLocalSize(int localSizeX, int localSizeY, int localSizeZ);
+
+ int &operator[](size_t index);
+ int operator[](size_t index) const;
+ size_t size() const;
+
+ // Checks whether two work group size declarations match.
+ // Two work group size declarations are the same if the explicitly specified elements are the
+ // same or if one of them is specified as one and the other one is not specified
+ bool isWorkGroupSizeMatching(const WorkGroupSize &right) const;
+
+ // Checks whether any of the values are set.
+ bool isAnyValueSet() const;
+
+ // Checks whether all of the values are set.
+ bool isDeclared() const;
+
+ // Checks whether either all of the values are set, or none of them are.
+ bool isLocalSizeValid() const;
+
+ int localSizeQualifiers[3];
+};
+
+inline constexpr WorkGroupSize::WorkGroupSize(int initialSize)
+ : localSizeQualifiers{initialSize, initialSize, initialSize}
+{}
+
+} // namespace sh
+
+#endif // GLSLANG_SHADERVARS_H_