blob: e55af757061ac3da97a85f81b0c0f34805725cc0 [file] [log] [blame]
shannonwoods@chromium.org7e0904d2013-05-30 00:06:45 +00001//
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/Uniform.h"
shannonwoods@chromium.org61aaf242013-05-30 00:12:20 +00008#include "common/mathutil.h"
9#include "common/utilities.h"
shannonwoods@chromium.org7e0904d2013-05-30 00:06:45 +000010
11namespace sh
12{
13
shannonwoods@chromium.org38676dc2013-05-30 00:06:52 +000014Uniform::Uniform(GLenum type, GLenum precision, const char *name, unsigned int arraySize, unsigned int registerIndex)
shannonwoods@chromium.org7e0904d2013-05-30 00:06:45 +000015{
16 this->type = type;
17 this->precision = precision;
18 this->name = name;
19 this->arraySize = arraySize;
20 this->registerIndex = registerIndex;
21}
22
shannonwoods@chromium.orgd7784172013-05-30 00:07:03 +000023BlockMemberInfo::BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
24 : offset(offset),
25 arrayStride(arrayStride),
26 matrixStride(matrixStride),
27 isRowMajorMatrix(isRowMajorMatrix)
28{
29}
30
31const BlockMemberInfo BlockMemberInfo::defaultBlockInfo(-1, -1, -1, false);
32
shannonwoods@chromium.org1500f092013-05-30 00:11:20 +000033InterfaceBlock::InterfaceBlock(const char *name, unsigned int arraySize, unsigned int registerIndex)
34 : name(name),
35 arraySize(arraySize),
36 registerIndex(registerIndex)
37{
38}
39
shannonwoods@chromium.org61aaf242013-05-30 00:12:20 +000040// Use the same layout for packed and shared
41void InterfaceBlock::setSharedBlockLayout()
42{
43 setPackedBlockLayout();
44}
45
46// Block layout packed according to the default D3D11 register packing rules
47// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
48void InterfaceBlock::setPackedBlockLayout()
49{
50 const size_t componentSize = 4;
51 const unsigned int registerSize = 4;
52 unsigned int currentOffset = 0;
53
54 blockInfo.clear();
55
56 for (unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)
57 {
58 const sh::Uniform &uniform = activeUniforms[uniformIndex];
59
60 // TODO: structs
61 // TODO: row major matrices
62 bool isRowMajorMatrix = false;
63
64 // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
65 ASSERT(gl::UniformComponentSize(gl::UniformComponentType(uniform.type)) == componentSize);
66
67 int arrayStride = 0;
68 int matrixStride = 0;
69
70 if (gl::IsMatrixType(uniform.type))
71 {
72 currentOffset = rx::roundUp(currentOffset, 4u);
73 matrixStride = registerSize;
74
75 if (uniform.arraySize > 0)
76 {
77 const int componentGroups = (isRowMajorMatrix ? gl::VariableColumnCount(uniform.type) : gl::VariableRowCount(uniform.type));
78 arrayStride = matrixStride * componentGroups;
79 }
80 }
81 else if (uniform.arraySize > 0)
82 {
83 currentOffset = rx::roundUp(currentOffset, registerSize);
84 arrayStride = registerSize;
85 }
86 else
87 {
88 int numComponents = gl::UniformComponentCount(uniform.type);
89 if ((numComponents + (currentOffset % registerSize)) >= registerSize)
90 {
91 currentOffset = rx::roundUp(currentOffset, registerSize);
92 }
93 }
94
95 BlockMemberInfo memberInfo(currentOffset * componentSize, arrayStride * componentSize, matrixStride * componentSize, isRowMajorMatrix);
96 blockInfo.push_back(memberInfo);
97
98 // for arrays/matrices, the next element is in a multiple of register size
99 if (uniform.arraySize > 0)
100 {
101 currentOffset += arrayStride * uniform.arraySize;
102 }
103 else if (gl::IsMatrixType(uniform.type))
104 {
105 const int componentGroups = (isRowMajorMatrix ? gl::VariableColumnCount(uniform.type) : gl::VariableRowCount(uniform.type));
106 currentOffset += matrixStride * componentGroups;
107 }
108 else
109 {
110 currentOffset += gl::UniformComponentCount(uniform.type);
111 }
112 }
113
114 dataSize = currentOffset * componentSize;
115}
116
117void InterfaceBlock::setStandardBlockLayout()
118{
119 const size_t componentSize = 4;
120 unsigned int currentOffset = 0;
121
122 blockInfo.clear();
123
124 for (unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)
125 {
126 const sh::Uniform &uniform = activeUniforms[uniformIndex];
127
128 // TODO: structs
129 // TODO: row major matrices
130 bool isRowMajorMatrix = false;
131
132 // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
133 ASSERT(gl::UniformComponentSize(gl::UniformComponentType(uniform.type)) == componentSize);
134
135 int numComponents = gl::UniformComponentCount(uniform.type);
136 size_t baseAlignment = static_cast<size_t>(numComponents == 3 ? 4 : numComponents);
137 int arrayStride = 0;
138 int matrixStride = 0;
139
140 if (gl::IsMatrixType(uniform.type))
141 {
142 numComponents = (isRowMajorMatrix ? gl::VariableRowCount(uniform.type) : gl::VariableColumnCount(uniform.type));
143 baseAlignment = rx::roundUp(baseAlignment, 4u);
144 matrixStride = baseAlignment;
145
146 if (uniform.arraySize > 0)
147 {
148 const int componentGroups = (isRowMajorMatrix ? gl::VariableColumnCount(uniform.type) : gl::VariableRowCount(uniform.type));
149 arrayStride = matrixStride * componentGroups;
150 }
151 }
152 else if (uniform.arraySize > 0)
153 {
154 baseAlignment = rx::roundUp(baseAlignment, 4u);
155 arrayStride = baseAlignment;
156 }
157
158 const unsigned int alignedOffset = rx::roundUp(currentOffset, baseAlignment);
159
160 BlockMemberInfo memberInfo(alignedOffset * componentSize, arrayStride * componentSize, matrixStride * componentSize, isRowMajorMatrix);
161 blockInfo.push_back(memberInfo);
162
163 if (uniform.arraySize > 0)
164 {
165 currentOffset += arrayStride * uniform.arraySize;
166 currentOffset = rx::roundUp(currentOffset, baseAlignment);
167 }
168 else if (gl::IsMatrixType(uniform.type))
169 {
170 const int componentGroups = (isRowMajorMatrix ? gl::VariableColumnCount(uniform.type) : gl::VariableRowCount(uniform.type));
171 currentOffset += matrixStride * componentGroups;
172 currentOffset = rx::roundUp(currentOffset, baseAlignment);
173 }
174 else
175 {
176 currentOffset += gl::UniformComponentCount(uniform.type);
177 }
178 }
179
180 dataSize = currentOffset * componentSize;
181}
182
shannonwoods@chromium.org7e0904d2013-05-30 00:06:45 +0000183}