blob: 3a1ab5ccb07d3697ae6fabebbfb3c787d8593acd [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;
Jamie Madill834e8b72014-04-11 13:33:58 -040022struct Uniform;
23struct Varying;
Jamie Madillfc43d272014-07-11 17:02:02 -040024struct InterfaceBlock;
Jamie Madill834e8b72014-04-11 13:33:58 -040025
Jamie Madille04a5b72014-07-18 10:33:12 -040026struct BlockMemberInfo
27{
28 BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
29 : offset(offset),
30 arrayStride(arrayStride),
31 matrixStride(matrixStride),
32 isRowMajorMatrix(isRowMajorMatrix)
33 {}
34
35 static BlockMemberInfo getDefaultBlockInfo()
36 {
37 return BlockMemberInfo(-1, -1, -1, false);
38 }
39
40 int offset;
41 int arrayStride;
42 int matrixStride;
43 bool isRowMajorMatrix;
44};
45
Jamie Madill834e8b72014-04-11 13:33:58 -040046class BlockLayoutEncoder
47{
48 public:
Jamie Madille04a5b72014-07-18 10:33:12 -040049 BlockLayoutEncoder();
Jamie Madill834e8b72014-04-11 13:33:58 -040050
51 void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields);
Jamie Madille04a5b72014-07-18 10:33:12 -040052 BlockMemberInfo encodeInterfaceBlockField(const InterfaceBlockField &field);
Jamie Madill834e8b72014-04-11 13:33:58 -040053 void encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
Jamie Madille04a5b72014-07-18 10:33:12 -040054
Jamie Madill834e8b72014-04-11 13:33:58 -040055 size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
Jamie Madillbf9cce22014-07-18 10:33:09 -040056 size_t getCurrentRegister() const { return mCurrentOffset / ComponentsPerRegister; }
57 size_t getCurrentElement() const { return mCurrentOffset % ComponentsPerRegister; }
Jamie Madill834e8b72014-04-11 13:33:58 -040058
Jamie Madille04a5b72014-07-18 10:33:12 -040059 virtual void enterAggregateType() = 0;
60 virtual void exitAggregateType() = 0;
61
Jamie Madill834e8b72014-04-11 13:33:58 -040062 static const size_t BytesPerComponent = 4u;
63 static const unsigned int ComponentsPerRegister = 4u;
64
65 protected:
66 size_t mCurrentOffset;
67
68 void nextRegister();
69
Jamie Madill834e8b72014-04-11 13:33:58 -040070 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0;
71 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0;
Jamie Madill834e8b72014-04-11 13:33:58 -040072};
73
74// Block layout according to the std140 block layout
75// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
76
77class Std140BlockEncoder : public BlockLayoutEncoder
78{
79 public:
Jamie Madille04a5b72014-07-18 10:33:12 -040080 Std140BlockEncoder();
Jamie Madill834e8b72014-04-11 13:33:58 -040081
Jamie Madill834e8b72014-04-11 13:33:58 -040082 virtual void enterAggregateType();
83 virtual void exitAggregateType();
Jamie Madille04a5b72014-07-18 10:33:12 -040084
85 protected:
Jamie Madill834e8b72014-04-11 13:33:58 -040086 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
87 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
88};
89
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040090// Block layout packed according to the D3D9 or default D3D10+ register packing rules
Jamie Madill834e8b72014-04-11 13:33:58 -040091// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
Jamie Madillf91ce812014-06-13 10:04:34 -040092// The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040093// for everything else (D3D10+ constant blocks and all attributes/varyings).
Jamie Madill834e8b72014-04-11 13:33:58 -040094
95class HLSLBlockEncoder : public BlockLayoutEncoder
96{
97 public:
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -040098 enum HLSLBlockEncoderStrategy
99 {
100 ENCODE_PACKED,
101 ENCODE_LOOSE
102 };
103
Jamie Madille04a5b72014-07-18 10:33:12 -0400104 HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy);
Jamie Madill834e8b72014-04-11 13:33:58 -0400105
106 virtual void enterAggregateType();
107 virtual void exitAggregateType();
Jamie Madillc600c8c2014-05-16 11:22:21 -0400108 void skipRegisters(unsigned int numRegisters);
Jamie Madill834e8b72014-04-11 13:33:58 -0400109
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400110 bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
111
Jamie Madillbf9cce22014-07-18 10:33:09 -0400112 static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
113
Jamie Madill834e8b72014-04-11 13:33:58 -0400114 protected:
115 virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
116 virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400117
118 HLSLBlockEncoderStrategy mEncoderStrategy;
Jamie Madill834e8b72014-04-11 13:33:58 -0400119};
120
Jamie Madill834e8b72014-04-11 13:33:58 -0400121// This method returns the number of used registers for a ShaderVariable. It is dependent on the HLSLBlockEncoder
122// class to count the number of used registers in a struct (which are individually packed according to the same rules).
123unsigned int HLSLVariableRegisterCount(const Varying &variable);
Vladimir Vukicevic24d8d672014-05-27 12:07:51 -0400124unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType);
Jamie Madill834e8b72014-04-11 13:33:58 -0400125
126}
127
128#endif // COMMON_BLOCKLAYOUT_H_