blob: 31656f9ba307f4ba5b0603da0a4242f331785676 [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/HLSLLayoutEncoder.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
15HLSLBlockEncoder::HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut)
16 : BlockLayoutEncoder(blockInfoOut)
17{
18}
19
20void HLSLBlockEncoder::enterAggregateType()
21{
22 nextRegister();
23}
24
25void HLSLBlockEncoder::exitAggregateType()
26{
27}
28
Jamie Madill912cbfe2013-08-30 13:21:03 -040029void HLSLBlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
Jamie Madill440dc742013-06-20 11:55:55 -040030{
Jamie Madill440dc742013-06-20 11:55:55 -040031 // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
Jamie Madill2b538b82013-08-30 13:21:09 -040032 ASSERT(gl::UniformComponentSize(gl::UniformComponentType(type)) == BytesPerComponent);
Jamie Madill440dc742013-06-20 11:55:55 -040033
34 int matrixStride = 0;
35 int arrayStride = 0;
36
Jamie Madill912cbfe2013-08-30 13:21:03 -040037 if (gl::IsMatrixType(type))
Jamie Madill440dc742013-06-20 11:55:55 -040038 {
39 nextRegister();
Jamie Madill2b538b82013-08-30 13:21:09 -040040 matrixStride = ComponentsPerRegister;
Jamie Madill440dc742013-06-20 11:55:55 -040041
Jamie Madill912cbfe2013-08-30 13:21:03 -040042 if (arraySize > 0)
Jamie Madill440dc742013-06-20 11:55:55 -040043 {
Jamie Madill912cbfe2013-08-30 13:21:03 -040044 const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
Jamie Madill2b538b82013-08-30 13:21:09 -040045 arrayStride = ComponentsPerRegister * numRegisters;
Jamie Madill440dc742013-06-20 11:55:55 -040046 }
47 }
Jamie Madill912cbfe2013-08-30 13:21:03 -040048 else if (arraySize > 0)
Jamie Madill440dc742013-06-20 11:55:55 -040049 {
50 nextRegister();
Jamie Madill2b538b82013-08-30 13:21:09 -040051 arrayStride = ComponentsPerRegister;
Jamie Madill440dc742013-06-20 11:55:55 -040052 }
53 else
54 {
Jamie Madill912cbfe2013-08-30 13:21:03 -040055 int numComponents = gl::UniformComponentCount(type);
Jamie Madill2b538b82013-08-30 13:21:09 -040056 if ((numComponents + (mCurrentOffset % ComponentsPerRegister)) > ComponentsPerRegister)
Jamie Madill440dc742013-06-20 11:55:55 -040057 {
58 nextRegister();
59 }
60 }
61
62 *matrixStrideOut = matrixStride;
63 *arrayStrideOut = arrayStride;
64}
65
Jamie Madill912cbfe2013-08-30 13:21:03 -040066void HLSLBlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
Jamie Madill440dc742013-06-20 11:55:55 -040067{
Jamie Madill912cbfe2013-08-30 13:21:03 -040068 if (arraySize > 0)
Jamie Madill440dc742013-06-20 11:55:55 -040069 {
Jamie Madill912cbfe2013-08-30 13:21:03 -040070 mCurrentOffset += arrayStride * (arraySize - 1);
Jamie Madill440dc742013-06-20 11:55:55 -040071 }
72
Jamie Madill912cbfe2013-08-30 13:21:03 -040073 if (gl::IsMatrixType(type))
Jamie Madill440dc742013-06-20 11:55:55 -040074 {
Jamie Madill2b538b82013-08-30 13:21:09 -040075 ASSERT(matrixStride == ComponentsPerRegister);
Jamie Madill912cbfe2013-08-30 13:21:03 -040076 const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
77 const int numComponents = gl::MatrixComponentCount(type, isRowMajorMatrix);
Jamie Madill2b538b82013-08-30 13:21:09 -040078 mCurrentOffset += ComponentsPerRegister * (numRegisters - 1);
Jamie Madill440dc742013-06-20 11:55:55 -040079 mCurrentOffset += numComponents;
80 }
81 else
82 {
Jamie Madill912cbfe2013-08-30 13:21:03 -040083 mCurrentOffset += gl::UniformComponentCount(type);
Jamie Madill440dc742013-06-20 11:55:55 -040084 }
85}
86
Jamie Madill56093782013-08-30 13:21:11 -040087void HLSLVariableGetRegisterInfo(unsigned int baseRegisterIndex, Uniform *variable, HLSLBlockEncoder *encoder, const std::vector<BlockMemberInfo> &blockInfo)
88{
89 // because this method computes offsets (element indexes) instead of any total sizes,
90 // we can ignore the array size of the variable
91
92 if (variable->isStruct())
93 {
94 encoder->enterAggregateType();
95
96 for (size_t fieldIndex = 0; fieldIndex < variable->fields.size(); fieldIndex++)
97 {
98 HLSLVariableGetRegisterInfo(baseRegisterIndex, &variable->fields[fieldIndex], encoder, blockInfo);
99 }
100
101 encoder->exitAggregateType();
102 }
103 else
104 {
105 encoder->encodeType(variable->type, variable->arraySize, false);
106
107 const size_t registerBytes = (encoder->BytesPerComponent * encoder->ComponentsPerRegister);
108 variable->registerIndex = baseRegisterIndex + (blockInfo.back().offset / registerBytes);
109 variable->elementIndex = (blockInfo.back().offset % registerBytes) / sizeof(float);
110 }
111}
112
113void HLSLVariableGetRegisterInfo(unsigned int baseRegisterIndex, Uniform *variable)
114{
115 std::vector<BlockMemberInfo> blockInfo;
116 HLSLBlockEncoder encoder(&blockInfo);
117 HLSLVariableGetRegisterInfo(baseRegisterIndex, variable, &encoder, blockInfo);
118}
119
Jamie Madillc2141fb2013-08-30 13:21:08 -0400120template <class ShaderVarType>
Jamie Madill86a97a12013-08-30 13:21:09 -0400121void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *encoder)
Jamie Madillc2141fb2013-08-30 13:21:08 -0400122{
123 if (variable.isStruct())
124 {
Jamie Madill86a97a12013-08-30 13:21:09 -0400125 for (size_t arrayElement = 0; arrayElement < variable.elementCount(); arrayElement++)
Jamie Madillc2141fb2013-08-30 13:21:08 -0400126 {
Jamie Madill86a97a12013-08-30 13:21:09 -0400127 encoder->enterAggregateType();
128
129 for (size_t fieldIndex = 0; fieldIndex < variable.fields.size(); fieldIndex++)
130 {
131 HLSLVariableRegisterCount(variable.fields[fieldIndex], encoder);
132 }
133
134 encoder->exitAggregateType();
Jamie Madillc2141fb2013-08-30 13:21:08 -0400135 }
Jamie Madillc2141fb2013-08-30 13:21:08 -0400136 }
137 else
138 {
Jamie Madill86a97a12013-08-30 13:21:09 -0400139 // We operate only on varyings and uniforms, which do not have matrix layout qualifiers
140 encoder->encodeType(variable.type, variable.arraySize, false);
Jamie Madillc2141fb2013-08-30 13:21:08 -0400141 }
142}
143
144unsigned int HLSLVariableRegisterCount(const Varying &variable)
145{
Jamie Madill86a97a12013-08-30 13:21:09 -0400146 HLSLBlockEncoder encoder(NULL);
147 HLSLVariableRegisterCount(variable, &encoder);
148
149 const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
150 return rx::roundUp(encoder.getBlockSize(), registerBytes) / registerBytes;
Jamie Madillc2141fb2013-08-30 13:21:08 -0400151}
152
153unsigned int HLSLVariableRegisterCount(const Uniform &variable)
154{
Jamie Madill86a97a12013-08-30 13:21:09 -0400155 HLSLBlockEncoder encoder(NULL);
156 HLSLVariableRegisterCount(variable, &encoder);
157
158 const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
159 return rx::roundUp(encoder.getBlockSize(), registerBytes) / registerBytes;
Jamie Madillc2141fb2013-08-30 13:21:08 -0400160}
161
Jamie Madill440dc742013-06-20 11:55:55 -0400162}