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 <vector> 14 #include <GLES3/gl3.h> 15 #include <GLES2/gl2.h> 16 #include <GLSLANG/ShaderLang.h> 17 #include <cstddef> 18 19 namespace gl 20 { 21 22 struct ShaderVariable; 23 struct InterfaceBlockField; 24 struct BlockMemberInfo; 25 struct Uniform; 26 struct Varying; 27 28 class BlockLayoutEncoder 29 { 30 public: 31 BlockLayoutEncoder(std::vector<BlockMemberInfo> *blockInfoOut); 32 33 void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields); 34 void encodeInterfaceBlockField(const InterfaceBlockField &field); 35 void encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix); 36 size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; } 37 38 static const size_t BytesPerComponent = 4u; 39 static const unsigned int ComponentsPerRegister = 4u; 40 41 protected: 42 size_t mCurrentOffset; 43 44 void nextRegister(); 45 46 virtual void enterAggregateType() = 0; 47 virtual void exitAggregateType() = 0; 48 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0; 49 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0; 50 51 private: 52 std::vector<BlockMemberInfo> *mBlockInfoOut; 53 }; 54 55 // Block layout according to the std140 block layout 56 // See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification 57 58 class Std140BlockEncoder : public BlockLayoutEncoder 59 { 60 public: 61 Std140BlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut); 62 63 protected: 64 virtual void enterAggregateType(); 65 virtual void exitAggregateType(); 66 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut); 67 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride); 68 }; 69 70 // Block layout packed according to the D3D9 or default D3D10+ register packing rules 71 // See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx 72 // The strategy should be ENCODE_LOOSE for D3D9 constnat blocks, and ENCODE_PACKED 73 // for everything else (D3D10+ constant blocks and all attributes/varyings). 74 75 class HLSLBlockEncoder : public BlockLayoutEncoder 76 { 77 public: 78 enum HLSLBlockEncoderStrategy 79 { 80 ENCODE_PACKED, 81 ENCODE_LOOSE 82 }; 83 84 HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut, 85 HLSLBlockEncoderStrategy strategy); 86 87 virtual void enterAggregateType(); 88 virtual void exitAggregateType(); 89 void skipRegisters(unsigned int numRegisters); 90 91 bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; } 92 93 protected: 94 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut); 95 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride); 96 97 HLSLBlockEncoderStrategy mEncoderStrategy; 98 }; 99 100 // This method assigns values to the variable's "registerIndex" and "elementIndex" fields. 101 // "elementIndex" is only used for structures. 102 void HLSLVariableGetRegisterInfo(unsigned int baseRegisterIndex, Uniform *variable, ShShaderOutput outputType); 103 104 // This method returns the number of used registers for a ShaderVariable. It is dependent on the HLSLBlockEncoder 105 // class to count the number of used registers in a struct (which are individually packed according to the same rules). 106 unsigned int HLSLVariableRegisterCount(const Varying &variable); 107 unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType); 108 109 } 110 111 #endif // COMMON_BLOCKLAYOUT_H_ 112