blob: ef2a0e9e2baffa85643d65402b6f2b27c62e9443 [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
Jamie Madill912cbfe2013-08-30 13:21:03 -040050 ASSERT(uniform.fields.empty());
51 getBlockLayoutInfo(uniform.type, uniform.arraySize, uniform.isRowMajorMatrix, &arrayStride, &matrixStride);
Jamie Madill440dc742013-06-20 11:55:55 -040052
53 const BlockMemberInfo memberInfo(mCurrentOffset * ComponentSize, arrayStride * ComponentSize, matrixStride * ComponentSize, uniform.isRowMajorMatrix);
54 mBlockInfoOut->push_back(memberInfo);
55
Jamie Madill912cbfe2013-08-30 13:21:03 -040056 advanceOffset(uniform.type, uniform.arraySize, uniform.isRowMajorMatrix, arrayStride, matrixStride);
57}
58
59void BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
60{
61 int arrayStride;
62 int matrixStride;
63
64 getBlockLayoutInfo(type, arraySize, isRowMajorMatrix, &arrayStride, &matrixStride);
65
66 const BlockMemberInfo memberInfo(mCurrentOffset * ComponentSize, arrayStride * ComponentSize, matrixStride * ComponentSize, isRowMajorMatrix);
67 mBlockInfoOut->push_back(memberInfo);
68
69 advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride);
Jamie Madill440dc742013-06-20 11:55:55 -040070}
71
72void BlockLayoutEncoder::nextRegister()
73{
74 mCurrentOffset = rx::roundUp(mCurrentOffset, RegisterSize);
75}
76
77Std140BlockEncoder::Std140BlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut)
78 : BlockLayoutEncoder(blockInfoOut)
79{
80}
81
82void Std140BlockEncoder::enterAggregateType()
83{
84 nextRegister();
85}
86
87void Std140BlockEncoder::exitAggregateType()
88{
89 nextRegister();
90}
91
Jamie Madill912cbfe2013-08-30 13:21:03 -040092void Std140BlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
Jamie Madill440dc742013-06-20 11:55:55 -040093{
Jamie Madill440dc742013-06-20 11:55:55 -040094 // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
Jamie Madill912cbfe2013-08-30 13:21:03 -040095 ASSERT(gl::UniformComponentSize(gl::UniformComponentType(type)) == ComponentSize);
Jamie Madill440dc742013-06-20 11:55:55 -040096
Jamie Madill912cbfe2013-08-30 13:21:03 -040097 int numComponents = gl::UniformComponentCount(type);
Jamie Madill919b0662013-06-20 11:55:56 -040098 size_t baseAlignment = 0;
Jamie Madill440dc742013-06-20 11:55:55 -040099 int matrixStride = 0;
100 int arrayStride = 0;
101
Jamie Madill912cbfe2013-08-30 13:21:03 -0400102 if (gl::IsMatrixType(type))
Jamie Madill440dc742013-06-20 11:55:55 -0400103 {
Jamie Madill919b0662013-06-20 11:55:56 -0400104 baseAlignment = RegisterSize;
105 matrixStride = RegisterSize;
Jamie Madill440dc742013-06-20 11:55:55 -0400106
Jamie Madill912cbfe2013-08-30 13:21:03 -0400107 if (arraySize > 0)
Jamie Madill440dc742013-06-20 11:55:55 -0400108 {
Jamie Madill912cbfe2013-08-30 13:21:03 -0400109 const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
Jamie Madill919b0662013-06-20 11:55:56 -0400110 arrayStride = RegisterSize * numRegisters;
Jamie Madill440dc742013-06-20 11:55:55 -0400111 }
112 }
Jamie Madill912cbfe2013-08-30 13:21:03 -0400113 else if (arraySize > 0)
Jamie Madill440dc742013-06-20 11:55:55 -0400114 {
Jamie Madill919b0662013-06-20 11:55:56 -0400115 baseAlignment = RegisterSize;
116 arrayStride = RegisterSize;
117 }
118 else
119 {
Jamie Madill912cbfe2013-08-30 13:21:03 -0400120 const int numComponents = gl::UniformComponentCount(type);
Jamie Madill919b0662013-06-20 11:55:56 -0400121 baseAlignment = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
Jamie Madill440dc742013-06-20 11:55:55 -0400122 }
123
124 mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
125
126 *matrixStrideOut = matrixStride;
127 *arrayStrideOut = arrayStride;
128}
129
Jamie Madill912cbfe2013-08-30 13:21:03 -0400130void Std140BlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
Jamie Madill440dc742013-06-20 11:55:55 -0400131{
Jamie Madill912cbfe2013-08-30 13:21:03 -0400132 if (arraySize > 0)
Jamie Madill440dc742013-06-20 11:55:55 -0400133 {
Jamie Madill912cbfe2013-08-30 13:21:03 -0400134 mCurrentOffset += arrayStride * arraySize;
Jamie Madill440dc742013-06-20 11:55:55 -0400135 }
Jamie Madill912cbfe2013-08-30 13:21:03 -0400136 else if (gl::IsMatrixType(type))
Jamie Madill440dc742013-06-20 11:55:55 -0400137 {
138 ASSERT(matrixStride == RegisterSize);
Jamie Madill912cbfe2013-08-30 13:21:03 -0400139 const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
Jamie Madill440dc742013-06-20 11:55:55 -0400140 mCurrentOffset += RegisterSize * numRegisters;
141 }
142 else
143 {
Jamie Madill912cbfe2013-08-30 13:21:03 -0400144 mCurrentOffset += gl::UniformComponentCount(type);
Jamie Madill440dc742013-06-20 11:55:55 -0400145 }
146}
147
148}