blob: 26d7ba2c55c3b61be77af00ca637af76ac34c522 [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
Geoff Lang17732822013-08-29 13:46:49 -04007#include "compiler/translator/BlockLayoutEncoder.h"
8#include "compiler/translator/ShaderVariable.h"
Jamie Madill440dc742013-06-20 11:55:55 -04009#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
Jamie Madill9d2ffb12013-08-30 13:21:04 -040021void BlockLayoutEncoder::encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields)
Jamie Madill440dc742013-06-20 11:55:55 -040022{
23 for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
24 {
Jamie Madill9d2ffb12013-08-30 13:21:04 -040025 const InterfaceBlockField &variable = fields[fieldIndex];
Jamie Madill440dc742013-06-20 11:55:55 -040026
Jamie Madill9d2ffb12013-08-30 13:21:04 -040027 if (variable.fields.size() > 0)
Jamie Madill440dc742013-06-20 11:55:55 -040028 {
Jamie Madill9d2ffb12013-08-30 13:21:04 -040029 const unsigned int elementCount = std::max(1u, variable.arraySize);
Jamie Madill440dc742013-06-20 11:55:55 -040030
31 for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
32 {
33 enterAggregateType();
Jamie Madill9d2ffb12013-08-30 13:21:04 -040034 encodeInterfaceBlockFields(variable.fields);
Jamie Madill440dc742013-06-20 11:55:55 -040035 exitAggregateType();
36 }
37 }
38 else
39 {
Jamie Madill9d2ffb12013-08-30 13:21:04 -040040 encodeInterfaceBlockField(variable);
Jamie Madill440dc742013-06-20 11:55:55 -040041 }
42 }
43}
44
Jamie Madill9d2ffb12013-08-30 13:21:04 -040045void BlockLayoutEncoder::encodeInterfaceBlockField(const InterfaceBlockField &field)
Jamie Madill440dc742013-06-20 11:55:55 -040046{
47 int arrayStride;
48 int matrixStride;
49
Jamie Madill9d2ffb12013-08-30 13:21:04 -040050 ASSERT(field.fields.empty());
51 getBlockLayoutInfo(field.type, field.arraySize, field.isRowMajorMatrix, &arrayStride, &matrixStride);
Jamie Madill440dc742013-06-20 11:55:55 -040052
Jamie Madill2b538b82013-08-30 13:21:09 -040053 const BlockMemberInfo memberInfo(mCurrentOffset * BytesPerComponent, arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, field.isRowMajorMatrix);
Jamie Madill77456f22013-08-30 13:21:07 -040054
55 if (mBlockInfoOut)
56 {
57 mBlockInfoOut->push_back(memberInfo);
58 }
Jamie Madill440dc742013-06-20 11:55:55 -040059
Jamie Madill9d2ffb12013-08-30 13:21:04 -040060 advanceOffset(field.type, field.arraySize, field.isRowMajorMatrix, arrayStride, matrixStride);
Jamie Madill912cbfe2013-08-30 13:21:03 -040061}
62
63void BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
64{
65 int arrayStride;
66 int matrixStride;
67
68 getBlockLayoutInfo(type, arraySize, isRowMajorMatrix, &arrayStride, &matrixStride);
69
Jamie Madill2b538b82013-08-30 13:21:09 -040070 const BlockMemberInfo memberInfo(mCurrentOffset * BytesPerComponent, arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, isRowMajorMatrix);
Jamie Madill77456f22013-08-30 13:21:07 -040071
72 if (mBlockInfoOut)
73 {
74 mBlockInfoOut->push_back(memberInfo);
75 }
Jamie Madill912cbfe2013-08-30 13:21:03 -040076
77 advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride);
Jamie Madill440dc742013-06-20 11:55:55 -040078}
79
80void BlockLayoutEncoder::nextRegister()
81{
Jamie Madill2b538b82013-08-30 13:21:09 -040082 mCurrentOffset = rx::roundUp(mCurrentOffset, ComponentsPerRegister);
Jamie Madill440dc742013-06-20 11:55:55 -040083}
84
85Std140BlockEncoder::Std140BlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut)
86 : BlockLayoutEncoder(blockInfoOut)
87{
88}
89
90void Std140BlockEncoder::enterAggregateType()
91{
92 nextRegister();
93}
94
95void Std140BlockEncoder::exitAggregateType()
96{
97 nextRegister();
98}
99
Jamie Madill912cbfe2013-08-30 13:21:03 -0400100void Std140BlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
Jamie Madill440dc742013-06-20 11:55:55 -0400101{
Jamie Madill440dc742013-06-20 11:55:55 -0400102 // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
Jamie Madill2b538b82013-08-30 13:21:09 -0400103 ASSERT(gl::UniformComponentSize(gl::UniformComponentType(type)) == BytesPerComponent);
Jamie Madill440dc742013-06-20 11:55:55 -0400104
Jamie Madill912cbfe2013-08-30 13:21:03 -0400105 int numComponents = gl::UniformComponentCount(type);
Jamie Madill919b0662013-06-20 11:55:56 -0400106 size_t baseAlignment = 0;
Jamie Madill440dc742013-06-20 11:55:55 -0400107 int matrixStride = 0;
108 int arrayStride = 0;
109
Jamie Madill912cbfe2013-08-30 13:21:03 -0400110 if (gl::IsMatrixType(type))
Jamie Madill440dc742013-06-20 11:55:55 -0400111 {
Jamie Madill2b538b82013-08-30 13:21:09 -0400112 baseAlignment = ComponentsPerRegister;
113 matrixStride = ComponentsPerRegister;
Jamie Madill440dc742013-06-20 11:55:55 -0400114
Jamie Madill912cbfe2013-08-30 13:21:03 -0400115 if (arraySize > 0)
Jamie Madill440dc742013-06-20 11:55:55 -0400116 {
Jamie Madill912cbfe2013-08-30 13:21:03 -0400117 const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
Jamie Madill2b538b82013-08-30 13:21:09 -0400118 arrayStride = ComponentsPerRegister * numRegisters;
Jamie Madill440dc742013-06-20 11:55:55 -0400119 }
120 }
Jamie Madill912cbfe2013-08-30 13:21:03 -0400121 else if (arraySize > 0)
Jamie Madill440dc742013-06-20 11:55:55 -0400122 {
Jamie Madill2b538b82013-08-30 13:21:09 -0400123 baseAlignment = ComponentsPerRegister;
124 arrayStride = ComponentsPerRegister;
Jamie Madill919b0662013-06-20 11:55:56 -0400125 }
126 else
127 {
Jamie Madill912cbfe2013-08-30 13:21:03 -0400128 const int numComponents = gl::UniformComponentCount(type);
Jamie Madill919b0662013-06-20 11:55:56 -0400129 baseAlignment = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
Jamie Madill440dc742013-06-20 11:55:55 -0400130 }
131
132 mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
133
134 *matrixStrideOut = matrixStride;
135 *arrayStrideOut = arrayStride;
136}
137
Jamie Madill912cbfe2013-08-30 13:21:03 -0400138void Std140BlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
Jamie Madill440dc742013-06-20 11:55:55 -0400139{
Jamie Madill912cbfe2013-08-30 13:21:03 -0400140 if (arraySize > 0)
Jamie Madill440dc742013-06-20 11:55:55 -0400141 {
Jamie Madill912cbfe2013-08-30 13:21:03 -0400142 mCurrentOffset += arrayStride * arraySize;
Jamie Madill440dc742013-06-20 11:55:55 -0400143 }
Jamie Madill912cbfe2013-08-30 13:21:03 -0400144 else if (gl::IsMatrixType(type))
Jamie Madill440dc742013-06-20 11:55:55 -0400145 {
Jamie Madill2b538b82013-08-30 13:21:09 -0400146 ASSERT(matrixStride == ComponentsPerRegister);
Jamie Madill912cbfe2013-08-30 13:21:03 -0400147 const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
Jamie Madill2b538b82013-08-30 13:21:09 -0400148 mCurrentOffset += ComponentsPerRegister * numRegisters;
Jamie Madill440dc742013-06-20 11:55:55 -0400149 }
150 else
151 {
Jamie Madill912cbfe2013-08-30 13:21:03 -0400152 mCurrentOffset += gl::UniformComponentCount(type);
Jamie Madill440dc742013-06-20 11:55:55 -0400153 }
154}
155
156}