Line data Source code
1 : //
2 : // Copyright (c) 2013-2014 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 : // blocklayout.cpp:
7 : // Implementation for block layout classes and methods.
8 : //
9 :
10 : #include "compiler/translator/blocklayoutHLSL.h"
11 :
12 : #include "common/mathutil.h"
13 : #include "common/utilities.h"
14 :
15 : namespace sh
16 : {
17 :
18 0 : HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy)
19 : : mEncoderStrategy(strategy),
20 0 : mTransposeMatrices(false)
21 : {
22 0 : }
23 :
24 0 : void HLSLBlockEncoder::enterAggregateType()
25 : {
26 0 : nextRegister();
27 0 : }
28 :
29 0 : void HLSLBlockEncoder::exitAggregateType()
30 : {
31 0 : }
32 :
33 0 : void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
34 : {
35 0 : GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
36 :
37 : // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
38 0 : ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent);
39 :
40 0 : int matrixStride = 0;
41 0 : int arrayStride = 0;
42 :
43 : // if variables are not to be packed, or we're about to
44 : // pack a matrix or array, skip to the start of the next
45 : // register
46 0 : if (!isPacked() ||
47 0 : gl::IsMatrixType(type) ||
48 : arraySize > 0)
49 : {
50 0 : nextRegister();
51 : }
52 :
53 0 : if (gl::IsMatrixType(type))
54 : {
55 0 : matrixStride = ComponentsPerRegister;
56 :
57 0 : if (arraySize > 0)
58 : {
59 0 : const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
60 0 : arrayStride = ComponentsPerRegister * numRegisters;
61 : }
62 : }
63 0 : else if (arraySize > 0)
64 : {
65 0 : arrayStride = ComponentsPerRegister;
66 : }
67 0 : else if (isPacked())
68 : {
69 0 : int numComponents = gl::VariableComponentCount(type);
70 0 : if ((numComponents + (mCurrentOffset % ComponentsPerRegister)) > ComponentsPerRegister)
71 : {
72 0 : nextRegister();
73 : }
74 : }
75 :
76 0 : *matrixStrideOut = matrixStride;
77 0 : *arrayStrideOut = arrayStride;
78 0 : }
79 :
80 0 : void HLSLBlockEncoder::advanceOffset(GLenum typeIn, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
81 : {
82 0 : GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
83 :
84 0 : if (arraySize > 0)
85 : {
86 0 : mCurrentOffset += arrayStride * (arraySize - 1);
87 : }
88 :
89 0 : if (gl::IsMatrixType(type))
90 : {
91 0 : ASSERT(matrixStride == ComponentsPerRegister);
92 0 : const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
93 0 : const int numComponents = gl::MatrixComponentCount(type, isRowMajorMatrix);
94 0 : mCurrentOffset += ComponentsPerRegister * (numRegisters - 1);
95 0 : mCurrentOffset += numComponents;
96 : }
97 0 : else if (isPacked())
98 : {
99 0 : mCurrentOffset += gl::VariableComponentCount(type);
100 : }
101 : else
102 : {
103 0 : mCurrentOffset += ComponentsPerRegister;
104 : }
105 0 : }
106 :
107 0 : void HLSLBlockEncoder::skipRegisters(unsigned int numRegisters)
108 : {
109 0 : mCurrentOffset += (numRegisters * ComponentsPerRegister);
110 0 : }
111 :
112 0 : HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(ShShaderOutput outputType)
113 : {
114 0 : switch (outputType)
115 : {
116 : case SH_HLSL_3_0_OUTPUT:
117 0 : return ENCODE_LOOSE;
118 : case SH_HLSL_4_1_OUTPUT:
119 : case SH_HLSL_4_0_FL9_3_OUTPUT:
120 0 : return ENCODE_PACKED;
121 : default:
122 0 : UNREACHABLE();
123 : return ENCODE_PACKED;
124 : }
125 : }
126 :
127 : template <class ShaderVarType>
128 0 : void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *encoder)
129 : {
130 0 : if (variable.isStruct())
131 : {
132 0 : for (size_t arrayElement = 0; arrayElement < variable.elementCount(); arrayElement++)
133 : {
134 0 : encoder->enterAggregateType();
135 :
136 0 : for (size_t fieldIndex = 0; fieldIndex < variable.fields.size(); fieldIndex++)
137 : {
138 0 : HLSLVariableRegisterCount(variable.fields[fieldIndex], encoder);
139 : }
140 :
141 0 : encoder->exitAggregateType();
142 : }
143 : }
144 : else
145 : {
146 : // We operate only on varyings and uniforms, which do not have matrix layout qualifiers
147 0 : encoder->encodeType(variable.type, variable.arraySize, false);
148 : }
149 0 : }
150 :
151 0 : unsigned int HLSLVariableRegisterCount(const Varying &variable, bool transposeMatrices)
152 : {
153 0 : HLSLBlockEncoder encoder(HLSLBlockEncoder::ENCODE_PACKED);
154 0 : encoder.setTransposeMatrices(transposeMatrices);
155 0 : HLSLVariableRegisterCount(variable, &encoder);
156 :
157 0 : const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
158 0 : return static_cast<unsigned int>(rx::roundUp<size_t>(encoder.getBlockSize(), registerBytes) / registerBytes);
159 : }
160 :
161 0 : unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType)
162 : {
163 0 : HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType));
164 0 : encoder.setTransposeMatrices(true);
165 0 : HLSLVariableRegisterCount(variable, &encoder);
166 :
167 0 : const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
168 0 : return static_cast<unsigned int>(rx::roundUp<size_t>(encoder.getBlockSize(), registerBytes) / registerBytes);
169 : }
170 :
171 : }
|