blob: 4ee58004ebd989266e3d71af8d4255584b82b997 [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;
25
26class BlockLayoutEncoder
27{
28 public:
29 BlockLayoutEncoder(std::vector<BlockMemberInfo> *blockInfoOut);
30
31 void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields);
32 void encodeInterfaceBlockField(const InterfaceBlockField &field);
33 void encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
34 size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
35
36 static const size_t BytesPerComponent = 4u;
37 static const unsigned int ComponentsPerRegister = 4u;
38
39 protected:
40 size_t mCurrentOffset;
41
42 void nextRegister();
43
44 virtual void enterAggregateType() = 0;
45 virtual void exitAggregateType() = 0;
46 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0;
47 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0;
48
49 private:
50 std::vector<BlockMemberInfo> *mBlockInfoOut;
51};
52
53// Block layout according to the std140 block layout
54// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
55
56class Std140BlockEncoder : public BlockLayoutEncoder
57{
58 public:
59 Std140BlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut);
60
61 protected:
62 virtual void enterAggregateType();
63 virtual void exitAggregateType();
64 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
65 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
66};
67
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040068// Block layout packed according to the D3D9 or default D3D10+ register packing rules
Jamie Madill834e8b72014-04-11 13:33:58 -040069// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
Jamie Madillf91ce812014-06-13 10:04:34 -040070// The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040071// for everything else (D3D10+ constant blocks and all attributes/varyings).
Jamie Madill834e8b72014-04-11 13:33:58 -040072
73class HLSLBlockEncoder : public BlockLayoutEncoder
74{
75 public:
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040076 enum HLSLBlockEncoderStrategy
77 {
78 ENCODE_PACKED,
79 ENCODE_LOOSE
80 };
81
82 HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut,
83 HLSLBlockEncoderStrategy strategy);
Jamie Madill834e8b72014-04-11 13:33:58 -040084
85 virtual void enterAggregateType();
86 virtual void exitAggregateType();
Jamie Madillc600c8c2014-05-16 11:22:21 -040087 void skipRegisters(unsigned int numRegisters);
Jamie Madill834e8b72014-04-11 13:33:58 -040088
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040089 bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
90
Jamie Madill834e8b72014-04-11 13:33:58 -040091 protected:
92 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
93 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040094
95 HLSLBlockEncoderStrategy mEncoderStrategy;
Jamie Madill834e8b72014-04-11 13:33:58 -040096};
97
98// This method assigns values to the variable's "registerIndex" and "elementIndex" fields.
99// "elementIndex" is only used for structures.
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400100void HLSLVariableGetRegisterInfo(unsigned int baseRegisterIndex, Uniform *variable, ShShaderOutput outputType);
Jamie Madill834e8b72014-04-11 13:33:58 -0400101
102// This method returns the number of used registers for a ShaderVariable. It is dependent on the HLSLBlockEncoder
103// class to count the number of used registers in a struct (which are individually packed according to the same rules).
104unsigned int HLSLVariableRegisterCount(const Varying &variable);
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400105unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType);
Jamie Madill834e8b72014-04-11 13:33:58 -0400106
107}
108
109#endif // COMMON_BLOCKLAYOUT_H_