1 // 2 // Copyright (c) 2013-2014 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 // blocklayout.h: 7 // Methods and classes related to uniform layout and packing in GLSL and HLSL. 8 // 9 10 #ifndef COMMON_BLOCKLAYOUT_H_ 11 #define COMMON_BLOCKLAYOUT_H_ 12 13 #include <cstddef> 14 #include <map> 15 #include <vector> 16 17 #include "angle_gl.h" 18 #include <GLSLANG/ShaderLang.h> 19 20 namespace sh 21 { 22 struct ShaderVariable; 23 struct InterfaceBlockField; 24 struct Uniform; 25 struct Varying; 26 struct InterfaceBlock; 27 28 struct BlockMemberInfo 29 { BlockMemberInfoBlockMemberInfo30 BlockMemberInfo() 31 : offset(-1), 32 arrayStride(-1), 33 matrixStride(-1), 34 isRowMajorMatrix(false), 35 topLevelArrayStride(-1) 36 { 37 } 38 BlockMemberInfoBlockMemberInfo39 BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix) 40 : offset(offset), 41 arrayStride(arrayStride), 42 matrixStride(matrixStride), 43 isRowMajorMatrix(isRowMajorMatrix), 44 topLevelArrayStride(-1) 45 { 46 } 47 BlockMemberInfoBlockMemberInfo48 BlockMemberInfo(int offset, 49 int arrayStride, 50 int matrixStride, 51 bool isRowMajorMatrix, 52 int topLevelArrayStride) 53 : offset(offset), 54 arrayStride(arrayStride), 55 matrixStride(matrixStride), 56 isRowMajorMatrix(isRowMajorMatrix), 57 topLevelArrayStride(topLevelArrayStride) 58 { 59 } 60 getDefaultBlockInfoBlockMemberInfo61 static BlockMemberInfo getDefaultBlockInfo() { return BlockMemberInfo(-1, -1, -1, false, -1); } 62 63 int offset; 64 int arrayStride; 65 int matrixStride; 66 bool isRowMajorMatrix; 67 int topLevelArrayStride; // Only used for shader storage block members. 68 }; 69 70 class BlockLayoutEncoder 71 { 72 public: 73 BlockLayoutEncoder(); ~BlockLayoutEncoder()74 virtual ~BlockLayoutEncoder() {} 75 76 BlockMemberInfo encodeType(GLenum type, 77 const std::vector<unsigned int> &arraySizes, 78 bool isRowMajorMatrix); 79 getBlockSize()80 size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; } 81 82 virtual void enterAggregateType() = 0; 83 virtual void exitAggregateType() = 0; 84 85 static const size_t BytesPerComponent = 4u; 86 static const unsigned int ComponentsPerRegister = 4u; 87 88 static size_t getBlockRegister(const BlockMemberInfo &info); 89 static size_t getBlockRegisterElement(const BlockMemberInfo &info); 90 91 protected: 92 size_t mCurrentOffset; 93 94 void nextRegister(); 95 96 virtual void getBlockLayoutInfo(GLenum type, 97 const std::vector<unsigned int> &arraySizes, 98 bool isRowMajorMatrix, 99 int *arrayStrideOut, 100 int *matrixStrideOut) = 0; 101 virtual void advanceOffset(GLenum type, 102 const std::vector<unsigned int> &arraySizes, 103 bool isRowMajorMatrix, 104 int arrayStride, 105 int matrixStride) = 0; 106 }; 107 108 // Block layout according to the std140 block layout 109 // See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification 110 111 class Std140BlockEncoder : public BlockLayoutEncoder 112 { 113 public: 114 Std140BlockEncoder(); 115 116 void enterAggregateType() override; 117 void exitAggregateType() override; 118 119 protected: 120 void getBlockLayoutInfo(GLenum type, 121 const std::vector<unsigned int> &arraySizes, 122 bool isRowMajorMatrix, 123 int *arrayStrideOut, 124 int *matrixStrideOut) override; 125 void advanceOffset(GLenum type, 126 const std::vector<unsigned int> &arraySizes, 127 bool isRowMajorMatrix, 128 int arrayStride, 129 int matrixStride) override; 130 }; 131 132 using BlockLayoutMap = std::map<std::string, BlockMemberInfo>; 133 134 // Only valid to call with ShaderVariable, InterfaceBlockField and Uniform. 135 template <typename VarT> 136 void GetUniformBlockInfo(const std::vector<VarT> &fields, 137 const std::string &prefix, 138 sh::BlockLayoutEncoder *encoder, 139 bool inRowMajorLayout, 140 BlockLayoutMap *blockLayoutMap); 141 142 } // namespace sh 143 144 #endif // COMMON_BLOCKLAYOUT_H_ 145