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 // blocklayout.h:
7 //   Methods and classes related to uniform layout and packing in GLSL and HLSL.
8 //
9 
10 #ifndef COMMON_BLOCKLAYOUTHLSL_H_
11 #define COMMON_BLOCKLAYOUTHLSL_H_
12 
13 #include <cstddef>
14 #include <vector>
15 
16 #include <GLSLANG/ShaderLang.h>
17 #include "angle_gl.h"
18 #include "blocklayout.h"
19 
20 namespace sh
21 {
22 // Block layout packed according to the D3D9 or default D3D10+ register packing rules
23 // See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
24 // The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED
25 // for everything else (D3D10+ constant blocks and all attributes/varyings).
26 
27 class HLSLBlockEncoder : public BlockLayoutEncoder
28 {
29   public:
30     enum HLSLBlockEncoderStrategy
31     {
32         ENCODE_PACKED,
33         ENCODE_LOOSE
34     };
35 
36     HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices);
37 
38     void enterAggregateType(const ShaderVariable &structVar) override;
39     void exitAggregateType(const ShaderVariable &structVar) override;
40     void skipRegisters(unsigned int numRegisters);
41 
isPacked()42     bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
43 
44     static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
45 
46   protected:
47     void getBlockLayoutInfo(GLenum type,
48                             const std::vector<unsigned int> &arraySizes,
49                             bool isRowMajorMatrix,
50                             int *arrayStrideOut,
51                             int *matrixStrideOut) override;
52     void advanceOffset(GLenum type,
53                        const std::vector<unsigned int> &arraySizes,
54                        bool isRowMajorMatrix,
55                        int arrayStride,
56                        int matrixStride) override;
57 
58     HLSLBlockEncoderStrategy mEncoderStrategy;
59     bool mTransposeMatrices;
60 };
61 
62 // This method returns the number of used registers for a ShaderVariable. It is dependent on the
63 // HLSLBlockEncoder class to count the number of used registers in a struct (which are individually
64 // packed according to the same rules).
65 unsigned int HLSLVariableRegisterCount(const ShaderVariable &variable, ShShaderOutput outputType);
66 }  // namespace sh
67 
68 #endif  // COMMON_BLOCKLAYOUTHLSL_H_
69