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/blocklayout.h"
11 :
12 : #include "common/mathutil.h"
13 : #include "common/utilities.h"
14 :
15 : namespace sh
16 : {
17 :
18 0 : BlockLayoutEncoder::BlockLayoutEncoder()
19 0 : : mCurrentOffset(0)
20 : {
21 0 : }
22 :
23 0 : BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
24 : {
25 : int arrayStride;
26 : int matrixStride;
27 :
28 0 : getBlockLayoutInfo(type, arraySize, isRowMajorMatrix, &arrayStride, &matrixStride);
29 :
30 0 : const BlockMemberInfo memberInfo(static_cast<int>(mCurrentOffset * BytesPerComponent),
31 0 : static_cast<int>(arrayStride * BytesPerComponent),
32 0 : static_cast<int>(matrixStride * BytesPerComponent),
33 0 : isRowMajorMatrix);
34 :
35 0 : advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride);
36 :
37 0 : return memberInfo;
38 : }
39 :
40 : // static
41 0 : size_t BlockLayoutEncoder::getBlockRegister(const BlockMemberInfo &info)
42 : {
43 0 : return (info.offset / BytesPerComponent) / ComponentsPerRegister;
44 : }
45 :
46 : // static
47 0 : size_t BlockLayoutEncoder::getBlockRegisterElement(const BlockMemberInfo &info)
48 : {
49 0 : return (info.offset / BytesPerComponent) % ComponentsPerRegister;
50 : }
51 :
52 0 : void BlockLayoutEncoder::nextRegister()
53 : {
54 0 : mCurrentOffset = rx::roundUp<size_t>(mCurrentOffset, ComponentsPerRegister);
55 0 : }
56 :
57 0 : Std140BlockEncoder::Std140BlockEncoder()
58 : {
59 0 : }
60 :
61 0 : void Std140BlockEncoder::enterAggregateType()
62 : {
63 0 : nextRegister();
64 0 : }
65 :
66 0 : void Std140BlockEncoder::exitAggregateType()
67 : {
68 0 : nextRegister();
69 0 : }
70 :
71 0 : void Std140BlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
72 : {
73 : // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
74 0 : ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent);
75 :
76 0 : size_t baseAlignment = 0;
77 0 : int matrixStride = 0;
78 0 : int arrayStride = 0;
79 :
80 0 : if (gl::IsMatrixType(type))
81 : {
82 0 : baseAlignment = ComponentsPerRegister;
83 0 : matrixStride = ComponentsPerRegister;
84 :
85 0 : if (arraySize > 0)
86 : {
87 0 : const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
88 0 : arrayStride = ComponentsPerRegister * numRegisters;
89 : }
90 : }
91 0 : else if (arraySize > 0)
92 : {
93 0 : baseAlignment = ComponentsPerRegister;
94 0 : arrayStride = ComponentsPerRegister;
95 : }
96 : else
97 : {
98 0 : const int numComponents = gl::VariableComponentCount(type);
99 0 : baseAlignment = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
100 : }
101 :
102 0 : mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
103 :
104 0 : *matrixStrideOut = matrixStride;
105 0 : *arrayStrideOut = arrayStride;
106 0 : }
107 :
108 0 : void Std140BlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
109 : {
110 0 : if (arraySize > 0)
111 : {
112 0 : mCurrentOffset += arrayStride * arraySize;
113 : }
114 0 : else if (gl::IsMatrixType(type))
115 : {
116 0 : ASSERT(matrixStride == ComponentsPerRegister);
117 0 : const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
118 0 : mCurrentOffset += ComponentsPerRegister * numRegisters;
119 : }
120 : else
121 : {
122 0 : mCurrentOffset += gl::VariableComponentCount(type);
123 : }
124 0 : }
125 :
126 : }
|