blob: bed99c40f15e0d08a490d91ff6e2cb1865401bd3 [file] [log] [blame]
Jamie Madill834e8b72014-04-11 13:33:58 -04001//
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
Jamie Madill13cfd272014-07-17 14:16:28 -040013#include <cstddef>
Jamie Madill834e8b72014-04-11 13:33:58 -040014#include <vector>
Jamie Madill13cfd272014-07-17 14:16:28 -040015
Jamie Madillf51639a2014-06-25 16:04:57 -040016#include "angle_gl.h"
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040017#include <GLSLANG/ShaderLang.h>
Jamie Madill834e8b72014-04-11 13:33:58 -040018
Jamie Madillf2575982014-06-25 16:04:54 -040019namespace sh
Jamie Madill834e8b72014-04-11 13:33:58 -040020{
Jamie Madill834e8b72014-04-11 13:33:58 -040021struct ShaderVariable;
22struct InterfaceBlockField;
Jamie Madill834e8b72014-04-11 13:33:58 -040023struct Uniform;
24struct Varying;
Jamie Madillfc43d272014-07-11 17:02:02 -040025struct InterfaceBlock;
Jamie Madill834e8b72014-04-11 13:33:58 -040026
Jamie Madille04a5b72014-07-18 10:33:12 -040027struct 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
Jamie Madill834e8b72014-04-11 13:33:58 -040047class BlockLayoutEncoder
48{
49 public:
Jamie Madille04a5b72014-07-18 10:33:12 -040050 BlockLayoutEncoder();
Jamie Madill834e8b72014-04-11 13:33:58 -040051
52 void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields);
Jamie Madille04a5b72014-07-18 10:33:12 -040053 BlockMemberInfo encodeInterfaceBlockField(const InterfaceBlockField &field);
Jamie Madill834e8b72014-04-11 13:33:58 -040054 void encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
Jamie Madille04a5b72014-07-18 10:33:12 -040055
Jamie Madill834e8b72014-04-11 13:33:58 -040056 size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
Jamie Madillbf9cce22014-07-18 10:33:09 -040057 size_t getCurrentRegister() const { return mCurrentOffset / ComponentsPerRegister; }
58 size_t getCurrentElement() const { return mCurrentOffset % ComponentsPerRegister; }
Jamie Madill834e8b72014-04-11 13:33:58 -040059
Jamie Madille04a5b72014-07-18 10:33:12 -040060 virtual void enterAggregateType() = 0;
61 virtual void exitAggregateType() = 0;
62
Jamie Madill834e8b72014-04-11 13:33:58 -040063 static const size_t BytesPerComponent = 4u;
64 static const unsigned int ComponentsPerRegister = 4u;
65
66 protected:
67 size_t mCurrentOffset;
68
69 void nextRegister();
70
Jamie Madill834e8b72014-04-11 13:33:58 -040071 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0;
72 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0;
Jamie Madill834e8b72014-04-11 13:33:58 -040073};
74
75// Block layout according to the std140 block layout
76// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
77
78class Std140BlockEncoder : public BlockLayoutEncoder
79{
80 public:
Jamie Madille04a5b72014-07-18 10:33:12 -040081 Std140BlockEncoder();
Jamie Madill834e8b72014-04-11 13:33:58 -040082
Jamie Madill834e8b72014-04-11 13:33:58 -040083 virtual void enterAggregateType();
84 virtual void exitAggregateType();
Jamie Madille04a5b72014-07-18 10:33:12 -040085
86 protected:
Jamie Madill834e8b72014-04-11 13:33:58 -040087 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
88 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
89};
90
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040091// Block layout packed according to the D3D9 or default D3D10+ register packing rules
Jamie Madill834e8b72014-04-11 13:33:58 -040092// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
Jamie Madillf91ce812014-06-13 10:04:34 -040093// The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040094// for everything else (D3D10+ constant blocks and all attributes/varyings).
Jamie Madill834e8b72014-04-11 13:33:58 -040095
96class HLSLBlockEncoder : public BlockLayoutEncoder
97{
98 public:
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040099 enum HLSLBlockEncoderStrategy
100 {
101 ENCODE_PACKED,
102 ENCODE_LOOSE
103 };
104
Jamie Madille04a5b72014-07-18 10:33:12 -0400105 HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy);
Jamie Madill834e8b72014-04-11 13:33:58 -0400106
107 virtual void enterAggregateType();
108 virtual void exitAggregateType();
Jamie Madillc600c8c2014-05-16 11:22:21 -0400109 void skipRegisters(unsigned int numRegisters);
Jamie Madill834e8b72014-04-11 13:33:58 -0400110
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400111 bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
112
Jamie Madillbf9cce22014-07-18 10:33:09 -0400113 static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
114
Jamie Madill834e8b72014-04-11 13:33:58 -0400115 protected:
116 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
117 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400118
119 HLSLBlockEncoderStrategy mEncoderStrategy;
Jamie Madill834e8b72014-04-11 13:33:58 -0400120};
121
Jamie Madill834e8b72014-04-11 13:33:58 -0400122// This method returns the number of used registers for a ShaderVariable. It is dependent on the HLSLBlockEncoder
123// class to count the number of used registers in a struct (which are individually packed according to the same rules).
124unsigned int HLSLVariableRegisterCount(const Varying &variable);
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400125unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType);
Jamie Madill834e8b72014-04-11 13:33:58 -0400126
127}
128
129#endif // COMMON_BLOCKLAYOUT_H_