blob: 39b1a5bd3635f5398c0f955933baee06d2308632 [file] [log] [blame]
Daniel Bratell73941de2015-02-25 14:34:49 +01001//
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
15namespace sh
16{
17
Jamie Madillcc2ed612017-03-14 15:59:00 -040018HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices)
19 : mEncoderStrategy(strategy), mTransposeMatrices(transposeMatrices)
Daniel Bratell73941de2015-02-25 14:34:49 +010020{
21}
22
23void HLSLBlockEncoder::enterAggregateType()
24{
25 nextRegister();
26}
27
28void HLSLBlockEncoder::exitAggregateType()
29{
30}
31
Jamie Madilld7b1ab52016-12-12 14:42:19 -050032void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn,
33 unsigned int arraySize,
34 bool isRowMajorMatrix,
35 int *arrayStrideOut,
36 int *matrixStrideOut)
Daniel Bratell73941de2015-02-25 14:34:49 +010037{
38 GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
39
40 // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
41 ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent);
42
43 int matrixStride = 0;
Jamie Madilld7b1ab52016-12-12 14:42:19 -050044 int arrayStride = 0;
Daniel Bratell73941de2015-02-25 14:34:49 +010045
46 // if variables are not to be packed, or we're about to
47 // pack a matrix or array, skip to the start of the next
48 // register
Jamie Madilld7b1ab52016-12-12 14:42:19 -050049 if (!isPacked() || gl::IsMatrixType(type) || arraySize > 0)
Daniel Bratell73941de2015-02-25 14:34:49 +010050 {
51 nextRegister();
52 }
53
54 if (gl::IsMatrixType(type))
55 {
56 matrixStride = ComponentsPerRegister;
57
58 if (arraySize > 0)
59 {
60 const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
Jamie Madilld7b1ab52016-12-12 14:42:19 -050061 arrayStride = ComponentsPerRegister * numRegisters;
Daniel Bratell73941de2015-02-25 14:34:49 +010062 }
63 }
64 else if (arraySize > 0)
65 {
66 arrayStride = ComponentsPerRegister;
67 }
68 else if (isPacked())
69 {
70 int numComponents = gl::VariableComponentCount(type);
71 if ((numComponents + (mCurrentOffset % ComponentsPerRegister)) > ComponentsPerRegister)
72 {
73 nextRegister();
74 }
75 }
76
77 *matrixStrideOut = matrixStride;
Jamie Madilld7b1ab52016-12-12 14:42:19 -050078 *arrayStrideOut = arrayStride;
Daniel Bratell73941de2015-02-25 14:34:49 +010079}
80
Jamie Madilld7b1ab52016-12-12 14:42:19 -050081void HLSLBlockEncoder::advanceOffset(GLenum typeIn,
82 unsigned int arraySize,
83 bool isRowMajorMatrix,
84 int arrayStride,
85 int matrixStride)
Daniel Bratell73941de2015-02-25 14:34:49 +010086{
87 GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
88
89 if (arraySize > 0)
90 {
91 mCurrentOffset += arrayStride * (arraySize - 1);
92 }
93
94 if (gl::IsMatrixType(type))
95 {
96 ASSERT(matrixStride == ComponentsPerRegister);
Jamie Madilld7b1ab52016-12-12 14:42:19 -050097 const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
Daniel Bratell73941de2015-02-25 14:34:49 +010098 const int numComponents = gl::MatrixComponentCount(type, isRowMajorMatrix);
99 mCurrentOffset += ComponentsPerRegister * (numRegisters - 1);
100 mCurrentOffset += numComponents;
101 }
102 else if (isPacked())
103 {
104 mCurrentOffset += gl::VariableComponentCount(type);
105 }
106 else
107 {
108 mCurrentOffset += ComponentsPerRegister;
109 }
110}
111
112void HLSLBlockEncoder::skipRegisters(unsigned int numRegisters)
113{
114 mCurrentOffset += (numRegisters * ComponentsPerRegister);
115}
116
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500117HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(
118 ShShaderOutput outputType)
Daniel Bratell73941de2015-02-25 14:34:49 +0100119{
120 switch (outputType)
121 {
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200122 case SH_HLSL_3_0_OUTPUT:
123 return ENCODE_LOOSE;
124 case SH_HLSL_4_1_OUTPUT:
125 case SH_HLSL_4_0_FL9_3_OUTPUT:
126 return ENCODE_PACKED;
127 default:
128 UNREACHABLE();
129 return ENCODE_PACKED;
Daniel Bratell73941de2015-02-25 14:34:49 +0100130 }
131}
132
133template <class ShaderVarType>
134void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *encoder)
135{
136 if (variable.isStruct())
137 {
138 for (size_t arrayElement = 0; arrayElement < variable.elementCount(); arrayElement++)
139 {
140 encoder->enterAggregateType();
141
142 for (size_t fieldIndex = 0; fieldIndex < variable.fields.size(); fieldIndex++)
143 {
144 HLSLVariableRegisterCount(variable.fields[fieldIndex], encoder);
145 }
146
147 encoder->exitAggregateType();
148 }
149 }
150 else
151 {
152 // We operate only on varyings and uniforms, which do not have matrix layout qualifiers
153 encoder->encodeType(variable.type, variable.arraySize, false);
154 }
155}
156
Daniel Bratell73941de2015-02-25 14:34:49 +0100157unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType)
158{
Jamie Madillcc2ed612017-03-14 15:59:00 -0400159 HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType), true);
Daniel Bratell73941de2015-02-25 14:34:49 +0100160 HLSLVariableRegisterCount(variable, &encoder);
161
162 const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500163 return static_cast<unsigned int>(rx::roundUp<size_t>(encoder.getBlockSize(), registerBytes) /
164 registerBytes);
Daniel Bratell73941de2015-02-25 14:34:49 +0100165}
Jamie Madillcc2ed612017-03-14 15:59:00 -0400166} // namespace sh