blob: 190516dd8e375546510976a6253f792764f8ba56 [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);
86 size_t baseAlignment = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
87 int matrixStride = 0;
88 int arrayStride = 0;
89
90 if (gl::IsMatrixType(uniform.type))
91 {
92 numComponents = gl::MatrixComponentCount(uniform.type, uniform.isRowMajorMatrix);
93 baseAlignment = rx::roundUp(baseAlignment, RegisterSize);
94 matrixStride = baseAlignment;
95
96 if (uniform.arraySize > 0)
97 {
98 const int numRegisters = gl::MatrixRegisterCount(uniform.type, uniform.isRowMajorMatrix);
99 arrayStride = matrixStride * numRegisters;
100 }
101 }
102 else if (uniform.arraySize > 0)
103 {
104 baseAlignment = rx::roundUp(baseAlignment, RegisterSize);
105 arrayStride = baseAlignment;
106 }
107
108 mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
109
110 *matrixStrideOut = matrixStride;
111 *arrayStrideOut = arrayStride;
112}
113
114void Std140BlockEncoder::advanceOffset(const Uniform &uniform, int arrayStride, int matrixStride)
115{
116 if (uniform.arraySize > 0)
117 {
118 mCurrentOffset += arrayStride * uniform.arraySize;
119 }
120 else if (gl::IsMatrixType(uniform.type))
121 {
122 ASSERT(matrixStride == RegisterSize);
123 const int numRegisters = gl::MatrixRegisterCount(uniform.type, uniform.isRowMajorMatrix);
124 mCurrentOffset += RegisterSize * numRegisters;
125 }
126 else
127 {
128 mCurrentOffset += gl::UniformComponentCount(uniform.type);
129 }
130}
131
132}