blob: 2df6db9ee15ee02930c551c2ee7e182a31427315 [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
13#include <vector>
Jamie Madillf51639a2014-06-25 16:04:57 -040014#include "angle_gl.h"
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040015#include <GLSLANG/ShaderLang.h>
Jamie Madill9fba2ba2014-04-22 14:21:00 -040016#include <cstddef>
Jamie Madill834e8b72014-04-11 13:33:58 -040017
Jamie Madillf2575982014-06-25 16:04:54 -040018namespace sh
Jamie Madill834e8b72014-04-11 13:33:58 -040019{
Jamie Madill834e8b72014-04-11 13:33:58 -040020struct ShaderVariable;
21struct InterfaceBlockField;
22struct BlockMemberInfo;
23struct Uniform;
24struct Varying;
Jamie Madillfc43d272014-07-11 17:02:02 -040025struct InterfaceBlock;
Jamie Madill834e8b72014-04-11 13:33:58 -040026
27class BlockLayoutEncoder
28{
29 public:
30 BlockLayoutEncoder(std::vector<BlockMemberInfo> *blockInfoOut);
31
32 void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields);
33 void encodeInterfaceBlockField(const InterfaceBlockField &field);
34 void encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
35 size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
Jamie Madillbf9cce22014-07-18 10:33:09 -040036 size_t getCurrentRegister() const { return mCurrentOffset / ComponentsPerRegister; }
37 size_t getCurrentElement() const { return mCurrentOffset % ComponentsPerRegister; }
Jamie Madill834e8b72014-04-11 13:33:58 -040038
39 static const size_t BytesPerComponent = 4u;
40 static const unsigned int ComponentsPerRegister = 4u;
41
42 protected:
43 size_t mCurrentOffset;
44
45 void nextRegister();
46
47 virtual void enterAggregateType() = 0;
48 virtual void exitAggregateType() = 0;
49 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0;
50 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0;
51
52 private:
53 std::vector<BlockMemberInfo> *mBlockInfoOut;
54};
55
56// Block layout according to the std140 block layout
57// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
58
59class Std140BlockEncoder : public BlockLayoutEncoder
60{
61 public:
62 Std140BlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut);
63
64 protected:
65 virtual void enterAggregateType();
66 virtual void exitAggregateType();
67 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
68 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
69};
70
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040071// Block layout packed according to the D3D9 or default D3D10+ register packing rules
Jamie Madill834e8b72014-04-11 13:33:58 -040072// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
Jamie Madillf91ce812014-06-13 10:04:34 -040073// The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040074// for everything else (D3D10+ constant blocks and all attributes/varyings).
Jamie Madill834e8b72014-04-11 13:33:58 -040075
76class HLSLBlockEncoder : public BlockLayoutEncoder
77{
78 public:
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040079 enum HLSLBlockEncoderStrategy
80 {
81 ENCODE_PACKED,
82 ENCODE_LOOSE
83 };
84
85 HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut,
86 HLSLBlockEncoderStrategy strategy);
Jamie Madillbf9cce22014-07-18 10:33:09 -040087 HLSLBlockEncoder(ShShaderOutput outputType);
Jamie Madill834e8b72014-04-11 13:33:58 -040088
89 virtual void enterAggregateType();
90 virtual void exitAggregateType();
Jamie Madillc600c8c2014-05-16 11:22:21 -040091 void skipRegisters(unsigned int numRegisters);
Jamie Madill834e8b72014-04-11 13:33:58 -040092
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040093 bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
94
Jamie Madillbf9cce22014-07-18 10:33:09 -040095 static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
96
Jamie Madill834e8b72014-04-11 13:33:58 -040097 protected:
98 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
99 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400100
101 HLSLBlockEncoderStrategy mEncoderStrategy;
Jamie Madill834e8b72014-04-11 13:33:58 -0400102};
103
Jamie Madillfc43d272014-07-11 17:02:02 -0400104// This method returns the data size of an interface block in HLSL, according to its layout.
105size_t HLSLInterfaceBlockDataSize(const sh::InterfaceBlock &interfaceBlock);
106
Jamie Madill834e8b72014-04-11 13:33:58 -0400107// This method assigns values to the variable's "registerIndex" and "elementIndex" fields.
108// "elementIndex" is only used for structures.
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400109void HLSLVariableGetRegisterInfo(unsigned int baseRegisterIndex, Uniform *variable, ShShaderOutput outputType);
Jamie Madill834e8b72014-04-11 13:33:58 -0400110
111// This method returns the number of used registers for a ShaderVariable. It is dependent on the HLSLBlockEncoder
112// class to count the number of used registers in a struct (which are individually packed according to the same rules).
113unsigned int HLSLVariableRegisterCount(const Varying &variable);
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400114unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType);
Jamie Madill834e8b72014-04-11 13:33:58 -0400115
116}
117
118#endif // COMMON_BLOCKLAYOUT_H_