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