blob: 7d31d7076a26ef43c9e3839cbfe894856abf6020 [file] [log] [blame]
Jamie Madill440dc742013-06-20 11:55:55 -04001//
2// Copyright (c) 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
7#include "compiler/BlockLayoutEncoder.h"
8#include "compiler/Uniform.h"
9#include "common/mathutil.h"
10#include "common/utilities.h"
11
12namespace sh
13{
14
15BlockLayoutEncoder::BlockLayoutEncoder(std::vector<BlockMemberInfo> *blockInfoOut)
16 : mCurrentOffset(0),
17 mBlockInfoOut(blockInfoOut)
18{
19}
20
21void BlockLayoutEncoder::encodeFields(const std::vector<Uniform> &fields)
22{
23 for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
24 {
25 const Uniform &uniform = fields[fieldIndex];
26
27 if (uniform.fields.size() > 0)
28 {
29 const unsigned int elementCount = std::max(1u, uniform.arraySize);
30
31 for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
32 {
33 enterAggregateType();
34 encodeFields(uniform.fields);
35 exitAggregateType();
36 }
37 }
38 else
39 {
40 encodeType(uniform);
41 }
42 }
43}
44
45void BlockLayoutEncoder::encodeType(const Uniform &uniform)
46{
47 int arrayStride;
48 int matrixStride;
49
50 getBlockLayoutInfo(uniform, &arrayStride, &matrixStride);
51
52 const BlockMemberInfo memberInfo(mCurrentOffset * ComponentSize, arrayStride * ComponentSize, matrixStride * ComponentSize, uniform.isRowMajorMatrix);
53 mBlockInfoOut->push_back(memberInfo);
54
55 advanceOffset(uniform, arrayStride, matrixStride);
56}
57
58void BlockLayoutEncoder::nextRegister()
59{
60 mCurrentOffset = rx::roundUp(mCurrentOffset, RegisterSize);
61}
62
63Std140BlockEncoder::Std140BlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut)
64 : BlockLayoutEncoder(blockInfoOut)
65{
66}
67
68void Std140BlockEncoder::enterAggregateType()
69{
70 nextRegister();
71}
72
73void Std140BlockEncoder::exitAggregateType()
74{
75 nextRegister();
76}
77
78void Std140BlockEncoder::getBlockLayoutInfo(const Uniform &uniform, int *arrayStrideOut, int *matrixStrideOut)
79{
80 ASSERT(uniform.fields.empty());
81
82 // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
83 ASSERT(gl::UniformComponentSize(gl::UniformComponentType(uniform.type)) == ComponentSize);
84
85 int numComponents = gl::UniformComponentCount(uniform.type);
Jamie Madill919b0662013-06-20 11:55:56 -040086 size_t baseAlignment = 0;
Jamie Madill440dc742013-06-20 11:55:55 -040087 int matrixStride = 0;
88 int arrayStride = 0;
89
90 if (gl::IsMatrixType(uniform.type))
91 {
Jamie Madill919b0662013-06-20 11:55:56 -040092 baseAlignment = RegisterSize;
93 matrixStride = RegisterSize;
Jamie Madill440dc742013-06-20 11:55:55 -040094
95 if (uniform.arraySize > 0)
96 {
97 const int numRegisters = gl::MatrixRegisterCount(uniform.type, uniform.isRowMajorMatrix);
Jamie Madill919b0662013-06-20 11:55:56 -040098 arrayStride = RegisterSize * numRegisters;
Jamie Madill440dc742013-06-20 11:55:55 -040099 }
100 }
101 else if (uniform.arraySize > 0)
102 {
Jamie Madill919b0662013-06-20 11:55:56 -0400103 baseAlignment = RegisterSize;
104 arrayStride = RegisterSize;
105 }
106 else
107 {
108 const int numComponents = gl::UniformComponentCount(uniform.type);
109 baseAlignment = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
Jamie Madill440dc742013-06-20 11:55:55 -0400110 }
111
112 mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
113
114 *matrixStrideOut = matrixStride;
115 *arrayStrideOut = arrayStride;
116}
117
118void Std140BlockEncoder::advanceOffset(const Uniform &uniform, int arrayStride, int matrixStride)
119{
120 if (uniform.arraySize > 0)
121 {
122 mCurrentOffset += arrayStride * uniform.arraySize;
123 }
124 else if (gl::IsMatrixType(uniform.type))
125 {
126 ASSERT(matrixStride == RegisterSize);
127 const int numRegisters = gl::MatrixRegisterCount(uniform.type, uniform.isRowMajorMatrix);
128 mCurrentOffset += RegisterSize * numRegisters;
129 }
130 else
131 {
132 mCurrentOffset += gl::UniformComponentCount(uniform.type);
133 }
134}
135
136}